mirror of https://github.com/PentHertz/srsLTE.git
Added handling of RRC re-establishment to srsENB.
* Added the appropriate code for handling and sending the re-establishment procedure messages to rrc_ue.c/.h. * Triggered RRC reconfiguration after the reception of RRC re-establishment complete * Refreshed K_eNB at the reception of re-establishment request * Changed the mapping of TEIDs to RNTIs in the GTP-U layer, as the RNTI might change with reestablishment.
This commit is contained in:
parent
0e99e2f6eb
commit
960c0e97cd
|
@ -465,9 +465,10 @@ public:
|
|||
class gtpu_interface_rrc
|
||||
{
|
||||
public:
|
||||
virtual void add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, uint32_t* teid_in) = 0;
|
||||
virtual void rem_bearer(uint16_t rnti, uint32_t lcid) = 0;
|
||||
virtual void rem_user(uint16_t rnti) = 0;
|
||||
virtual uint32_t add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out) = 0;
|
||||
virtual void rem_bearer(uint16_t rnti, uint32_t lcid) = 0;
|
||||
virtual void mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti) = 0;
|
||||
virtual void rem_user(uint16_t rnti) = 0;
|
||||
};
|
||||
|
||||
// S1AP interface for RRC
|
||||
|
|
|
@ -122,7 +122,6 @@ public:
|
|||
|
||||
private:
|
||||
class ue;
|
||||
|
||||
// args
|
||||
srslte::timer_handler* timers = nullptr;
|
||||
srslte::byte_buffer_pool* pool = nullptr;
|
||||
|
|
|
@ -36,21 +36,22 @@ public:
|
|||
|
||||
bool set_security_capabilities(const asn1::s1ap::ue_security_cap_s& caps);
|
||||
void set_security_key(const asn1::fixed_bitstring<256, false, true>& key);
|
||||
void regenerate_keys_handover(uint32_t new_pci, uint32_t new_dl_earfcn);
|
||||
|
||||
asn1::rrc::security_algorithm_cfg_s get_security_algorithm_cfg();
|
||||
const srslte::as_security_config_t& get_as_sec_cfg() const { return sec_cfg; }
|
||||
bool is_as_sec_cfg_valid() const { return k_enb_present; }
|
||||
|
||||
void regenerate_keys_handover(uint32_t new_pci, uint32_t new_dl_earfcn);
|
||||
|
||||
private:
|
||||
void generate_as_keys();
|
||||
|
||||
srslte::log_ref log_h{"RRC"};
|
||||
const rrc_cfg_t* cfg;
|
||||
bool k_enb_present = false;
|
||||
asn1::s1ap::ue_security_cap_s security_capabilities;
|
||||
uint8_t k_enb[32] = {}; // Provided by MME
|
||||
srslte::as_security_config_t sec_cfg = {};
|
||||
const rrc_cfg_t* cfg = nullptr;
|
||||
bool k_enb_present = false;
|
||||
asn1::s1ap::ue_security_cap_s security_capabilities = {};
|
||||
uint8_t k_enb[32] = {}; // Provided by MME
|
||||
srslte::as_security_config_t sec_cfg = {};
|
||||
};
|
||||
|
||||
class bearer_cfg_handler
|
||||
|
@ -64,7 +65,7 @@ public:
|
|||
uint32_t teid_in = 0;
|
||||
};
|
||||
|
||||
bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_, gtpu_interface_rrc* gtpu_);
|
||||
bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_);
|
||||
|
||||
void add_srb(uint8_t srb_id);
|
||||
int add_erab(uint8_t erab_id,
|
||||
|
@ -83,24 +84,25 @@ public:
|
|||
void apply_mac_bearer_updates(mac_interface_rrc* mac, sched_interface::ue_cfg_t* sched_ue_cfg);
|
||||
void apply_pdcp_bearer_updates(pdcp_interface_rrc* pdcp, const security_cfg_handler& ue_sec_cfg);
|
||||
void apply_rlc_bearer_updates(rlc_interface_rrc* rlc);
|
||||
void add_gtpu_bearer(gtpu_interface_rrc* gtpu, uint32_t erab_id);
|
||||
void fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg);
|
||||
|
||||
const std::map<uint8_t, erab_t>& get_erabs() const { return erabs; }
|
||||
const asn1::rrc::drb_to_add_mod_list_l& established_drbs() const { return last_drbs; }
|
||||
const asn1::rrc::srb_to_add_mod_list_l& established_srbs() const { return last_srbs; }
|
||||
|
||||
private:
|
||||
srslte::log_ref log_h{"RRC"};
|
||||
uint16_t rnti;
|
||||
const rrc_cfg_t* cfg;
|
||||
gtpu_interface_rrc* gtpu;
|
||||
const asn1::rrc::drb_to_add_mod_list_l& get_established_drbs() const { return current_drbs; }
|
||||
const asn1::rrc::srb_to_add_mod_list_l& get_established_srbs() const { return current_srbs; }
|
||||
const asn1::rrc::drb_to_add_mod_list_l& get_pending_addmod_drbs() const { return drbs_to_add; }
|
||||
|
||||
std::map<uint8_t, std::vector<uint8_t> > erab_info_list;
|
||||
std::map<uint8_t, erab_t> erabs;
|
||||
|
||||
private:
|
||||
srslte::log_ref log_h{"RRC"};
|
||||
uint16_t rnti = 0;
|
||||
const rrc_cfg_t* cfg = nullptr;
|
||||
|
||||
// last cfg
|
||||
asn1::rrc::srb_to_add_mod_list_l last_srbs;
|
||||
asn1::rrc::drb_to_add_mod_list_l last_drbs;
|
||||
asn1::rrc::srb_to_add_mod_list_l current_srbs;
|
||||
asn1::rrc::drb_to_add_mod_list_l current_drbs;
|
||||
|
||||
// pending cfg updates
|
||||
asn1::rrc::srb_to_add_mod_list_l srbs_to_add;
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace srsenb {
|
|||
typedef enum {
|
||||
RRC_STATE_IDLE = 0,
|
||||
RRC_STATE_WAIT_FOR_CON_SETUP_COMPLETE,
|
||||
RRC_STATE_WAIT_FOR_CON_REEST_COMPLETE,
|
||||
RRC_STATE_WAIT_FOR_SECURITY_MODE_COMPLETE,
|
||||
RRC_STATE_WAIT_FOR_UE_CAP_INFO,
|
||||
RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE,
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
rrc_state_t get_state();
|
||||
|
||||
void send_connection_setup(bool is_setup = true);
|
||||
void send_connection_setup();
|
||||
void send_connection_reest();
|
||||
void send_connection_reject();
|
||||
void send_connection_release();
|
||||
|
@ -66,6 +66,8 @@ public:
|
|||
void handle_rrc_con_req(asn1::rrc::rrc_conn_request_s* msg);
|
||||
void handle_rrc_con_reest_req(asn1::rrc::rrc_conn_reest_request_r8_ies_s* msg);
|
||||
void handle_rrc_con_setup_complete(asn1::rrc::rrc_conn_setup_complete_s* msg, srslte::unique_byte_buffer_t pdu);
|
||||
void handle_rrc_con_reest_req(asn1::rrc::rrc_conn_reest_request_s* msg);
|
||||
void handle_rrc_con_reest_complete(asn1::rrc::rrc_conn_reest_complete_s* msg, srslte::unique_byte_buffer_t pdu);
|
||||
void handle_rrc_reconf_complete(asn1::rrc::rrc_conn_recfg_complete_s* msg, srslte::unique_byte_buffer_t pdu);
|
||||
void handle_security_mode_complete(asn1::rrc::security_mode_complete_s* msg);
|
||||
void handle_security_mode_failure(asn1::rrc::security_mode_fail_s* msg);
|
||||
|
@ -121,6 +123,7 @@ private:
|
|||
sched_interface::ue_cfg_t current_sched_ue_cfg = {};
|
||||
uint32_t rlf_cnt = 0;
|
||||
uint8_t transaction_id = 0;
|
||||
uint16_t old_reest_rnti = SRSLTE_INVALID_RNTI;
|
||||
rrc_state_t state = RRC_STATE_IDLE;
|
||||
|
||||
asn1::s1ap::ue_aggregate_maximum_bitrate_s bitrates;
|
||||
|
@ -134,6 +137,12 @@ private:
|
|||
bearer_cfg_handler bearer_list;
|
||||
security_cfg_handler ue_security_cfg;
|
||||
|
||||
///< Helper to add SRB to scheduler
|
||||
void init_sched_ue_cfg(asn1::rrc::phys_cfg_ded_s* phy_cfg);
|
||||
|
||||
///< Helper to fill RR config dedicated struct for RRR Connection Setup/Reestablish
|
||||
void fill_rrc_setup_rr_config_dedicated(asn1::rrc::rr_cfg_ded_s* rr_cfg);
|
||||
|
||||
///< Helper to access a cell cfg based on ue_cc_idx
|
||||
cell_info_common* get_ue_cc_cfg(uint32_t ue_cc_idx);
|
||||
|
||||
|
|
|
@ -49,9 +49,10 @@ public:
|
|||
void stop();
|
||||
|
||||
// gtpu_interface_rrc
|
||||
void add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, uint32_t* teid_in) override;
|
||||
void rem_bearer(uint16_t rnti, uint32_t lcid) override;
|
||||
void rem_user(uint16_t rnti) override;
|
||||
uint32_t add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out) override;
|
||||
void rem_bearer(uint16_t rnti, uint32_t lcid) override;
|
||||
void mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti) override;
|
||||
void rem_user(uint16_t rnti) override;
|
||||
|
||||
// gtpu_interface_pdcp
|
||||
void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) override;
|
||||
|
@ -105,6 +106,12 @@ private:
|
|||
} bearer_map;
|
||||
std::map<uint16_t, bearer_map> rnti_bearers;
|
||||
|
||||
typedef struct {
|
||||
uint16_t rnti;
|
||||
uint16_t lcid;
|
||||
} rnti_lcid_t;
|
||||
std::map<uint32_t, rnti_lcid_t> teidin_to_rntilcid_map;
|
||||
|
||||
// Socket file descriptor
|
||||
int fd = -1;
|
||||
|
||||
|
@ -113,8 +120,12 @@ private:
|
|||
/****************************************************************************
|
||||
* TEID to RNIT/LCID helper functions
|
||||
***************************************************************************/
|
||||
void teidin_to_rntilcid(uint32_t teidin, uint16_t* rnti, uint16_t* lcid);
|
||||
void rntilcid_to_teidin(uint16_t rnti, uint16_t lcid, uint32_t* teidin);
|
||||
uint32_t next_teid_in = 0;
|
||||
uint32_t allocate_teidin(uint16_t rnti, uint16_t lcid);
|
||||
void free_teidin(uint16_t rnti, uint16_t lcid);
|
||||
void free_teidin(uint16_t rnti);
|
||||
rnti_lcid_t teidin_to_rntilcid(uint32_t teidin);
|
||||
uint32_t rntilcid_to_teidin(uint16_t rnti, uint16_t lcid);
|
||||
};
|
||||
|
||||
} // namespace srsenb
|
||||
|
|
|
@ -179,7 +179,7 @@ void rrc::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& sched_ue_cfg)
|
|||
mac->ue_cfg(SRSLTE_MRNTI, NULL);
|
||||
rlc->add_bearer_mrb(SRSLTE_MRNTI, lcid);
|
||||
pdcp->add_bearer(SRSLTE_MRNTI, lcid, srslte::make_drb_pdcp_config_t(1, false));
|
||||
gtpu->add_bearer(SRSLTE_MRNTI, lcid, 1, 1, &teid_in);
|
||||
teid_in = gtpu->add_bearer(SRSLTE_MRNTI, lcid, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -456,8 +456,6 @@ void rrc::ho_preparation_complete(uint16_t rnti, bool is_success, srslte::unique
|
|||
|
||||
void rrc::parse_ul_ccch(uint16_t rnti, srslte::unique_byte_buffer_t pdu)
|
||||
{
|
||||
uint16_t old_rnti = 0;
|
||||
|
||||
if (pdu) {
|
||||
ul_ccch_msg_s ul_ccch_msg;
|
||||
asn1::cbit_ref bref(pdu->msg, pdu->N_bytes);
|
||||
|
@ -479,41 +477,10 @@ void rrc::parse_ul_ccch(uint16_t rnti, srslte::unique_byte_buffer_t pdu)
|
|||
}
|
||||
break;
|
||||
case ul_ccch_msg_type_c::c1_c_::types::rrc_conn_reest_request:
|
||||
rrc_log->debug("rnti=0x%x, phyid=0x%x, smac=0x%x, cause=%s\n",
|
||||
(uint32_t)ul_ccch_msg.msg.c1()
|
||||
.rrc_conn_reest_request()
|
||||
.crit_exts.rrc_conn_reest_request_r8()
|
||||
.ue_id.c_rnti.to_number(),
|
||||
ul_ccch_msg.msg.c1().rrc_conn_reest_request().crit_exts.rrc_conn_reest_request_r8().ue_id.pci,
|
||||
(uint32_t)ul_ccch_msg.msg.c1()
|
||||
.rrc_conn_reest_request()
|
||||
.crit_exts.rrc_conn_reest_request_r8()
|
||||
.ue_id.short_mac_i.to_number(),
|
||||
ul_ccch_msg.msg.c1()
|
||||
.rrc_conn_reest_request()
|
||||
.crit_exts.rrc_conn_reest_request_r8()
|
||||
.reest_cause.to_string()
|
||||
.c_str());
|
||||
if (user_it->second->is_idle()) {
|
||||
old_rnti = (uint16_t)ul_ccch_msg.msg.c1()
|
||||
.rrc_conn_reest_request()
|
||||
.crit_exts.rrc_conn_reest_request_r8()
|
||||
.ue_id.c_rnti.to_number();
|
||||
if (users.count(old_rnti)) {
|
||||
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, 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();
|
||||
}
|
||||
// remove temporal rnti
|
||||
rrc_log->warning(
|
||||
"Received ConnectionReestablishment for rnti=0x%x. Removing temporal rnti=0x%x\n", old_rnti, rnti);
|
||||
rem_user_thread(rnti);
|
||||
if (user_it != users.end()) {
|
||||
user_it->second->handle_rrc_con_reest_req(&ul_ccch_msg.msg.c1().rrc_conn_reest_request());
|
||||
} else {
|
||||
rrc_log->error("Received ReestablishmentRequest from an rnti=0x%x not in IDLE\n", rnti);
|
||||
rrc_log->error("Received ConnectionReestablishment for rnti=0x%x without context.\n", rnti);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -178,8 +178,6 @@ void security_cfg_handler::set_security_key(const asn1::fixed_bitstring<256, fal
|
|||
|
||||
void security_cfg_handler::generate_as_keys()
|
||||
{
|
||||
log_h->info("Selected security algorithms EEA: EEA%d EIA: EIA%d\n", sec_cfg.cipher_algo, sec_cfg.integ_algo);
|
||||
|
||||
// Generate K_rrc_enc and K_rrc_int
|
||||
srslte::security_generate_k_rrc(
|
||||
k_enb, sec_cfg.cipher_algo, sec_cfg.integ_algo, sec_cfg.k_rrc_enc.data(), sec_cfg.k_rrc_int.data());
|
||||
|
@ -203,17 +201,18 @@ void security_cfg_handler::regenerate_keys_handover(uint32_t new_pci, uint32_t n
|
|||
memcpy(k_enb, k_enb_star, 32);
|
||||
|
||||
generate_as_keys();
|
||||
|
||||
log_h->info("Regenerating KeNB with PCI=0x%02x, DL-EARFCN=%d\n", new_pci, new_dl_earfcn);
|
||||
log_h->info_hex(sec_cfg.k_rrc_enc.data(), 32, "RRC Encryption Key (k_rrc_enc)");
|
||||
log_h->info_hex(sec_cfg.k_rrc_int.data(), 32, "RRC Integrity Key (k_rrc_int)");
|
||||
log_h->info_hex(sec_cfg.k_up_enc.data(), 32, "UP Encryption Key (k_up_enc)");
|
||||
}
|
||||
|
||||
/*****************************
|
||||
* Bearer Handler
|
||||
****************************/
|
||||
|
||||
bearer_cfg_handler::bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_, gtpu_interface_rrc* gtpu_) :
|
||||
rnti(rnti_),
|
||||
cfg(&cfg_),
|
||||
gtpu(gtpu_)
|
||||
{}
|
||||
bearer_cfg_handler::bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_) : rnti(rnti_), cfg(&cfg_) {}
|
||||
|
||||
void bearer_cfg_handler::add_srb(uint8_t srb_id)
|
||||
{
|
||||
|
@ -283,9 +282,6 @@ int bearer_cfg_handler::add_erab(uint8_t
|
|||
drb_it->rlc_cfg_present = true;
|
||||
drb_it->rlc_cfg = cfg->qci_cfg[qos.qci].rlc_cfg;
|
||||
|
||||
// Initialize ERAB in GTPU right-away. DRBs are only created during RRC setup/reconf
|
||||
uint32_t addr_ = addr.to_number();
|
||||
gtpu->add_bearer(rnti, lcid, addr_, erabs[erab_id].teid_out, &(erabs[erab_id].teid_in));
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -316,15 +312,15 @@ void bearer_cfg_handler::release_erabs()
|
|||
void bearer_cfg_handler::reest_bearers()
|
||||
{
|
||||
// Re-add all SRBs/DRBs
|
||||
srbs_to_add = last_srbs;
|
||||
drbs_to_add = last_drbs;
|
||||
srbs_to_add = current_srbs;
|
||||
drbs_to_add = current_drbs;
|
||||
}
|
||||
|
||||
void bearer_cfg_handler::rr_ded_cfg_complete()
|
||||
{
|
||||
// Apply changes in internal bearer_handler DRB/SRBtoAddModLists
|
||||
srslte::apply_addmodlist_diff(last_srbs, srbs_to_add, last_srbs);
|
||||
srslte::apply_addmodremlist_diff(last_drbs, drbs_to_add, drbs_to_release, last_drbs);
|
||||
srslte::apply_addmodlist_diff(current_srbs, srbs_to_add, current_srbs);
|
||||
srslte::apply_addmodremlist_diff(current_drbs, drbs_to_add, drbs_to_release, current_drbs);
|
||||
|
||||
// Reset DRBs/SRBs to Add/mod/release
|
||||
srbs_to_add = {};
|
||||
|
@ -416,6 +412,19 @@ void bearer_cfg_handler::apply_rlc_bearer_updates(rlc_interface_rrc* rlc)
|
|||
}
|
||||
}
|
||||
|
||||
void bearer_cfg_handler::add_gtpu_bearer(srsenb::gtpu_interface_rrc* gtpu, uint32_t erab_id)
|
||||
{
|
||||
auto it = erabs.find(erab_id);
|
||||
if (it != erabs.end()) {
|
||||
erab_t& erab = it->second;
|
||||
// Initialize ERAB in GTPU right-away. DRBs are only created during RRC setup/reconf
|
||||
uint32_t addr_ = erab.address.to_number();
|
||||
erab.teid_in = gtpu->add_bearer(rnti, erab.id - 2, addr_, erab.teid_out);
|
||||
} else {
|
||||
log_h->error("Adding erab_id=%d to GTPU\n", erab_id);
|
||||
}
|
||||
}
|
||||
|
||||
void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg)
|
||||
{
|
||||
// Add space for NAS messages
|
||||
|
|
|
@ -528,10 +528,9 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg)
|
|||
continue;
|
||||
}
|
||||
meas_ev.meas_cell = cell_it;
|
||||
meas_ev.target_eci = std::find_if(meas_list_cfg.begin(),
|
||||
meas_list_cfg.end(),
|
||||
[pci](const meas_cell_cfg_t& c) { return c.pci == pci; })
|
||||
->eci;
|
||||
meas_ev.target_eci = std::find_if(meas_list_cfg.begin(), meas_list_cfg.end(), [pci](const meas_cell_cfg_t& c) {
|
||||
return c.pci == pci;
|
||||
})->eci;
|
||||
|
||||
// eNB found the respective cell. eNB takes "HO Decision"
|
||||
// NOTE: From now we just choose the strongest.
|
||||
|
@ -968,7 +967,7 @@ void rrc::ue::rrc_mobility::intraenb_ho_st::enter(rrc_mobility* f)
|
|||
}
|
||||
|
||||
/* Freeze all DRBs. SRBs are needed for sending the HO Cmd */
|
||||
for (const drb_to_add_mod_s& drb : f->rrc_ue->bearer_list.established_drbs()) {
|
||||
for (const drb_to_add_mod_s& drb : f->rrc_ue->bearer_list.get_established_drbs()) {
|
||||
f->rrc_enb->pdcp->del_bearer(f->rrc_ue->rnti, drb.drb_id + 2);
|
||||
f->rrc_enb->mac->bearer_ue_rem(f->rrc_ue->rnti, drb.drb_id + 2);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -140,17 +140,17 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t
|
|||
* If access to any element created in init (such as gtpu_log) is required, it must be considered
|
||||
* the case of it being NULL.
|
||||
*/
|
||||
void gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, uint32_t* teid_in)
|
||||
uint32_t gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out)
|
||||
{
|
||||
// Allocate a TEID for the incoming tunnel
|
||||
rntilcid_to_teidin(rnti, lcid, teid_in);
|
||||
uint32_t teid_in = allocate_teidin(rnti, lcid);
|
||||
if (gtpu_log) {
|
||||
gtpu_log->info("Adding bearer for rnti: 0x%x, lcid: %d, addr: 0x%x, teid_out: 0x%x, teid_in: 0x%x\n",
|
||||
rnti,
|
||||
lcid,
|
||||
addr,
|
||||
teid_out,
|
||||
*teid_in);
|
||||
teid_in);
|
||||
}
|
||||
|
||||
// Initialize maps if it's a new RNTI
|
||||
|
@ -162,15 +162,21 @@ void gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid
|
|||
}
|
||||
}
|
||||
|
||||
rnti_bearers[rnti].teids_in[lcid] = *teid_in;
|
||||
rnti_bearers[rnti].teids_in[lcid] = teid_in;
|
||||
rnti_bearers[rnti].teids_out[lcid] = teid_out;
|
||||
rnti_bearers[rnti].spgw_addrs[lcid] = addr;
|
||||
|
||||
return teid_in;
|
||||
}
|
||||
|
||||
void gtpu::rem_bearer(uint16_t rnti, uint32_t lcid)
|
||||
{
|
||||
gtpu_log->info("Removing bearer for rnti: 0x%x, lcid: %d\n", rnti, lcid);
|
||||
|
||||
// Remove from TEID from map
|
||||
free_teidin(rnti, lcid);
|
||||
|
||||
// Remove
|
||||
rnti_bearers[rnti].teids_in[lcid] = 0;
|
||||
rnti_bearers[rnti].teids_out[lcid] = 0;
|
||||
|
||||
|
@ -186,8 +192,43 @@ void gtpu::rem_bearer(uint16_t rnti, uint32_t lcid)
|
|||
}
|
||||
}
|
||||
|
||||
void gtpu::mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti)
|
||||
{
|
||||
gtpu_log->info("Modifying bearer rnti. Old rnti: 0x%x, new rnti: 0x%x\n", old_rnti, new_rnti);
|
||||
|
||||
if (rnti_bearers.count(new_rnti) != 0) {
|
||||
gtpu_log->error("New rnti already exists, aborting.\n");
|
||||
return;
|
||||
}
|
||||
if (rnti_bearers.count(old_rnti) == 0) {
|
||||
gtpu_log->error("Old rnti does not exist, aborting.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Change RNTI bearers map
|
||||
auto entry = rnti_bearers.find(old_rnti);
|
||||
if (entry != rnti_bearers.end()) {
|
||||
auto const value = std::move(entry->second);
|
||||
rnti_bearers.erase(entry);
|
||||
rnti_bearers.insert({new_rnti, std::move(value)});
|
||||
}
|
||||
|
||||
// Change TEID
|
||||
for (std::map<uint32_t, rnti_lcid_t>::iterator it = teidin_to_rntilcid_map.begin();
|
||||
it != teidin_to_rntilcid_map.end();
|
||||
it++) {
|
||||
if (it->second.rnti == old_rnti) {
|
||||
it->second.rnti = new_rnti;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gtpu::rem_user(uint16_t rnti)
|
||||
{
|
||||
// Free from TEID map
|
||||
free_teidin(rnti);
|
||||
|
||||
// Remove user from RNTI map
|
||||
rnti_bearers.erase(rnti);
|
||||
}
|
||||
|
||||
|
@ -206,14 +247,14 @@ void gtpu::handle_gtpu_s1u_rx_packet(srslte::unique_byte_buffer_t pdu, const soc
|
|||
echo_response(addr.sin_addr.s_addr, addr.sin_port, header.seq_number);
|
||||
break;
|
||||
case GTPU_MSG_DATA_PDU: {
|
||||
uint16_t rnti = 0;
|
||||
uint16_t lcid = 0;
|
||||
teidin_to_rntilcid(header.teid, &rnti, &lcid);
|
||||
rnti_lcid_t rnti_lcid = teidin_to_rntilcid(header.teid);
|
||||
uint16_t rnti = rnti_lcid.rnti;
|
||||
uint16_t lcid = rnti_lcid.lcid;
|
||||
|
||||
bool user_exists = (rnti_bearers.count(rnti) > 0);
|
||||
|
||||
if (not user_exists) {
|
||||
gtpu_log->error("Unrecognized RNTI for DL PDU: 0x%x - dropping packet\n", rnti);
|
||||
gtpu_log->error("Unrecognized TEID In=%d for DL PDU. Dropping packet\n", header.teid);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -264,17 +305,71 @@ void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq)
|
|||
}
|
||||
|
||||
/****************************************************************************
|
||||
* TEID to RNIT/LCID helper functions
|
||||
* TEID to RNTI/LCID helper functions
|
||||
***************************************************************************/
|
||||
void gtpu::teidin_to_rntilcid(uint32_t teidin, uint16_t* rnti, uint16_t* lcid)
|
||||
uint32_t gtpu::allocate_teidin(uint16_t rnti, uint16_t lcid)
|
||||
{
|
||||
*lcid = teidin & 0xFFFF;
|
||||
*rnti = (teidin >> 16) & 0xFFFF;
|
||||
uint32_t teid_in = ++next_teid_in;
|
||||
if (teidin_to_rntilcid_map.count(teid_in) != 0) {
|
||||
gtpu_log->error("TEID In already exists\n");
|
||||
return 0;
|
||||
}
|
||||
rnti_lcid_t rnti_lcid = {rnti, lcid};
|
||||
teidin_to_rntilcid_map[teid_in] = rnti_lcid;
|
||||
gtpu_log->debug("TEID In=%d added\n", teid_in);
|
||||
return teid_in;
|
||||
}
|
||||
|
||||
void gtpu::rntilcid_to_teidin(uint16_t rnti, uint16_t lcid, uint32_t* teidin)
|
||||
void gtpu::free_teidin(uint16_t rnti, uint16_t lcid)
|
||||
{
|
||||
*teidin = (rnti << 16) | lcid;
|
||||
for (std::map<uint32_t, rnti_lcid_t>::iterator it = teidin_to_rntilcid_map.begin();
|
||||
it != teidin_to_rntilcid_map.end();) {
|
||||
if (it->second.rnti == rnti && it->second.lcid == lcid) {
|
||||
gtpu_log->debug("TEID In=%d erased\n", it->first);
|
||||
it = teidin_to_rntilcid_map.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gtpu::free_teidin(uint16_t rnti)
|
||||
{
|
||||
for (std::map<uint32_t, rnti_lcid_t>::iterator it = teidin_to_rntilcid_map.begin();
|
||||
it != teidin_to_rntilcid_map.end();) {
|
||||
if (it->second.rnti == rnti) {
|
||||
gtpu_log->debug("TEID In=%d erased\n", it->first);
|
||||
it = teidin_to_rntilcid_map.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gtpu::rnti_lcid_t gtpu::teidin_to_rntilcid(uint32_t teidin)
|
||||
{
|
||||
rnti_lcid_t rnti_lcid = {};
|
||||
if (teidin_to_rntilcid_map.count(teidin) == 0) {
|
||||
gtpu_log->error("TEID=%d In does not exist.\n", teidin);
|
||||
return rnti_lcid;
|
||||
}
|
||||
rnti_lcid.rnti = teidin_to_rntilcid_map[teidin].rnti;
|
||||
rnti_lcid.lcid = teidin_to_rntilcid_map[teidin].lcid;
|
||||
return rnti_lcid;
|
||||
}
|
||||
|
||||
uint32_t gtpu::rntilcid_to_teidin(uint16_t rnti, uint16_t lcid)
|
||||
{
|
||||
uint32_t teidin = 0;
|
||||
for (const std::pair<const uint32_t, rnti_lcid_t>& item : teidin_to_rntilcid_map) {
|
||||
if (item.second.rnti == rnti and item.second.lcid == lcid) {
|
||||
teidin = item.first;
|
||||
}
|
||||
}
|
||||
if (teidin == 0) {
|
||||
gtpu_log->error("Could not find TEID. RNTI=0x%x, LCID=%d.\n", rnti, lcid);
|
||||
}
|
||||
return teidin;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -314,8 +409,7 @@ bool gtpu::m1u_handler::init(std::string m1u_multiaddr_, std::string m1u_if_addr
|
|||
}
|
||||
|
||||
/* Send an ADD MEMBERSHIP message via setsockopt */
|
||||
struct ip_mreq mreq {
|
||||
};
|
||||
struct ip_mreq mreq {};
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(m1u_multiaddr.c_str()); // Multicast address of the service
|
||||
mreq.imr_interface.s_addr = inet_addr(m1u_if_addr.c_str()); // Address of the IF the socket will listen to.
|
||||
if (setsockopt(m1u_sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
|
||||
|
|
|
@ -124,9 +124,10 @@ public:
|
|||
class gtpu_dummy : public gtpu_interface_rrc
|
||||
{
|
||||
public:
|
||||
void add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, uint32_t* teid_in) override {}
|
||||
void rem_bearer(uint16_t rnti, uint32_t lcid) override {}
|
||||
void rem_user(uint16_t rnti) override {}
|
||||
uint32_t add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out) override { return 0; }
|
||||
void rem_bearer(uint16_t rnti, uint32_t lcid) override {}
|
||||
void mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti) override {}
|
||||
void rem_user(uint16_t rnti) override {}
|
||||
};
|
||||
|
||||
} // namespace srsenb
|
||||
|
|
|
@ -138,14 +138,14 @@ void rrc::init(phy_interface_rrc_lte* phy_,
|
|||
gw_interface_rrc* gw_,
|
||||
const rrc_args_t& args_)
|
||||
{
|
||||
pool = byte_buffer_pool::get_instance();
|
||||
phy = phy_;
|
||||
mac = mac_;
|
||||
rlc = rlc_;
|
||||
pdcp = pdcp_;
|
||||
nas = nas_;
|
||||
usim = usim_;
|
||||
gw = gw_;
|
||||
pool = byte_buffer_pool::get_instance();
|
||||
phy = phy_;
|
||||
mac = mac_;
|
||||
rlc = rlc_;
|
||||
pdcp = pdcp_;
|
||||
nas = nas_;
|
||||
usim = usim_;
|
||||
gw = gw_;
|
||||
|
||||
args = args_;
|
||||
|
||||
|
@ -1818,6 +1818,7 @@ void rrc::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu)
|
|||
|
||||
void rrc::process_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu)
|
||||
{
|
||||
rrc_log->debug("RX PDU, LCID: %d\n", lcid);
|
||||
switch (lcid) {
|
||||
case RB_ID_SRB0:
|
||||
parse_dl_ccch(std::move(pdu));
|
||||
|
@ -1827,7 +1828,7 @@ void rrc::process_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu)
|
|||
parse_dl_dcch(lcid, std::move(pdu));
|
||||
break;
|
||||
default:
|
||||
rrc_log->error("RX PDU with invalid bearer id: %d", lcid);
|
||||
rrc_log->error("RX PDU with invalid bearer id: %d\n", lcid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,7 +214,7 @@ void usim::generate_nas_keys(uint8_t* k_asme,
|
|||
RRC interface
|
||||
*******************************************************************************/
|
||||
|
||||
void usim::generate_as_keys(uint8_t* k_asme, uint32_t count_ul, srslte::as_security_config_t *sec_cfg)
|
||||
void usim::generate_as_keys(uint8_t* k_asme, uint32_t count_ul, srslte::as_security_config_t* sec_cfg)
|
||||
{
|
||||
// Generate K_enb
|
||||
security_generate_k_enb(k_asme, count_ul, k_enb);
|
||||
|
@ -238,6 +238,9 @@ void usim::generate_as_keys(uint8_t* k_asme, uint32_t count_ul, srslte::as_secur
|
|||
|
||||
void usim::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::as_security_config_t* sec_cfg)
|
||||
{
|
||||
usim_log->info("Generating AS Keys HO. PCI 0x%02x, DL-EARFCN %d, NCC %d\n", pci, earfcn, ncc);
|
||||
usim_log->info_hex(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "Original HO K_RCC_enc");
|
||||
usim_log->info_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "Original HO K_RCC_int");
|
||||
uint8_t* enb_star_key = k_enb;
|
||||
|
||||
if (ncc < 0) {
|
||||
|
@ -276,6 +279,9 @@ void usim::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::a
|
|||
// Generate K_up_enc and K_up_int
|
||||
security_generate_k_up(
|
||||
k_enb, sec_cfg->cipher_algo, sec_cfg->integ_algo, sec_cfg->k_up_enc.data(), sec_cfg->k_up_int.data());
|
||||
|
||||
usim_log->info_hex(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "HO K_RCC_enc");
|
||||
usim_log->info_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "HO K_RCC_int");
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
Loading…
Reference in New Issue