diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 84ddc5b5c..cd284619f 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -41,7 +41,7 @@ class pdcp { public: pdcp(); - ~pdcp(); + virtual ~pdcp(); void init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, @@ -78,7 +78,7 @@ public: void write_pdu_bcch_bch(byte_buffer_t *sdu); void write_pdu_bcch_dlsch(byte_buffer_t *sdu); void write_pdu_pcch(byte_buffer_t *sdu); - + private: srsue::rlc_interface_pdcp *rlc; srsue::rrc_interface_pdcp *rrc; @@ -89,6 +89,7 @@ private: log *pdcp_log; pdcp_map_t pdcp_array, pdcp_array_mrb; + pthread_rwlock_t rwlock; // default PDCP entity that is maintained active by PDCP instance srslte_pdcp_config_t default_cnfg; diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index 2d056f631..3f934f73d 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -36,15 +36,20 @@ pdcp::pdcp() gw = NULL; pdcp_log = NULL; default_lcid = 0; + pthread_rwlock_init(&rwlock, NULL); } pdcp::~pdcp() { // destroy all remaining entities + pthread_rwlock_wrlock(&rwlock); for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { delete(it->second); } pdcp_array.clear(); + + pthread_rwlock_unlock(&rwlock); + pthread_rwlock_destroy(&rwlock); } void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, log *pdcp_log_, uint32_t lcid_, uint8_t direction_) @@ -61,34 +66,34 @@ void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_ default_cnfg.direction = direction_; // create default PDCP entity for SRB0 - if (not pdcp_array.insert(pdcp_map_pair_t(0, new pdcp_entity())).second) { - pdcp_log->error("Error inserting PDCP entity in to array\n."); - return; - } - pdcp_array.at(0)->init(rlc, rrc, gw, pdcp_log, default_lcid, default_cnfg); + add_bearer(0, default_cnfg); } void pdcp::stop() { // destroy default entity + pthread_rwlock_wrlock(&rwlock); if (valid_lcid(0)) { - pdcp_map_t::iterator it; - it = pdcp_array.find(0); + pdcp_map_t::iterator it = pdcp_array.find(0); delete(it->second); pdcp_array.erase(it); } + pthread_rwlock_unlock(&rwlock); } void pdcp::reestablish() { + pthread_rwlock_rdlock(&rwlock); for (uint32_t i = 0; i < SRSLTE_N_RADIO_BEARERS; i++) { if (valid_lcid(i)) { pdcp_array.at(i)->reestablish(); } } + pthread_rwlock_unlock(&rwlock); } void pdcp::reset() { + pthread_rwlock_rdlock(&rwlock); for (uint32_t i = 0; i < SRSLTE_N_RADIO_BEARERS; i++) { if (valid_lcid(i)) { pdcp_array.at(i)->reset(); @@ -98,6 +103,7 @@ void pdcp::reset() if (valid_lcid(0)) { pdcp_array.at(0)->init(rlc, rrc, gw, pdcp_log, default_lcid, default_cnfg); } + pthread_rwlock_unlock(&rwlock); } /******************************************************************************* @@ -105,39 +111,46 @@ void pdcp::reset() *******************************************************************************/ bool pdcp::is_drb_enabled(uint32_t lcid) { + pthread_rwlock_rdlock(&rwlock); + bool ret = false; + if (lcid >= SRSLTE_N_RADIO_BEARERS) { pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); - return false; + goto unlock_and_exit; } if (pdcp_array.find(lcid) == pdcp_array.end()) { - return false; + goto unlock_and_exit; } - return pdcp_array.at(lcid)->is_active(); + ret = pdcp_array.at(lcid)->is_active(); + +unlock_and_exit: + pthread_rwlock_unlock(&rwlock); + return ret; } void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { + pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { pdcp_array.at(lcid)->write_sdu(sdu); } else { pdcp_log->warning("Writing sdu: lcid=%d. Deallocating sdu\n", lcid); byte_buffer_pool::get_instance()->deallocate(sdu); } + pthread_rwlock_unlock(&rwlock); } void pdcp::write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu) { + pthread_rwlock_rdlock(&rwlock); if (valid_mch_lcid(lcid)){ pdcp_array_mrb.at(lcid)->write_sdu(sdu); } + pthread_rwlock_unlock(&rwlock); } void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) { - if (lcid >= SRSLTE_N_RADIO_BEARERS) { - pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); - return; - } - + pthread_rwlock_rdlock(&rwlock); if (not valid_lcid(lcid)) { if (not pdcp_array.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { pdcp_log->error("Error inserting PDCP entity in to array\n."); @@ -148,17 +161,15 @@ void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) } else { pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); } + pthread_rwlock_unlock(&rwlock); } void pdcp::add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cfg) { - if (lcid >= SRSLTE_N_RADIO_BEARERS) { - pdcp_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); - return; - } + pthread_rwlock_rdlock(&rwlock); if (not valid_mch_lcid(lcid)) { - if (pdcp_array_mrb.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { + if (not pdcp_array_mrb.insert(pdcp_map_pair_t(lcid, new pdcp_entity())).second) { pdcp_log->error("Error inserting PDCP entity in to array\n."); return; } @@ -167,6 +178,7 @@ void pdcp::add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cfg) } else { pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); } + pthread_rwlock_unlock(&rwlock); } void pdcp::config_security(uint32_t lcid, @@ -175,9 +187,11 @@ void pdcp::config_security(uint32_t lcid, CIPHERING_ALGORITHM_ID_ENUM cipher_algo, INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { + pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { pdcp_array.at(lcid)->config_security(k_enc, k_int, cipher_algo, integ_algo); } + pthread_rwlock_unlock(&rwlock); } void pdcp::config_security_all(uint8_t *k_enc, @@ -185,25 +199,31 @@ void pdcp::config_security_all(uint8_t *k_enc, CIPHERING_ALGORITHM_ID_ENUM cipher_algo, INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { + pthread_rwlock_rdlock(&rwlock); for(uint32_t i=0;iis_active()) { pdcp_array.at(i)->config_security(k_enc, k_int, cipher_algo, integ_algo); } } + pthread_rwlock_unlock(&rwlock); } void pdcp::enable_integrity(uint32_t lcid) { + pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { pdcp_array.at(lcid)->enable_integrity(); } + pthread_rwlock_unlock(&rwlock); } void pdcp::enable_encryption(uint32_t lcid) { + pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { pdcp_array.at(lcid)->enable_encryption(); } + pthread_rwlock_unlock(&rwlock); } /******************************************************************************* @@ -211,18 +231,21 @@ void pdcp::enable_encryption(uint32_t lcid) *******************************************************************************/ void pdcp::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { + pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { pdcp_array.at(lcid)->write_pdu(pdu); } else { pdcp_log->warning("Writing pdu: lcid=%d. Deallocating pdu\n", lcid); byte_buffer_pool::get_instance()->deallocate(pdu); } + pthread_rwlock_unlock(&rwlock); } void pdcp::write_pdu_bcch_bch(byte_buffer_t *sdu) { rrc->write_pdu_bcch_bch(sdu); } + void pdcp::write_pdu_bcch_dlsch(byte_buffer_t *sdu) { rrc->write_pdu_bcch_dlsch(sdu); @@ -243,7 +266,7 @@ void pdcp::write_pdu_mch(uint32_t lcid, byte_buffer_t *sdu) } /******************************************************************************* - Helpers + Helpers (Lock must be hold when calling those) *******************************************************************************/ bool pdcp::valid_lcid(uint32_t lcid) { diff --git a/srsenb/hdr/upper/pdcp.h b/srsenb/hdr/upper/pdcp.h index 9624958e4..ce6b01ca6 100644 --- a/srsenb/hdr/upper/pdcp.h +++ b/srsenb/hdr/upper/pdcp.h @@ -39,7 +39,7 @@ class pdcp : public pdcp_interface_rlc, public pdcp_interface_rrc { public: - + virtual ~pdcp() {}; void init(rlc_interface_pdcp *rlc_, rrc_interface_pdcp *rrc_, gtpu_interface_pdcp *gtpu_, srslte::log *pdcp_log_); void stop(); diff --git a/srsenb/src/upper/pdcp.cc b/srsenb/src/upper/pdcp.cc index 6f07e4ece..7f62477f9 100644 --- a/srsenb/src/upper/pdcp.cc +++ b/srsenb/src/upper/pdcp.cc @@ -56,7 +56,7 @@ void pdcp::add_user(uint16_t rnti) { pthread_rwlock_rdlock(&rwlock); if (users.count(rnti) == 0) { - srslte::pdcp *obj = new srslte::pdcp; + srslte::pdcp *obj = new srslte::pdcp; obj->init(&users[rnti].rlc_itf, &users[rnti].rrc_itf, &users[rnti].gtpu_itf, log_h, RB_ID_SRB0, SECURITY_DIRECTION_DOWNLINK); users[rnti].rlc_itf.rnti = rnti; users[rnti].gtpu_itf.rnti = rnti;