|
|
|
@ -62,30 +62,26 @@ void ue_cc_softbuffers::clear()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cc_used_buffers_map::cc_used_buffers_map(srsran::pdu_queue& shared_pdu_queue_) :
|
|
|
|
|
shared_pdu_queue(&shared_pdu_queue_), logger(&srslog::fetch_basic_logger("MAC"))
|
|
|
|
|
{}
|
|
|
|
|
cc_used_buffers_map::cc_used_buffers_map() : logger(&srslog::fetch_basic_logger("MAC")) {}
|
|
|
|
|
|
|
|
|
|
cc_used_buffers_map::~cc_used_buffers_map()
|
|
|
|
|
{
|
|
|
|
|
clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool cc_used_buffers_map::push_pdu(tti_point tti, uint32_t len, uint32_t grant_nof_prbs)
|
|
|
|
|
srsran::unique_byte_buffer_t cc_used_buffers_map::release_pdu(tti_point tti, uint32_t len)
|
|
|
|
|
{
|
|
|
|
|
if (not has_tti(tti)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
uint8_t* buffer = pdu_map[tti.to_uint()];
|
|
|
|
|
if (len > 0) {
|
|
|
|
|
shared_pdu_queue->push(buffer, len, srsran::pdu_queue::DCH, grant_nof_prbs);
|
|
|
|
|
} else {
|
|
|
|
|
shared_pdu_queue->deallocate(buffer);
|
|
|
|
|
logger->error("Error pushing PDU: null length");
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Extract PDU from PDU map
|
|
|
|
|
srsran::unique_byte_buffer_t pdu = std::move(pdu_map[tti.to_uint()]);
|
|
|
|
|
srsran_expect(pdu->size() == len, "UL buffers: Inconsistent UL PDU length for tti=%d", tti.to_uint());
|
|
|
|
|
|
|
|
|
|
// clear entry in map
|
|
|
|
|
pdu_map.erase(tti.to_uint());
|
|
|
|
|
return len > 0;
|
|
|
|
|
return pdu;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t* cc_used_buffers_map::request_pdu(tti_point tti, uint32_t len)
|
|
|
|
@ -95,15 +91,17 @@ uint8_t* cc_used_buffers_map::request_pdu(tti_point tti, uint32_t len)
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t* pdu = shared_pdu_queue->request(len);
|
|
|
|
|
srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer();
|
|
|
|
|
if (pdu == nullptr) {
|
|
|
|
|
logger->error("UE buffers: Requesting buffer from pool");
|
|
|
|
|
logger->error("UE buffers: Requesting buffer from byte buffer pool");
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
srsran_assert(len < pdu->get_tailroom(), "Requested UL pdu doesn't fit in byte_buffer");
|
|
|
|
|
pdu->N_bytes = len;
|
|
|
|
|
|
|
|
|
|
bool inserted = pdu_map.insert(tti.to_uint(), pdu);
|
|
|
|
|
srsran_assert(inserted, "Failure to allocate new buffer");
|
|
|
|
|
return pdu;
|
|
|
|
|
auto inserted_elem = pdu_map.insert(tti.to_uint(), std::move(pdu));
|
|
|
|
|
srsran_assert(inserted_elem.has_value(), "Failure to allocate new buffer in mac::ue");
|
|
|
|
|
return inserted_elem.value()->second->data();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cc_used_buffers_map::clear_old_pdus(tti_point current_tti)
|
|
|
|
@ -115,40 +113,14 @@ void cc_used_buffers_map::clear_old_pdus(tti_point current_tti)
|
|
|
|
|
tti_point t(pdu_pair.first);
|
|
|
|
|
if (t < max_tti) {
|
|
|
|
|
logger->warning("UE buffers: Removing old buffer tti=%d, interval=%d", t.to_uint(), current_tti - t);
|
|
|
|
|
remove_pdu(t);
|
|
|
|
|
pdu_map.erase(t.to_uint());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cc_used_buffers_map::remove_pdu(tti_point tti)
|
|
|
|
|
{
|
|
|
|
|
uint8_t* buffer = pdu_map[tti.to_uint()];
|
|
|
|
|
// return pdus back to the queue
|
|
|
|
|
shared_pdu_queue->deallocate(buffer);
|
|
|
|
|
// clear entry in map
|
|
|
|
|
pdu_map.erase(tti.to_uint());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool cc_used_buffers_map::try_deallocate_pdu(tti_point tti)
|
|
|
|
|
{
|
|
|
|
|
if (has_tti(tti)) {
|
|
|
|
|
remove_pdu(tti);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cc_used_buffers_map::clear()
|
|
|
|
|
{
|
|
|
|
|
for (auto& buffer : pdu_map) {
|
|
|
|
|
shared_pdu_queue->deallocate(buffer.second);
|
|
|
|
|
}
|
|
|
|
|
pdu_map.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t*& cc_used_buffers_map::operator[](tti_point tti)
|
|
|
|
|
{
|
|
|
|
|
return pdu_map[tti.to_uint()];
|
|
|
|
|
return pdu_map[tti.to_uint()]->msg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool cc_used_buffers_map::has_tti(tti_point tti) const
|
|
|
|
@ -158,7 +130,7 @@ bool cc_used_buffers_map::has_tti(tti_point tti) const
|
|
|
|
|
|
|
|
|
|
////////////////
|
|
|
|
|
|
|
|
|
|
cc_buffer_handler::cc_buffer_handler(srsran::pdu_queue& shared_pdu_queue_) : rx_used_buffers(shared_pdu_queue_)
|
|
|
|
|
cc_buffer_handler::cc_buffer_handler()
|
|
|
|
|
{
|
|
|
|
|
for (auto& harq_buffers : tx_payload_buffer) {
|
|
|
|
|
for (srsran::unique_byte_buffer_t& tb_buffer : harq_buffers) {
|
|
|
|
@ -219,26 +191,15 @@ ue::ue(uint16_t rnti_,
|
|
|
|
|
mac_msg_dl(20, logger_),
|
|
|
|
|
mch_mac_msg_dl(10, logger_),
|
|
|
|
|
mac_msg_ul(20, logger_),
|
|
|
|
|
pdus(logger_),
|
|
|
|
|
ta_fsm(this),
|
|
|
|
|
softbuffer_pool(softbuffer_pool_)
|
|
|
|
|
softbuffer_pool(softbuffer_pool_),
|
|
|
|
|
cc_buffers(nof_cells_)
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < nof_cells_; ++i) {
|
|
|
|
|
cc_buffers.emplace_back(pdus);
|
|
|
|
|
}
|
|
|
|
|
pdus.init(this);
|
|
|
|
|
|
|
|
|
|
// Allocate buffer for PCell
|
|
|
|
|
cc_buffers[0].allocate_cc(softbuffer_pool->make());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ue::~ue()
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock<std::mutex> lock(rx_buffers_mutex);
|
|
|
|
|
for (auto& cc : cc_buffers) {
|
|
|
|
|
cc.get_rx_used_buffers().clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ue::~ue() {}
|
|
|
|
|
|
|
|
|
|
void ue::reset()
|
|
|
|
|
{
|
|
|
|
@ -260,7 +221,7 @@ void ue::start_pcap(srsran::mac_pcap* pcap_)
|
|
|
|
|
pcap = pcap_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srsran_softbuffer_rx_t* ue::get_rx_softbuffer(const uint32_t ue_cc_idx, const uint32_t tti)
|
|
|
|
|
srsran_softbuffer_rx_t* ue::get_rx_softbuffer(uint32_t ue_cc_idx, uint32_t tti)
|
|
|
|
|
{
|
|
|
|
|
if ((size_t)ue_cc_idx >= cc_buffers.size()) {
|
|
|
|
|
ERROR("UE CC Index (%d/%zd) out-of-range", ue_cc_idx, cc_buffers.size());
|
|
|
|
@ -270,8 +231,7 @@ srsran_softbuffer_rx_t* ue::get_rx_softbuffer(const uint32_t ue_cc_idx, const ui
|
|
|
|
|
return &cc_buffers[ue_cc_idx].get_rx_softbuffer(tti);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srsran_softbuffer_tx_t*
|
|
|
|
|
ue::get_tx_softbuffer(const uint32_t ue_cc_idx, const uint32_t harq_process, const uint32_t tb_idx)
|
|
|
|
|
srsran_softbuffer_tx_t* ue::get_tx_softbuffer(uint32_t ue_cc_idx, uint32_t harq_process, uint32_t tb_idx)
|
|
|
|
|
{
|
|
|
|
|
if ((size_t)ue_cc_idx >= cc_buffers.size()) {
|
|
|
|
|
ERROR("UE CC Index (%d/%zd) out-of-range", ue_cc_idx, cc_buffers.size());
|
|
|
|
@ -283,31 +243,20 @@ ue::get_tx_softbuffer(const uint32_t ue_cc_idx, const uint32_t harq_process, con
|
|
|
|
|
|
|
|
|
|
uint8_t* ue::request_buffer(uint32_t tti, uint32_t ue_cc_idx, const uint32_t len)
|
|
|
|
|
{
|
|
|
|
|
srsran_assert(len > 0, "UE buffers: Requesting buffer for zero bytes");
|
|
|
|
|
std::unique_lock<std::mutex> lock(rx_buffers_mutex);
|
|
|
|
|
uint8_t* pdu = nullptr;
|
|
|
|
|
if (len > 0) {
|
|
|
|
|
pdu = cc_buffers[ue_cc_idx].get_rx_used_buffers().request_pdu(tti_point(tti), len);
|
|
|
|
|
} else {
|
|
|
|
|
logger.error("UE buffers: Requesting buffer for zero bytes");
|
|
|
|
|
}
|
|
|
|
|
return pdu;
|
|
|
|
|
return cc_buffers[ue_cc_idx].get_rx_used_buffers().request_pdu(tti_point(tti), len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ue::clear_old_buffers(uint32_t tti)
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock<std::mutex> lock(rx_buffers_mutex);
|
|
|
|
|
|
|
|
|
|
// remove old buffers
|
|
|
|
|
for (auto& cc : cc_buffers) {
|
|
|
|
|
cc.get_rx_used_buffers().clear_old_pdus(tti_point{tti});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ue::process_pdus()
|
|
|
|
|
{
|
|
|
|
|
return pdus.process_pdus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ue::set_tti(uint32_t tti)
|
|
|
|
|
{
|
|
|
|
|
last_tti = tti;
|
|
|
|
@ -329,11 +278,11 @@ uint32_t ue::set_ta(int ta_)
|
|
|
|
|
return nof_cmd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srsran::pdu_queue::channel_t channel, int grant_nof_prbs)
|
|
|
|
|
void ue::process_pdu(srsran::unique_byte_buffer_t pdu, uint32_t grant_nof_prbs)
|
|
|
|
|
{
|
|
|
|
|
// Unpack ULSCH MAC PDU
|
|
|
|
|
mac_msg_ul.init_rx(nof_bytes, true);
|
|
|
|
|
mac_msg_ul.parse_packet(pdu);
|
|
|
|
|
mac_msg_ul.init_rx(pdu->size(), true);
|
|
|
|
|
mac_msg_ul.parse_packet(pdu->data());
|
|
|
|
|
|
|
|
|
|
if (logger.info.enabled()) {
|
|
|
|
|
fmt::memory_buffer str_buffer;
|
|
|
|
@ -341,16 +290,14 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srsran::pdu_queue::channe
|
|
|
|
|
logger.info("0x%x %s", rnti, srsran::to_c_str(str_buffer));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pcap) {
|
|
|
|
|
pcap->write_ul_crnti(pdu, nof_bytes, rnti, true, last_tti, UL_CC_IDX);
|
|
|
|
|
if (pcap != nullptr) {
|
|
|
|
|
pcap->write_ul_crnti(pdu->data(), pdu->size(), rnti, true, last_tti, UL_CC_IDX);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pcap_net) {
|
|
|
|
|
pcap_net->write_ul_crnti(pdu, nof_bytes, rnti, true, last_tti, UL_CC_IDX);
|
|
|
|
|
if (pcap_net != nullptr) {
|
|
|
|
|
pcap_net->write_ul_crnti(pdu->data(), pdu->size(), rnti, true, last_tti, UL_CC_IDX);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pdus.deallocate(pdu);
|
|
|
|
|
|
|
|
|
|
uint32_t lcid_most_data = 0;
|
|
|
|
|
int most_data = -99;
|
|
|
|
|
|
|
|
|
@ -386,7 +333,7 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srsran::pdu_queue::channe
|
|
|
|
|
// Indicate DRB activity in UL to RRC
|
|
|
|
|
if (mac_msg_ul.get()->get_sdu_lcid() > 2) {
|
|
|
|
|
rrc->set_activity_user(rnti);
|
|
|
|
|
logger.debug("UL activity rnti=0x%x, n_bytes=%d", rnti, nof_bytes);
|
|
|
|
|
logger.debug("UL activity rnti=0x%x, n_bytes=%d", rnti, pdu->size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((int)mac_msg_ul.get()->get_payload_size() > most_data) {
|
|
|
|
@ -431,24 +378,13 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srsran::pdu_queue::channe
|
|
|
|
|
logger.debug("MAC PDU processed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ue::deallocate_pdu(uint32_t tti, uint32_t ue_cc_idx)
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock<std::mutex> lock(rx_buffers_mutex);
|
|
|
|
|
if (not cc_buffers[ue_cc_idx].get_rx_used_buffers().try_deallocate_pdu(tti_point(tti))) {
|
|
|
|
|
logger.warning(
|
|
|
|
|
"UE buffers: Null RX PDU pointer in deallocate_pdu for rnti=0x%x tti=%d cc_idx=%d", rnti, tti, ue_cc_idx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ue::push_pdu(uint32_t tti, uint32_t ue_cc_idx, uint32_t len, uint32_t grant_nof_prbs)
|
|
|
|
|
srsran::unique_byte_buffer_t ue::release_pdu(uint32_t tti, uint32_t ue_cc_idx, uint32_t len)
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock<std::mutex> lock(rx_buffers_mutex);
|
|
|
|
|
if (not cc_buffers[ue_cc_idx].get_rx_used_buffers().push_pdu(tti_point(tti), len, grant_nof_prbs)) {
|
|
|
|
|
logger.warning("UE buffers: Failed to push RX PDU for rnti=0x%x tti=%d cc_idx=%d", rnti, tti, ue_cc_idx);
|
|
|
|
|
}
|
|
|
|
|
std::lock_guard<std::mutex> lock(rx_buffers_mutex);
|
|
|
|
|
return cc_buffers[ue_cc_idx].get_rx_used_buffers().release_pdu(tti_point(tti), len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ue::process_ce(srsran::sch_subh* subh, int grant_nof_prbs)
|
|
|
|
|
bool ue::process_ce(srsran::sch_subh* subh, uint32_t grant_nof_prbs)
|
|
|
|
|
{
|
|
|
|
|
uint32_t buff_size_idx[4] = {};
|
|
|
|
|
uint32_t buff_size_bytes[4] = {};
|
|
|
|
|