diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index d4cca957a..84ddc5b5c 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -41,7 +41,7 @@ class pdcp { public: pdcp(); - virtual ~pdcp(){} + ~pdcp(); void init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, @@ -79,17 +79,20 @@ public: 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; srsue::gw_interface_pdcp *gw; - log *pdcp_log; - pdcp_entity pdcp_array[SRSLTE_N_RADIO_BEARERS]; - pdcp_entity pdcp_array_mrb[SRSLTE_N_MCH_LCIDS]; - uint32_t lcid; // default LCID that is maintained active by PDCP instance - uint8_t direction; + typedef std::map pdcp_map_t; + typedef std::pair pdcp_map_pair_t; + + log *pdcp_log; + pdcp_map_t pdcp_array, pdcp_array_mrb; + + // default PDCP entity that is maintained active by PDCP instance + srslte_pdcp_config_t default_cnfg; + uint32_t default_lcid; bool valid_lcid(uint32_t lcid); bool valid_mch_lcid(uint32_t lcid); diff --git a/lib/include/srslte/upper/pdcp_entity.h b/lib/include/srslte/upper/pdcp_entity.h index de51ed1de..6586becc0 100644 --- a/lib/include/srslte/upper/pdcp_entity.h +++ b/lib/include/srslte/upper/pdcp_entity.h @@ -33,6 +33,7 @@ #include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/security.h" #include "srslte/common/threads.h" +#include "pdcp_interface.h" namespace srslte { @@ -59,7 +60,7 @@ static const char pdcp_d_c_text[PDCP_D_C_N_ITEMS][20] = {"Control PDU", * PDCP Entity interface * Common interface for all PDCP entities ***************************************************************************/ -class pdcp_entity +class pdcp_entity : public pdcp_entity_interface { public: pdcp_entity(); diff --git a/lib/include/srslte/upper/pdcp_interface.h b/lib/include/srslte/upper/pdcp_interface.h index 9182c74ea..915fbe420 100644 --- a/lib/include/srslte/upper/pdcp_interface.h +++ b/lib/include/srslte/upper/pdcp_interface.h @@ -43,6 +43,7 @@ namespace srslte { class pdcp_entity_interface { public: + virtual ~pdcp_entity_interface() {}; virtual void init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index e577a12ce..2d056f631 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -35,47 +35,69 @@ pdcp::pdcp() rrc = NULL; gw = NULL; pdcp_log = NULL; - lcid = 0; - direction = 0; + default_lcid = 0; +} + +pdcp::~pdcp() +{ + // destroy all remaining entities + for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { + delete(it->second); + } + pdcp_array.clear(); } 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_) { - rlc = rlc_; - rrc = rrc_; - gw = gw_; - pdcp_log = pdcp_log_; - lcid = lcid_; - direction = direction_; + rlc = rlc_; + rrc = rrc_; + gw = gw_; + pdcp_log = pdcp_log_; + default_lcid = lcid_; // Default config - srslte_pdcp_config_t cnfg; - cnfg.is_control = false; - cnfg.is_data = false; - cnfg.direction = direction_; + default_cnfg.is_control = false; + default_cnfg.is_data = false; + default_cnfg.direction = direction_; - pdcp_array[0].init(rlc, rrc, gw, pdcp_log, lcid, cnfg); + // 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); } void pdcp::stop() { + // destroy default entity + if (valid_lcid(0)) { + pdcp_map_t::iterator it; + it = pdcp_array.find(0); + delete(it->second); + pdcp_array.erase(it); + } } void pdcp::reestablish() { - for(uint32_t i=0;ireestablish(); } } } void pdcp::reset() { - for(uint32_t i=0;ireset(); + } } - pdcp_array[0].init(rlc, rrc, gw, pdcp_log, lcid, direction); + if (valid_lcid(0)) { + pdcp_array.at(0)->init(rlc, rrc, gw, pdcp_log, default_lcid, default_cnfg); + } } /******************************************************************************* @@ -83,17 +105,20 @@ void pdcp::reset() *******************************************************************************/ bool pdcp::is_drb_enabled(uint32_t lcid) { - if(lcid >= SRSLTE_N_RADIO_BEARERS) { + 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; } - return pdcp_array[lcid].is_active(); + if (pdcp_array.find(lcid) == pdcp_array.end()) { + return false; + } + return pdcp_array.at(lcid)->is_active(); } void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { - if(valid_lcid(lcid)) { - pdcp_array[lcid].write_sdu(sdu); + 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); @@ -102,18 +127,23 @@ void pdcp::write_sdu(uint32_t lcid, byte_buffer_t *sdu) void pdcp::write_sdu_mch(uint32_t lcid, byte_buffer_t *sdu) { - if(valid_mch_lcid(lcid)){ - pdcp_array_mrb[lcid].write_sdu(sdu); + if (valid_mch_lcid(lcid)){ + pdcp_array_mrb.at(lcid)->write_sdu(sdu); } } void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) { - if(lcid >= SRSLTE_N_RADIO_BEARERS) { + 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; } - if (!pdcp_array[lcid].is_active()) { - pdcp_array[lcid].init(rlc, rrc, gw, pdcp_log, lcid, cfg); + + 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."); + return; + } + pdcp_array.at(lcid)->init(rlc, rrc, gw, pdcp_log, lcid, cfg); pdcp_log->info("Added bearer %s\n", rrc->get_rb_name(lcid).c_str()); } else { pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); @@ -123,12 +153,16 @@ void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg) void pdcp::add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cfg) { - if(lcid >= SRSLTE_N_RADIO_BEARERS) { + 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; } - if (!pdcp_array_mrb[lcid].is_active()) { - pdcp_array_mrb[lcid].init(rlc, rrc, gw, pdcp_log, lcid, cfg); + if (not valid_mch_lcid(lcid)) { + if (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; + } + pdcp_array_mrb.at(lcid)->init(rlc, rrc, gw, pdcp_log, lcid, cfg); pdcp_log->info("Added bearer %s\n", rrc->get_rb_name(lcid).c_str()); } else { pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); @@ -141,8 +175,9 @@ void pdcp::config_security(uint32_t lcid, CIPHERING_ALGORITHM_ID_ENUM cipher_algo, INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { - if(valid_lcid(lcid)) - pdcp_array[lcid].config_security(k_enc, k_int, cipher_algo, integ_algo); + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->config_security(k_enc, k_int, cipher_algo, integ_algo); + } } void pdcp::config_security_all(uint8_t *k_enc, @@ -151,22 +186,24 @@ void pdcp::config_security_all(uint8_t *k_enc, INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { for(uint32_t i=0;iis_active()) { + pdcp_array.at(i)->config_security(k_enc, k_int, cipher_algo, integ_algo); } } } void pdcp::enable_integrity(uint32_t lcid) { - if(valid_lcid(lcid)) - pdcp_array[lcid].enable_integrity(); + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->enable_integrity(); + } } void pdcp::enable_encryption(uint32_t lcid) { - if(valid_lcid(lcid)) - pdcp_array[lcid].enable_encryption(); + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->enable_encryption(); + } } /******************************************************************************* @@ -174,8 +211,8 @@ void pdcp::enable_encryption(uint32_t lcid) *******************************************************************************/ void pdcp::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { - if(valid_lcid(lcid)) { - pdcp_array[lcid].write_pdu(pdu); + 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); @@ -198,7 +235,7 @@ void pdcp::write_pdu_pcch(byte_buffer_t *sdu) void pdcp::write_pdu_mch(uint32_t lcid, byte_buffer_t *sdu) { - if(0 == lcid) { + if (0 == lcid) { rrc->write_pdu_mch(lcid, sdu); } else { gw->write_pdu_mch(lcid, sdu); @@ -210,27 +247,31 @@ void pdcp::write_pdu_mch(uint32_t lcid, byte_buffer_t *sdu) *******************************************************************************/ bool pdcp::valid_lcid(uint32_t lcid) { - if(lcid >= SRSLTE_N_RADIO_BEARERS) { + if (lcid >= SRSLTE_N_RADIO_BEARERS) { pdcp_log->error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); return false; } - if(!pdcp_array[lcid].is_active()) { + + if (pdcp_array.find(lcid) == pdcp_array.end()) { pdcp_log->error("PDCP entity for logical channel %d has not been activated\n", lcid); return false; } + return true; } bool pdcp::valid_mch_lcid(uint32_t lcid) { - if(lcid >= SRSLTE_N_MCH_LCIDS) { + if (lcid >= SRSLTE_N_MCH_LCIDS) { pdcp_log->error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); return false; } - if(!pdcp_array_mrb[lcid].is_active()) { + + if (pdcp_array_mrb.find(lcid) == pdcp_array_mrb.end()) { pdcp_log->error("PDCP entity for logical channel %d has not been activated\n", lcid); return false; } + return true; }