replaced byte_buffer_t allocated by the buffer pool for unique_byte_buffer which is safer and easier to use

This commit is contained in:
Francisco Paisana 2019-05-01 17:41:04 +01:00 committed by Andre Puschmann
parent 0976ea6f27
commit f469e2178b
42 changed files with 787 additions and 883 deletions

View File

@ -49,15 +49,16 @@ public:
// Callback functions for mutexed operations inside pop/push methods // Callback functions for mutexed operations inside pop/push methods
class call_mutexed_itf { class call_mutexed_itf {
public: public:
virtual void popping(myobj obj) = 0; virtual void popping(const myobj& obj) = 0;
virtual void pushing(myobj obj) = 0; virtual void pushing(const myobj& obj) = 0;
}; };
block_queue<myobj>(int capacity = -1) { explicit block_queue<myobj>(int capacity_ = -1)
{
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cv_empty, NULL); pthread_cond_init(&cv_empty, NULL);
pthread_cond_init(&cv_full, NULL); pthread_cond_init(&cv_full, NULL);
this->capacity = capacity; capacity = capacity_;
mutexed_callback = NULL; mutexed_callback = NULL;
enable = true; enable = true;
num_threads = 0; num_threads = 0;
@ -93,10 +94,14 @@ public:
push_(value, true); push_(value, true);
} }
void push(myobj&& value) { push_(std::move(value), true); }
bool try_push(const myobj& value) { bool try_push(const myobj& value) {
return push_(value, false); return push_(value, false);
} }
bool try_push(myobj&& value) { return push_(std::move(value), false); }
bool try_pop(myobj *value) { bool try_pop(myobj *value) {
return pop_(value, false); return pop_(value, false);
} }
@ -144,13 +149,13 @@ private:
goto exit; goto exit;
} }
if (value) { if (value) {
*value = q.front(); *value = std::move(q.front());
}
if (mutexed_callback) {
mutexed_callback->popping(*value); // FIXME: Value might be null!
} }
q.pop(); q.pop();
ret = true; ret = true;
if (mutexed_callback) {
mutexed_callback->popping(*value);
}
pthread_cond_signal(&cv_full); pthread_cond_signal(&cv_full);
exit: exit:
num_threads--; num_threads--;
@ -158,7 +163,9 @@ private:
return ret; return ret;
} }
bool push_(const myobj& value, bool block) { template <typename MyObj> // universal ref
bool push_(MyObj&& value, bool block)
{
if (!enable) { if (!enable) {
return false; return false;
} }
@ -177,11 +184,11 @@ private:
goto exit; goto exit;
} }
} }
q.push(value);
ret = true;
if (mutexed_callback) { if (mutexed_callback) {
mutexed_callback->pushing(value); mutexed_callback->pushing(value);
} }
q.push(std::forward<MyObj>(value));
ret = true;
pthread_cond_signal(&cv_empty); pthread_cond_signal(&cv_empty);
exit: exit:
num_threads--; num_threads--;

View File

@ -183,6 +183,8 @@ public:
log = NULL; log = NULL;
pool = new buffer_pool<byte_buffer_t>(capacity); pool = new buffer_pool<byte_buffer_t>(capacity);
} }
byte_buffer_pool(const byte_buffer_pool& other) = delete;
byte_buffer_pool& operator=(const byte_buffer_pool& other) = delete;
~byte_buffer_pool() { ~byte_buffer_pool() {
delete pool; delete pool;
} }
@ -222,24 +224,21 @@ private:
buffer_pool<byte_buffer_t> *pool; buffer_pool<byte_buffer_t> *pool;
}; };
inline bool byte_buffer_guard::allocate() inline void byte_buffer_deleter::operator()(byte_buffer_t* buf) const
{ {
deallocate(); if (buf) {
buf = pool->allocate(); pool->deallocate(buf);
if (buf == nullptr) {
// allocation failed
pool = nullptr;
return false;
} }
return true;
} }
inline void byte_buffer_guard::deallocate() inline unique_byte_buffer allocate_unique_buffer(byte_buffer_pool& pool, bool blocking = false)
{ {
if (buf != nullptr) { return std::move(unique_byte_buffer(pool.allocate(nullptr, blocking), byte_buffer_deleter(&pool)));
pool->deallocate(buf); }
buf = nullptr;
} inline unique_byte_buffer allocate_unique_buffer(byte_buffer_pool& pool, const char* debug_name, bool blocking = false)
{
return std::move(unique_byte_buffer(pool.allocate(debug_name, blocking), byte_buffer_deleter(&pool)));
} }
} // namespace srsue } // namespace srsue

View File

@ -26,6 +26,7 @@
INCLUDES INCLUDES
*******************************************************************************/ *******************************************************************************/
#include <memory>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -266,79 +267,17 @@ private:
#endif #endif
}; };
// Create a Managed Life-Time Byte Buffer
class byte_buffer_pool; class byte_buffer_pool;
class byte_buffer_guard class byte_buffer_deleter
{ {
public: public:
byte_buffer_guard(byte_buffer_pool* pool_) : pool(pool_) {} explicit byte_buffer_deleter(byte_buffer_pool* pool_ = nullptr) : pool(pool_) {}
byte_buffer_guard(byte_buffer_t* buf_, byte_buffer_pool* pool_) : buf(buf_), pool(pool_) {} void operator()(byte_buffer_t* buf) const;
byte_buffer_guard(const byte_buffer_guard& other) = delete;
byte_buffer_guard& operator=(const byte_buffer_guard& other) = delete;
// move ctor
byte_buffer_guard(byte_buffer_guard&& other)
{
printf("In move ctor\n");
buf = other.buf;
pool = other.pool;
other.buf = nullptr;
}
byte_buffer_guard& operator=(byte_buffer_guard&& other) noexcept
{
printf("in copy move ctor\n");
if (this == &other) {
return *this;
}
this->buf = other.buf;
this->pool = other.pool;
other.buf = nullptr;
return *this;
}
~byte_buffer_guard() { deallocate(); }
void set_pool(byte_buffer_pool* pool_)
{
deallocate();
pool = pool_;
}
// acquire already alloc buffer
void acquire(byte_buffer_t* buf_) { buf = buf_; }
// allocate buffer
// bool allocate() {
// deallocate();
// buf = pool->allocate();
// if(buf == nullptr) {
// // allocation failed
// pool = nullptr;
// return false;
// }
// return true;
// }
bool allocate();
void deallocate();
byte_buffer_t* operator->() { return buf; }
const byte_buffer_t* operator->() const { return buf; }
byte_buffer_t* get() { return buf; }
const byte_buffer_t* get() const { return buf; }
const byte_buffer_pool* get_pool() const { return pool; }
private:
byte_buffer_t* buf = nullptr;
byte_buffer_pool* pool; byte_buffer_pool* pool;
// void deallocate() {
// if (buf != nullptr) {
// printf("called dealloc!\n");
// pool->deallocate(buf);
// }
// }
}; };
typedef byte_buffer_guard unique_pool_buffer; typedef std::unique_ptr<byte_buffer_t, byte_buffer_deleter> unique_byte_buffer;
} // namespace srslte } // namespace srslte

View File

@ -179,7 +179,7 @@ class rlc_interface_pdcp
public: public:
/* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls /* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls
* RLC PDUs according to TB size. */ * RLC PDUs according to TB size. */
virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer sdu) = 0;
virtual bool rb_is_um(uint16_t rnti, uint32_t lcid) = 0; virtual bool rb_is_um(uint16_t rnti, uint32_t lcid) = 0;
}; };
@ -199,7 +199,7 @@ public:
class pdcp_interface_gtpu class pdcp_interface_gtpu
{ {
public: public:
virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_pool_buffer sdu) = 0; virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer sdu) = 0;
}; };
// PDCP interface for RRC // PDCP interface for RRC
@ -209,7 +209,7 @@ public:
virtual void reset(uint16_t rnti) = 0; virtual void reset(uint16_t rnti) = 0;
virtual void add_user(uint16_t rnti) = 0; virtual void add_user(uint16_t rnti) = 0;
virtual void rem_user(uint16_t rnti) = 0; virtual void rem_user(uint16_t rnti) = 0;
virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer sdu) = 0;
virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_pdcp_config_t cnfg) = 0; virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_pdcp_config_t cnfg) = 0;
virtual void config_security(uint16_t rnti, virtual void config_security(uint16_t rnti,
uint32_t lcid, uint32_t lcid,
@ -227,7 +227,7 @@ class pdcp_interface_rlc
{ {
public: public:
/* RLC calls PDCP to push a PDCP PDU. */ /* RLC calls PDCP to push a PDCP PDU. */
virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer sdu) = 0;
}; };
// RRC interface for RLC // RRC interface for RLC
@ -255,14 +255,14 @@ public:
class rrc_interface_pdcp class rrc_interface_pdcp
{ {
public: public:
virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer pdu) = 0;
}; };
// RRC interface for S1AP // RRC interface for S1AP
class rrc_interface_s1ap class rrc_interface_s1ap
{ {
public: public:
virtual void write_dl_info(uint16_t rnti, srslte::byte_buffer_t *sdu) = 0; virtual void write_dl_info(uint16_t rnti, srslte::unique_byte_buffer sdu) = 0;
virtual void release_complete(uint16_t rnti) = 0; virtual void release_complete(uint16_t rnti) = 0;
virtual bool setup_ue_ctxt(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg) = 0; virtual bool setup_ue_ctxt(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg) = 0;
virtual bool setup_ue_erabs(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *msg) = 0; virtual bool setup_ue_erabs(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *msg) = 0;
@ -274,7 +274,7 @@ public:
class gtpu_interface_pdcp class gtpu_interface_pdcp
{ {
public: public:
virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer pdu) = 0;
}; };
// GTPU interface for RRC // GTPU interface for RRC
@ -290,9 +290,14 @@ public:
class s1ap_interface_rrc class s1ap_interface_rrc
{ {
public: public:
virtual void initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::byte_buffer_t *pdu) = 0; virtual void
virtual void initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::byte_buffer_t *pdu, uint32_t m_tmsi, uint8_t mmec) = 0; initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::unique_byte_buffer pdu) = 0;
virtual void write_pdu(uint16_t rnti, srslte::byte_buffer_t *pdu) = 0; virtual void initial_ue(uint16_t rnti,
LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause,
srslte::unique_byte_buffer pdu,
uint32_t m_tmsi,
uint8_t mmec) = 0;
virtual void write_pdu(uint16_t rnti, srslte::unique_byte_buffer pdu) = 0;
virtual bool user_exists(uint16_t rnti) = 0; virtual bool user_exists(uint16_t rnti) = 0;
virtual bool user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio) = 0; virtual bool user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio) = 0;
virtual void ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *res) = 0; virtual void ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *res) = 0;

View File

@ -114,8 +114,8 @@ public:
class gw_interface_pdcp class gw_interface_pdcp
{ {
public: public:
virtual void write_pdu(uint32_t lcid, srslte::unique_pool_buffer pdu) = 0; virtual void write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu) = 0;
virtual void write_pdu_mch(uint32_t lcid, srslte::unique_pool_buffer pdu) = 0; virtual void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer pdu) = 0;
}; };
// NAS interface for RRC // NAS interface for RRC
@ -132,7 +132,7 @@ public:
virtual void set_barring(barring_t barring) = 0; virtual void set_barring(barring_t barring) = 0;
virtual void paging(asn1::rrc::s_tmsi_s* ue_identiy) = 0; virtual void paging(asn1::rrc::s_tmsi_s* ue_identiy) = 0;
virtual bool is_attached() = 0; virtual bool is_attached() = 0;
virtual void write_pdu(uint32_t lcid, srslte::unique_pool_buffer pdu) = 0; virtual void write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu) = 0;
virtual uint32_t get_k_enb_count() = 0; virtual uint32_t get_k_enb_count() = 0;
virtual bool get_k_asme(uint8_t *k_asme_, uint32_t n) = 0; virtual bool get_k_asme(uint8_t *k_asme_, uint32_t n) = 0;
virtual uint32_t get_ipv4_addr() = 0; virtual uint32_t get_ipv4_addr() = 0;
@ -189,13 +189,14 @@ public:
const static int MAX_FOUND_PLMNS = 16; const static int MAX_FOUND_PLMNS = 16;
virtual void write_sdu(srslte::unique_pool_buffer sdu) = 0; virtual void write_sdu(srslte::unique_byte_buffer sdu) = 0;
virtual uint16_t get_mcc() = 0; virtual uint16_t get_mcc() = 0;
virtual uint16_t get_mnc() = 0; virtual uint16_t get_mnc() = 0;
virtual void enable_capabilities() = 0; virtual void enable_capabilities() = 0;
virtual int plmn_search(found_plmn_t found_plmns[MAX_FOUND_PLMNS]) = 0; virtual int plmn_search(found_plmn_t found_plmns[MAX_FOUND_PLMNS]) = 0;
virtual void plmn_select(asn1::rrc::plmn_id_s plmn_id) = 0; virtual void plmn_select(asn1::rrc::plmn_id_s plmn_id) = 0;
virtual bool connection_request(asn1::rrc::establishment_cause_e cause, srslte::byte_buffer_t* dedicatedInfoNAS) = 0; virtual bool connection_request(asn1::rrc::establishment_cause_e cause,
srslte::unique_byte_buffer dedicatedInfoNAS) = 0;
virtual void set_ue_idenity(asn1::rrc::s_tmsi_s s_tmsi) = 0; virtual void set_ue_idenity(asn1::rrc::s_tmsi_s s_tmsi) = 0;
virtual bool is_connected() = 0; virtual bool is_connected() = 0;
virtual std::string get_rb_name(uint32_t lcid) = 0; virtual std::string get_rb_name(uint32_t lcid) = 0;
@ -205,11 +206,11 @@ public:
class rrc_interface_pdcp class rrc_interface_pdcp
{ {
public: public:
virtual void write_pdu(uint32_t lcid, srslte::unique_pool_buffer pdu) = 0; virtual void write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu) = 0;
virtual void write_pdu_bcch_bch(srslte::unique_pool_buffer pdu) = 0; virtual void write_pdu_bcch_bch(srslte::unique_byte_buffer pdu) = 0;
virtual void write_pdu_bcch_dlsch(srslte::unique_pool_buffer pdu) = 0; virtual void write_pdu_bcch_dlsch(srslte::unique_byte_buffer pdu) = 0;
virtual void write_pdu_pcch(srslte::unique_pool_buffer pdu) = 0; virtual void write_pdu_pcch(srslte::unique_byte_buffer pdu) = 0;
virtual void write_pdu_mch(uint32_t lcid, srslte::unique_pool_buffer pdu) = 0; virtual void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer pdu) = 0;
virtual std::string get_rb_name(uint32_t lcid) = 0; virtual std::string get_rb_name(uint32_t lcid) = 0;
}; };
@ -225,7 +226,7 @@ public:
class pdcp_interface_gw class pdcp_interface_gw
{ {
public: public:
virtual void write_sdu(uint32_t lcid, srslte::unique_pool_buffer sdu, bool blocking) = 0; virtual void write_sdu(uint32_t lcid, srslte::unique_byte_buffer sdu, bool blocking) = 0;
virtual bool is_lcid_enabled(uint32_t lcid) = 0; virtual bool is_lcid_enabled(uint32_t lcid) = 0;
}; };
@ -235,7 +236,7 @@ class pdcp_interface_rrc
public: public:
virtual void reestablish() = 0; virtual void reestablish() = 0;
virtual void reset() = 0; virtual void reset() = 0;
virtual void write_sdu(uint32_t lcid, srslte::unique_pool_buffer sdu, bool blocking = true) = 0; virtual void write_sdu(uint32_t lcid, srslte::unique_byte_buffer sdu, bool blocking = true) = 0;
virtual void add_bearer(uint32_t lcid, srslte::srslte_pdcp_config_t cnfg = srslte::srslte_pdcp_config_t()) = 0; virtual void add_bearer(uint32_t lcid, srslte::srslte_pdcp_config_t cnfg = srslte::srslte_pdcp_config_t()) = 0;
virtual void change_lcid(uint32_t old_lcid, uint32_t new_lcid) = 0; virtual void change_lcid(uint32_t old_lcid, uint32_t new_lcid) = 0;
virtual void config_security(uint32_t lcid, virtual void config_security(uint32_t lcid,
@ -260,11 +261,11 @@ class pdcp_interface_rlc
{ {
public: public:
/* RLC calls PDCP to push a PDCP PDU. */ /* RLC calls PDCP to push a PDCP PDU. */
virtual void write_pdu(uint32_t lcid, srslte::unique_pool_buffer sdu) = 0; virtual void write_pdu(uint32_t lcid, srslte::unique_byte_buffer sdu) = 0;
virtual void write_pdu_bcch_bch(srslte::unique_pool_buffer sdu) = 0; virtual void write_pdu_bcch_bch(srslte::unique_byte_buffer sdu) = 0;
virtual void write_pdu_bcch_dlsch(srslte::unique_pool_buffer sdu) = 0; virtual void write_pdu_bcch_dlsch(srslte::unique_byte_buffer sdu) = 0;
virtual void write_pdu_pcch(srslte::unique_pool_buffer sdu) = 0; virtual void write_pdu_pcch(srslte::unique_byte_buffer sdu) = 0;
virtual void write_pdu_mch(uint32_t lcid, srslte::unique_pool_buffer sdu) = 0; virtual void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) = 0;
}; };
// RLC interface for RRC // RLC interface for RRC
@ -289,7 +290,7 @@ class rlc_interface_pdcp
public: public:
/* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls /* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls
* RLC PDUs according to TB size. */ * RLC PDUs according to TB size. */
virtual void write_sdu(uint32_t lcid, srslte::unique_pool_buffer sdu, bool blocking = true) = 0; virtual void write_sdu(uint32_t lcid, srslte::unique_byte_buffer sdu, bool blocking = true) = 0;
virtual bool rb_is_um(uint32_t lcid) = 0; virtual bool rb_is_um(uint32_t lcid) = 0;
}; };

View File

@ -51,8 +51,8 @@ public:
// RRC interface // RRC interface
void reestablish(); void reestablish();
void reset(); void reset();
void write_sdu(uint32_t lcid, unique_pool_buffer sdu, bool blocking = true); void write_sdu(uint32_t lcid, unique_byte_buffer sdu, bool blocking = true);
void write_sdu_mch(uint32_t lcid, unique_pool_buffer sdu); void write_sdu_mch(uint32_t lcid, unique_byte_buffer sdu);
void add_bearer(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t()); void add_bearer(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t());
void add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t()); void add_bearer_mrb(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t());
void del_bearer(uint32_t lcid); void del_bearer(uint32_t lcid);
@ -74,11 +74,11 @@ public:
uint32_t get_ul_count(uint32_t lcid); uint32_t get_ul_count(uint32_t lcid);
// RLC interface // RLC interface
void write_pdu(uint32_t lcid, unique_pool_buffer sdu); void write_pdu(uint32_t lcid, unique_byte_buffer sdu);
void write_pdu_mch(uint32_t lcid, unique_pool_buffer sdu); void write_pdu_mch(uint32_t lcid, unique_byte_buffer sdu);
void write_pdu_bcch_bch(unique_pool_buffer sdu); void write_pdu_bcch_bch(unique_byte_buffer sdu);
void write_pdu_bcch_dlsch(unique_pool_buffer sdu); void write_pdu_bcch_dlsch(unique_byte_buffer sdu);
void write_pdu_pcch(unique_pool_buffer sdu); void write_pdu_pcch(unique_byte_buffer sdu);
private: private:
srsue::rlc_interface_pdcp *rlc; srsue::rlc_interface_pdcp *rlc;

View File

@ -72,7 +72,7 @@ public:
bool is_active(); bool is_active();
// RRC interface // RRC interface
void write_sdu(unique_pool_buffer sdu, bool blocking); void write_sdu(unique_byte_buffer sdu, bool blocking);
void config_security(uint8_t *k_rrc_enc_, void config_security(uint8_t *k_rrc_enc_,
uint8_t *k_rrc_int_, uint8_t *k_rrc_int_,
uint8_t *k_up_enc_, uint8_t *k_up_enc_,
@ -84,7 +84,7 @@ public:
uint32_t get_ul_count(); uint32_t get_ul_count();
// RLC interface // RLC interface
void write_pdu(unique_pool_buffer pdu); void write_pdu(unique_byte_buffer pdu);
private: private:
byte_buffer_pool *pool; byte_buffer_pool *pool;

View File

@ -50,7 +50,7 @@ public:
virtual bool is_active() = 0; virtual bool is_active() = 0;
// RRC interface // RRC interface
virtual void write_sdu(unique_pool_buffer sdu, bool blocking) = 0; virtual void write_sdu(unique_byte_buffer sdu, bool blocking) = 0;
virtual void config_security(uint8_t *k_rrc_enc_, virtual void config_security(uint8_t *k_rrc_enc_,
uint8_t *k_rrc_int_, uint8_t *k_rrc_int_,
uint8_t *k_up_enc_, uint8_t *k_up_enc_,
@ -62,7 +62,7 @@ public:
virtual uint32_t get_ul_count() = 0; virtual uint32_t get_ul_count() = 0;
// RLC interface // RLC interface
virtual void write_pdu(unique_pool_buffer pdu) = 0; virtual void write_pdu(unique_byte_buffer pdu) = 0;
}; };
} // namespace srslte } // namespace srslte

View File

@ -56,8 +56,8 @@ public:
void get_metrics(rlc_metrics_t &m); void get_metrics(rlc_metrics_t &m);
// PDCP interface // PDCP interface
void write_sdu(uint32_t lcid, unique_pool_buffer sdu, bool blocking = true); void write_sdu(uint32_t lcid, unique_byte_buffer sdu, bool blocking = true);
void write_sdu_mch(uint32_t lcid, unique_pool_buffer sdu); void write_sdu_mch(uint32_t lcid, unique_byte_buffer sdu);
bool rb_is_um(uint32_t lcid); bool rb_is_um(uint32_t lcid);
// MAC interface // MAC interface

View File

@ -39,7 +39,7 @@ namespace srslte {
struct rlc_amd_rx_pdu_t{ struct rlc_amd_rx_pdu_t{
rlc_amd_pdu_header_t header; rlc_amd_pdu_header_t header;
byte_buffer_t *buf; unique_byte_buffer buf;
}; };
struct rlc_amd_rx_pdu_segments_t{ struct rlc_amd_rx_pdu_segments_t{
@ -48,7 +48,7 @@ struct rlc_amd_rx_pdu_segments_t{
struct rlc_amd_tx_pdu_t{ struct rlc_amd_tx_pdu_t{
rlc_amd_pdu_header_t header; rlc_amd_pdu_header_t header;
byte_buffer_t *buf; unique_byte_buffer buf;
uint32_t retx_count; uint32_t retx_count;
bool is_acked; bool is_acked;
}; };
@ -81,7 +81,7 @@ public:
uint32_t get_bearer(); uint32_t get_bearer();
// PDCP interface // PDCP interface
void write_sdu(unique_pool_buffer sdu, bool blocking = true); void write_sdu(unique_byte_buffer sdu, bool blocking = true);
// MAC interface // MAC interface
bool has_data(); bool has_data();
@ -109,7 +109,7 @@ private:
void reestablish(); void reestablish();
void stop(); void stop();
void write_sdu(unique_pool_buffer sdu, bool blocking); void write_sdu(unique_byte_buffer sdu, bool blocking);
int read_pdu(uint8_t *payload, uint32_t nof_bytes); int read_pdu(uint8_t *payload, uint32_t nof_bytes);
bool has_data(); bool has_data();
@ -156,7 +156,8 @@ private:
// TX SDU buffers // TX SDU buffers
rlc_tx_queue tx_sdu_queue; rlc_tx_queue tx_sdu_queue;
byte_buffer_t *tx_sdu;; unique_byte_buffer tx_sdu;
;
bool tx_enabled; bool tx_enabled;
@ -245,7 +246,7 @@ private:
srslte_rlc_am_config_t cfg; srslte_rlc_am_config_t cfg;
// RX SDU buffers // RX SDU buffers
byte_buffer_t *rx_sdu; unique_byte_buffer rx_sdu;
/**************************************************************************** /****************************************************************************
* State variables and counters * State variables and counters

View File

@ -161,7 +161,7 @@ public:
virtual void reset_metrics() = 0; virtual void reset_metrics() = 0;
// PDCP interface // PDCP interface
virtual void write_sdu(unique_pool_buffer sdu, bool blocking) = 0; virtual void write_sdu(unique_byte_buffer sdu, bool blocking) = 0;
// MAC interface // MAC interface
virtual bool has_data() = 0; virtual bool has_data() = 0;

View File

@ -54,7 +54,7 @@ public:
void reset_metrics(); void reset_metrics();
// PDCP interface // PDCP interface
void write_sdu(byte_buffer_t *sdu, bool blocking); void write_sdu(unique_byte_buffer sdu, bool blocking);
// MAC interface // MAC interface
bool has_data(); bool has_data();

View File

@ -36,7 +36,7 @@
namespace srslte { namespace srslte {
class rlc_tx_queue : public block_queue<unique_pool_buffer>::call_mutexed_itf class rlc_tx_queue : public block_queue<unique_byte_buffer>::call_mutexed_itf
{ {
public: public:
rlc_tx_queue(int capacity = 128) : queue(capacity) { rlc_tx_queue(int capacity = 128) : queue(capacity) {
@ -44,27 +44,22 @@ public:
queue.set_mutexed_itf(this); queue.set_mutexed_itf(this);
} }
// increase/decrease unread_bytes inside push/pop mutexed operations // increase/decrease unread_bytes inside push/pop mutexed operations
void pushing(byte_buffer_t *msg) { void pushing(const unique_byte_buffer& msg) final { unread_bytes += msg->N_bytes; }
unread_bytes += msg->N_bytes; void popping(const unique_byte_buffer& msg) final
} {
void popping(byte_buffer_t *msg) {
if (unread_bytes > msg->N_bytes) { if (unread_bytes > msg->N_bytes) {
unread_bytes -= msg->N_bytes; unread_bytes -= msg->N_bytes;
} else { } else {
unread_bytes = 0; unread_bytes = 0;
} }
} }
void write(unique_pool_buffer msg) { queue.push(std::move(msg)); } void write(unique_byte_buffer msg) { queue.push(std::move(msg)); }
bool try_write(unique_pool_buffer msg) { return queue.try_push(std::move(msg)); } bool try_write(unique_byte_buffer msg) { return queue.try_push(std::move(msg)); }
void read(unique_pool_buffer* msg) void read(unique_byte_buffer* msg) { *msg = std::move(queue.wait_pop()); }
{
unique_pool_buffer m = queue.wait_pop();
*msg = std::move(m);
}
bool try_read(unique_pool_buffer* msg) { return queue.try_pop(msg); } bool try_read(unique_byte_buffer* msg) { return queue.try_pop(msg); }
void resize(uint32_t capacity) void resize(uint32_t capacity)
{ {
@ -83,7 +78,7 @@ public:
uint32_t size_tail_bytes() uint32_t size_tail_bytes()
{ {
if (!queue.empty()) { if (!queue.empty()) {
unique_pool_buffer& m = queue.front(); unique_byte_buffer& m = queue.front();
if (m.get()) { if (m.get()) {
return m->N_bytes; return m->N_bytes;
} }
@ -101,7 +96,7 @@ public:
} }
private: private:
block_queue<unique_pool_buffer> queue; block_queue<unique_byte_buffer> queue;
uint32_t unread_bytes; uint32_t unread_bytes;
}; };

View File

@ -36,7 +36,7 @@ namespace srslte {
struct rlc_umd_pdu_t{ struct rlc_umd_pdu_t{
rlc_umd_pdu_header_t header; rlc_umd_pdu_header_t header;
byte_buffer_t *buf; unique_byte_buffer buf;
}; };
class rlc_um class rlc_um
@ -60,7 +60,7 @@ public:
uint32_t get_bearer(); uint32_t get_bearer();
// PDCP interface // PDCP interface
void write_sdu(byte_buffer_t *sdu, bool blocking = true); void write_sdu(unique_byte_buffer sdu, bool blocking = true);
// MAC interface // MAC interface
bool has_data(); bool has_data();
@ -87,8 +87,8 @@ private:
void stop(); void stop();
void reestablish(); void reestablish();
void empty_queue(); void empty_queue();
void write_sdu(byte_buffer_t *sdu); void write_sdu(unique_byte_buffer sdu);
void try_write_sdu(byte_buffer_t *sdu); void try_write_sdu(unique_byte_buffer sdu);
uint32_t get_num_tx_bytes(); uint32_t get_num_tx_bytes();
void reset_metrics(); void reset_metrics();
bool has_data(); bool has_data();
@ -107,7 +107,7 @@ private:
// TX SDU buffers // TX SDU buffers
rlc_tx_queue tx_sdu_queue; rlc_tx_queue tx_sdu_queue;
byte_buffer_t *tx_sdu; unique_byte_buffer tx_sdu;
/**************************************************************************** /****************************************************************************
* State variables and counters * State variables and counters
@ -168,7 +168,7 @@ private:
std::map<uint32_t, rlc_umd_pdu_t> rx_window; std::map<uint32_t, rlc_umd_pdu_t> rx_window;
// RX SDU buffers // RX SDU buffers
byte_buffer_t *rx_sdu; unique_byte_buffer rx_sdu;
uint32_t vr_ur_in_rx_sdu; uint32_t vr_ur_in_rx_sdu;
// Rx state variables and counter // Rx state variables and counter
@ -220,9 +220,9 @@ private:
* Header pack/unpack helper functions * Header pack/unpack helper functions
* Ref: 3GPP TS 36.322 v10.0.0 Section 6.2.1 * Ref: 3GPP TS 36.322 v10.0.0 Section 6.2.1
***************************************************************************/ ***************************************************************************/
void rlc_um_read_data_pdu_header(byte_buffer_t *pdu, rlc_umd_sn_size_t sn_size, rlc_umd_pdu_header_t *header); void rlc_um_read_data_pdu_header(byte_buffer_t* pdu, rlc_umd_sn_size_t sn_size, rlc_umd_pdu_header_t* header);
void rlc_um_read_data_pdu_header(uint8_t *payload, uint32_t nof_bytes, rlc_umd_sn_size_t sn_size, rlc_umd_pdu_header_t *header); void rlc_um_read_data_pdu_header(uint8_t *payload, uint32_t nof_bytes, rlc_umd_sn_size_t sn_size, rlc_umd_pdu_header_t *header);
void rlc_um_write_data_pdu_header(rlc_umd_pdu_header_t *header, byte_buffer_t *pdu); void rlc_um_write_data_pdu_header(rlc_umd_pdu_header_t* header, byte_buffer_t* pdu);
uint32_t rlc_um_packed_length(rlc_umd_pdu_header_t *header); uint32_t rlc_um_packed_length(rlc_umd_pdu_header_t *header);
bool rlc_um_start_aligned(uint8_t fi); bool rlc_um_start_aligned(uint8_t fi);

View File

@ -117,7 +117,7 @@ bool pdcp::is_lcid_enabled(uint32_t lcid)
return ret; return ret;
} }
void pdcp::write_sdu(uint32_t lcid, unique_pool_buffer sdu, bool blocking) void pdcp::write_sdu(uint32_t lcid, unique_byte_buffer sdu, bool blocking)
{ {
pthread_rwlock_rdlock(&rwlock); pthread_rwlock_rdlock(&rwlock);
if (valid_lcid(lcid)) { if (valid_lcid(lcid)) {
@ -128,7 +128,7 @@ void pdcp::write_sdu(uint32_t lcid, unique_pool_buffer sdu, bool blocking)
pthread_rwlock_unlock(&rwlock); pthread_rwlock_unlock(&rwlock);
} }
void pdcp::write_sdu_mch(uint32_t lcid, unique_pool_buffer sdu) void pdcp::write_sdu_mch(uint32_t lcid, unique_byte_buffer sdu)
{ {
pthread_rwlock_rdlock(&rwlock); pthread_rwlock_rdlock(&rwlock);
if (valid_mch_lcid(lcid)){ if (valid_mch_lcid(lcid)){
@ -276,7 +276,7 @@ uint32_t pdcp::get_ul_count(uint32_t lcid)
/******************************************************************************* /*******************************************************************************
RLC interface RLC interface
*******************************************************************************/ *******************************************************************************/
void pdcp::write_pdu(uint32_t lcid, unique_pool_buffer pdu) void pdcp::write_pdu(uint32_t lcid, unique_byte_buffer pdu)
{ {
pthread_rwlock_rdlock(&rwlock); pthread_rwlock_rdlock(&rwlock);
if (valid_lcid(lcid)) { if (valid_lcid(lcid)) {
@ -287,22 +287,22 @@ void pdcp::write_pdu(uint32_t lcid, unique_pool_buffer pdu)
pthread_rwlock_unlock(&rwlock); pthread_rwlock_unlock(&rwlock);
} }
void pdcp::write_pdu_bcch_bch(unique_pool_buffer sdu) void pdcp::write_pdu_bcch_bch(unique_byte_buffer sdu)
{ {
rrc->write_pdu_bcch_bch(std::move(sdu)); rrc->write_pdu_bcch_bch(std::move(sdu));
} }
void pdcp::write_pdu_bcch_dlsch(unique_pool_buffer sdu) void pdcp::write_pdu_bcch_dlsch(unique_byte_buffer sdu)
{ {
rrc->write_pdu_bcch_dlsch(std::move(sdu)); rrc->write_pdu_bcch_dlsch(std::move(sdu));
} }
void pdcp::write_pdu_pcch(unique_pool_buffer sdu) void pdcp::write_pdu_pcch(unique_byte_buffer sdu)
{ {
rrc->write_pdu_pcch(std::move(sdu)); rrc->write_pdu_pcch(std::move(sdu));
} }
void pdcp::write_pdu_mch(uint32_t lcid, unique_pool_buffer sdu) void pdcp::write_pdu_mch(uint32_t lcid, unique_byte_buffer sdu)
{ {
if (0 == lcid) { if (0 == lcid) {
rrc->write_pdu_mch(lcid, std::move(sdu)); rrc->write_pdu_mch(lcid, std::move(sdu));

View File

@ -112,7 +112,7 @@ bool pdcp_entity::is_active()
} }
// GW/RRC interface // GW/RRC interface
void pdcp_entity::write_sdu(unique_pool_buffer sdu, bool blocking) void pdcp_entity::write_sdu(unique_byte_buffer sdu, bool blocking)
{ {
log->info_hex(sdu->msg, sdu->N_bytes, log->info_hex(sdu->msg, sdu->N_bytes,
"TX %s SDU, SN: %d, do_integrity = %s, do_encryption = %s", "TX %s SDU, SN: %d, do_integrity = %s, do_encryption = %s",
@ -178,7 +178,7 @@ void pdcp_entity::enable_encryption()
} }
// RLC interface // RLC interface
void pdcp_entity::write_pdu(unique_pool_buffer pdu) void pdcp_entity::write_pdu(unique_byte_buffer pdu)
{ {
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU, do_integrity = %s, do_encryption = %s", log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU, do_integrity = %s, do_encryption = %s",
rrc->get_rb_name(lcid).c_str(), (do_integrity) ? "true" : "false", (do_encryption) ? "true" : "false"); rrc->get_rb_name(lcid).c_str(), (do_integrity) ? "true" : "false", (do_encryption) ? "true" : "false");

View File

@ -199,7 +199,7 @@ void rlc::empty_queue()
PDCP interface PDCP interface
*******************************************************************************/ *******************************************************************************/
void rlc::write_sdu(uint32_t lcid, unique_pool_buffer sdu, bool blocking) void rlc::write_sdu(uint32_t lcid, unique_byte_buffer sdu, bool blocking)
{ {
// FIXME: rework build PDU logic to allow large SDUs (without concatenation) // FIXME: rework build PDU logic to allow large SDUs (without concatenation)
if (sdu->N_bytes > RLC_MAX_SDU_SIZE) { if (sdu->N_bytes > RLC_MAX_SDU_SIZE) {
@ -209,18 +209,18 @@ void rlc::write_sdu(uint32_t lcid, unique_pool_buffer sdu, bool blocking)
pthread_rwlock_rdlock(&rwlock); pthread_rwlock_rdlock(&rwlock);
if (valid_lcid(lcid)) { if (valid_lcid(lcid)) {
rlc_array.at(lcid)->write_sdu(sdu, blocking); rlc_array.at(lcid)->write_sdu(std::move(sdu), blocking);
} else { } else {
rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid); rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid);
} }
pthread_rwlock_unlock(&rwlock); pthread_rwlock_unlock(&rwlock);
} }
void rlc::write_sdu_mch(uint32_t lcid, unique_pool_buffer sdu) void rlc::write_sdu_mch(uint32_t lcid, unique_byte_buffer sdu)
{ {
pthread_rwlock_rdlock(&rwlock); pthread_rwlock_rdlock(&rwlock);
if (valid_lcid_mrb(lcid)) { if (valid_lcid_mrb(lcid)) {
rlc_array_mrb.at(lcid)->write_sdu(sdu, false); // write in non-blocking mode by default rlc_array_mrb.at(lcid)->write_sdu(std::move(sdu), false); // write in non-blocking mode by default
} else { } else {
rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid); rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid);
} }
@ -331,12 +331,12 @@ void rlc::write_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes)
void rlc::write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes) void rlc::write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes)
{ {
rlc_log->info_hex(payload, nof_bytes, "BCCH BCH message received."); rlc_log->info_hex(payload, nof_bytes, "BCCH BCH message received.");
byte_buffer_t *buf = pool_allocate; unique_byte_buffer buf = allocate_unique_buffer(*pool);
if (buf != NULL) { if (buf != NULL) {
memcpy(buf->msg, payload, nof_bytes); memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes; buf->N_bytes = nof_bytes;
buf->set_timestamp(); buf->set_timestamp();
pdcp->write_pdu_bcch_bch(buf); pdcp->write_pdu_bcch_bch(std::move(buf));
} else { } else {
rlc_log->error("Fatal error: Out of buffers from the pool in write_pdu_bcch_bch()\n"); rlc_log->error("Fatal error: Out of buffers from the pool in write_pdu_bcch_bch()\n");
} }
@ -346,12 +346,12 @@ void rlc::write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes)
void rlc::write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes) void rlc::write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes)
{ {
rlc_log->info_hex(payload, nof_bytes, "BCCH TXSCH message received."); rlc_log->info_hex(payload, nof_bytes, "BCCH TXSCH message received.");
byte_buffer_t *buf = pool_allocate; unique_byte_buffer buf = allocate_unique_buffer(*pool);
if (buf != NULL) { if (buf != NULL) {
memcpy(buf->msg, payload, nof_bytes); memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes; buf->N_bytes = nof_bytes;
buf->set_timestamp(); buf->set_timestamp();
pdcp->write_pdu_bcch_dlsch(buf); pdcp->write_pdu_bcch_dlsch(std::move(buf));
} else { } else {
rlc_log->error("Fatal error: Out of buffers from the pool in write_pdu_bcch_dlsch()\n"); rlc_log->error("Fatal error: Out of buffers from the pool in write_pdu_bcch_dlsch()\n");
} }
@ -361,12 +361,12 @@ void rlc::write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes)
void rlc::write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) void rlc::write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes)
{ {
rlc_log->info_hex(payload, nof_bytes, "PCCH message received."); rlc_log->info_hex(payload, nof_bytes, "PCCH message received.");
byte_buffer_t *buf = pool_allocate; unique_byte_buffer buf = allocate_unique_buffer(*pool);
if (buf != NULL) { if (buf != NULL) {
memcpy(buf->msg, payload, nof_bytes); memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes; buf->N_bytes = nof_bytes;
buf->set_timestamp(); buf->set_timestamp();
pdcp->write_pdu_pcch(buf); pdcp->write_pdu_pcch(std::move(buf));
} else { } else {
rlc_log->error("Fatal error: Out of buffers from the pool in write_pdu_pcch()\n"); rlc_log->error("Fatal error: Out of buffers from the pool in write_pdu_pcch()\n");
} }

View File

@ -128,9 +128,9 @@ void rlc_am::reset_metrics()
* PDCP interface * PDCP interface
***************************************************************************/ ***************************************************************************/
void rlc_am::write_sdu(unique_pool_buffer sdu, bool blocking) void rlc_am::write_sdu(unique_byte_buffer sdu, bool blocking)
{ {
tx.write_sdu(sdu, blocking); tx.write_sdu(std::move(sdu), blocking);
} }
/**************************************************************************** /****************************************************************************
@ -175,7 +175,6 @@ rlc_am::rlc_am_tx::rlc_am_tx(rlc_am* parent_) :
num_tx_bytes(0), num_tx_bytes(0),
pdu_without_poll(0), pdu_without_poll(0),
byte_without_poll(0), byte_without_poll(0),
tx_sdu(NULL),
log(NULL), log(NULL),
cfg(), cfg(),
tx_status(), tx_status(),
@ -258,10 +257,6 @@ void rlc_am::rlc_am_tx::stop()
byte_without_poll = 0; byte_without_poll = 0;
// Drop all messages in TX window // Drop all messages in TX window
std::map<uint32_t, rlc_amd_tx_pdu_t>::iterator txit;
for(txit = tx_window.begin(); txit != tx_window.end(); txit++) {
pool->deallocate(txit->second.buf);
}
tx_window.clear(); tx_window.clear();
// Drop all messages in RETX queue // Drop all messages in RETX queue
@ -275,16 +270,12 @@ void rlc_am::rlc_am_tx::empty_queue()
// deallocate all SDUs in transmit queue // deallocate all SDUs in transmit queue
while(tx_sdu_queue.size() > 0) { while(tx_sdu_queue.size() > 0) {
byte_buffer_t *buf; unique_byte_buffer buf;
tx_sdu_queue.read(&buf); tx_sdu_queue.read(&buf);
pool->deallocate(buf);
} }
// deallocate SDU that is currently processed // deallocate SDU that is currently processed
if (tx_sdu != NULL) { tx_sdu.reset();
pool->deallocate(tx_sdu);
tx_sdu = NULL;
}
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
} }
@ -362,7 +353,7 @@ uint32_t rlc_am::rlc_am_tx::get_buffer_state()
return n_bytes; return n_bytes;
} }
void rlc_am::rlc_am_tx::write_sdu(unique_pool_buffer sdu, bool blocking) void rlc_am::rlc_am_tx::write_sdu(unique_byte_buffer sdu, bool blocking)
{ {
if (!tx_enabled) { if (!tx_enabled) {
return; return;
@ -371,15 +362,20 @@ void rlc_am::rlc_am_tx::write_sdu(unique_pool_buffer sdu, bool blocking)
if (sdu.get() != NULL) { if (sdu.get() != NULL) {
if (blocking) { if (blocking) {
// block on write to queue // block on write to queue
tx_sdu_queue.write(std::move(sdu));
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", RB_NAME, sdu->N_bytes, tx_sdu_queue.size()); log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", RB_NAME, sdu->N_bytes, tx_sdu_queue.size());
tx_sdu_queue.write(std::move(sdu));
} else { } else {
// non-blocking write // non-blocking write
uint8_t* msg_ptr = sdu->msg;
uint32_t nof_bytes = sdu->N_bytes;
if (tx_sdu_queue.try_write(std::move(sdu))) { if (tx_sdu_queue.try_write(std::move(sdu))) {
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", RB_NAME, sdu->N_bytes, tx_sdu_queue.size()); log->info_hex(
msg_ptr, nof_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", RB_NAME, nof_bytes, tx_sdu_queue.size());
} else { } else {
log->info_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", RB_NAME, #warning Find a more elegant solution - the msg was already deallocated at this point
sdu->N_bytes, tx_sdu_queue.size()); log->info("[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", RB_NAME, nof_bytes, tx_sdu_queue.size());
// log->info_hex(msg_ptr, nof_bytes, "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", RB_NAME,
// nof_bytes, tx_sdu_queue.size());
} }
} }
} else { } else {
@ -783,7 +779,7 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
return 0; return 0;
} }
byte_buffer_t *pdu = pool_allocate_blocking; unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (pdu == NULL) { if (pdu == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG #ifdef RLC_AM_BUFFER_DEBUG
log->console("Fatal Error: Could not allocate PDU in build_data_pdu()\n"); log->console("Fatal Error: Could not allocate PDU in build_data_pdu()\n");
@ -823,7 +819,6 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
{ {
log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n", log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n",
RB_NAME, nof_bytes, head_len); RB_NAME, nof_bytes, head_len);
pool->deallocate(pdu);
return 0; return 0;
} }
@ -843,8 +838,7 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
{ {
log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
RB_NAME, tx_sdu->get_latency_us()); RB_NAME, tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); tx_sdu.reset();
tx_sdu = NULL;
} }
if (pdu_space > to_move) { if (pdu_space > to_move) {
pdu_space -= SRSLTE_MIN(to_move, pdu->get_tailroom()); pdu_space -= SRSLTE_MIN(to_move, pdu->get_tailroom());
@ -879,8 +873,7 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
if (tx_sdu->N_bytes == 0) { if (tx_sdu->N_bytes == 0) {
log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
RB_NAME, tx_sdu->get_latency_us()); RB_NAME, tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); tx_sdu.reset();
tx_sdu = NULL;
} }
if(pdu_space > to_move) { if(pdu_space > to_move) {
pdu_space -= to_move; pdu_space -= to_move;
@ -925,15 +918,16 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
vt_s = (vt_s + 1)%MOD; vt_s = (vt_s + 1)%MOD;
// Place PDU in tx_window, write header and TX // Place PDU in tx_window, write header and TX
tx_window[header.sn].buf = pdu; tx_window[header.sn].buf = std::move(pdu);
tx_window[header.sn].header = header; tx_window[header.sn].header = header;
tx_window[header.sn].is_acked = false; tx_window[header.sn].is_acked = false;
tx_window[header.sn].retx_count = 0; tx_window[header.sn].retx_count = 0;
const byte_buffer_t* buffer_ptr = tx_window[header.sn].buf.get();
uint8_t *ptr = payload; uint8_t *ptr = payload;
rlc_am_write_data_pdu_header(&header, &ptr); rlc_am_write_data_pdu_header(&header, &ptr);
memcpy(ptr, pdu->msg, pdu->N_bytes); memcpy(ptr, buffer_ptr->msg, buffer_ptr->N_bytes);
int total_len = (ptr-payload) + pdu->N_bytes; int total_len = (ptr - payload) + buffer_ptr->N_bytes;
log->info_hex(payload, total_len, "%s Tx PDU SN=%d (%d B)\n", RB_NAME, header.sn, total_len); log->info_hex(payload, total_len, "%s Tx PDU SN=%d (%d B)\n", RB_NAME, header.sn, total_len);
log->debug("%s\n", rlc_amd_pdu_header_to_string(header).c_str()); log->debug("%s\n", rlc_amd_pdu_header_to_string(header).c_str());
debug_state(); debug_state();
@ -1021,10 +1015,6 @@ void rlc_am::rlc_am_tx::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes)
it = tx_window.find(i); it = tx_window.find(i);
if (it != tx_window.end()) { if (it != tx_window.end()) {
if(update_vt_a) { if(update_vt_a) {
if (it->second.buf != NULL) {
pool->deallocate(it->second.buf);
it->second.buf = 0;
}
tx_window.erase(it); tx_window.erase(it);
vt_a = (vt_a + 1)%MOD; vt_a = (vt_a + 1)%MOD;
vt_ms = (vt_ms + 1)%MOD; vt_ms = (vt_ms + 1)%MOD;
@ -1153,7 +1143,6 @@ rlc_am::rlc_am_rx::rlc_am_rx(rlc_am* parent_)
,num_rx_bytes(0) ,num_rx_bytes(0)
,poll_received(false) ,poll_received(false)
,do_status(false) ,do_status(false)
,rx_sdu(NULL)
{ {
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
} }
@ -1205,10 +1194,7 @@ void rlc_am::rlc_am_rx::stop()
reordering_timer = NULL; reordering_timer = NULL;
} }
if (rx_sdu != NULL) { rx_sdu.reset();
pool->deallocate(rx_sdu);
rx_sdu = NULL;
}
vr_r = 0; vr_r = 0;
vr_mr = RLC_AM_WINDOW_SIZE; vr_mr = RLC_AM_WINDOW_SIZE;
@ -1220,22 +1206,9 @@ void rlc_am::rlc_am_rx::stop()
do_status = false; do_status = false;
// Drop all messages in RX segments // Drop all messages in RX segments
std::map<uint32_t, rlc_amd_rx_pdu_segments_t>::iterator rxsegsit;
std::list<rlc_amd_rx_pdu_t>::iterator segit;
for(rxsegsit = rx_segments.begin(); rxsegsit != rx_segments.end(); rxsegsit++) {
std::list<rlc_amd_rx_pdu_t> l = rxsegsit->second.segments;
for(segit = l.begin(); segit != l.end(); segit++) {
pool->deallocate(segit->buf);
}
l.clear();
}
rx_segments.clear(); rx_segments.clear();
// Drop all messages in RX window // Drop all messages in RX window
std::map<uint32_t, rlc_amd_rx_pdu_t>::iterator rxit;
for(rxit = rx_window.begin(); rxit != rx_window.end(); rxit++) {
pool->deallocate(rxit->second.buf);
}
rx_window.clear(); rx_window.clear();
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
@ -1275,7 +1248,7 @@ void rlc_am::rlc_am_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rl
// Write to rx window // Write to rx window
rlc_amd_rx_pdu_t pdu; rlc_amd_rx_pdu_t pdu;
pdu.buf = pool_allocate_blocking; pdu.buf = srslte::allocate_unique_buffer(*pool, true);
if (pdu.buf == NULL) { if (pdu.buf == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG #ifdef RLC_AM_BUFFER_DEBUG
log->console("Fatal Error: Couldn't allocate PDU in handle_data_pdu().\n"); log->console("Fatal Error: Couldn't allocate PDU in handle_data_pdu().\n");
@ -1290,14 +1263,13 @@ void rlc_am::rlc_am_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes, rl
if (nof_bytes > pdu.buf->get_tailroom()) { if (nof_bytes > pdu.buf->get_tailroom()) {
log->error("%s Discarding SN: %d of size %d B (available space %d B)\n", log->error("%s Discarding SN: %d of size %d B (available space %d B)\n",
RB_NAME, header.sn, nof_bytes, pdu.buf->get_tailroom()); RB_NAME, header.sn, nof_bytes, pdu.buf->get_tailroom());
pool->deallocate(pdu.buf);
return; return;
} }
memcpy(pdu.buf->msg, payload, nof_bytes); memcpy(pdu.buf->msg, payload, nof_bytes);
pdu.buf->N_bytes = nof_bytes; pdu.buf->N_bytes = nof_bytes;
pdu.header = header; pdu.header = header;
rx_window[header.sn] = pdu; rx_window[header.sn] = std::move(pdu);
// Update vr_h // Update vr_h
if(RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_h)) { if(RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_h)) {
@ -1367,7 +1339,7 @@ void rlc_am::rlc_am_rx::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_b
} }
rlc_amd_rx_pdu_t segment; rlc_amd_rx_pdu_t segment;
segment.buf = pool_allocate_blocking; segment.buf = srslte::allocate_unique_buffer(*pool, true);
if (segment.buf == NULL) { if (segment.buf == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG #ifdef RLC_AM_BUFFER_DEBUG
log->console("Fatal Error: Couldn't allocate PDU in handle_data_pdu_segment().\n"); log->console("Fatal Error: Couldn't allocate PDU in handle_data_pdu_segment().\n");
@ -1392,13 +1364,8 @@ void rlc_am::rlc_am_rx::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_b
} }
// Add segment to PDU list and check for complete // Add segment to PDU list and check for complete
// NOTE: MAY MOVE. Preference would be to capture by value, and then move; but header is stack allocated
if(add_segment_and_check(&it->second, &segment)) { if(add_segment_and_check(&it->second, &segment)) {
std::list<rlc_amd_rx_pdu_t>::iterator segit;
std::list<rlc_amd_rx_pdu_t> seglist = it->second.segments;
for(segit = seglist.begin(); segit != seglist.end(); segit++) {
pool->deallocate(segit->buf);
}
seglist.clear();
rx_segments.erase(it); rx_segments.erase(it);
} }
@ -1406,8 +1373,8 @@ void rlc_am::rlc_am_rx::handle_data_pdu_segment(uint8_t *payload, uint32_t nof_b
// Create new PDU segment list and write to rx_segments // Create new PDU segment list and write to rx_segments
rlc_amd_rx_pdu_segments_t pdu; rlc_amd_rx_pdu_segments_t pdu;
pdu.segments.push_back(segment); pdu.segments.push_back(std::move(segment));
rx_segments[header.sn] = pdu; rx_segments[header.sn] = std::move(pdu);
// Update vr_h // Update vr_h
if (RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_h)) { if (RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_h)) {
@ -1439,7 +1406,7 @@ void rlc_am::rlc_am_rx::reassemble_rx_sdus()
{ {
uint32_t len = 0; uint32_t len = 0;
if (rx_sdu == NULL) { if (rx_sdu == NULL) {
rx_sdu = pool_allocate_blocking; rx_sdu = allocate_unique_buffer(*pool, true);
if (rx_sdu == NULL) { if (rx_sdu == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG #ifdef RLC_AM_BUFFER_DEBUG
log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (1)\n"); log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (1)\n");
@ -1474,9 +1441,9 @@ void rlc_am::rlc_am_rx::reassemble_rx_sdus()
rx_window[vr_r].buf->N_bytes -= len; rx_window[vr_r].buf->N_bytes -= len;
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes);
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
parent->pdcp->write_pdu(parent->lcid, rx_sdu); parent->pdcp->write_pdu(parent->lcid, std::move(rx_sdu));
rx_sdu = pool_allocate_blocking; rx_sdu = allocate_unique_buffer(*pool, true);
if (rx_sdu == NULL) { if (rx_sdu == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG #ifdef RLC_AM_BUFFER_DEBUG
log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)\n"); log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)\n");
@ -1488,12 +1455,12 @@ void rlc_am::rlc_am_rx::reassemble_rx_sdus()
} }
} else { } else {
log->error("Cannot read %d bytes from rx_window. vr_r=%d, msg-buffer=%ld bytes\n", len, vr_r, (rx_window[vr_r].buf->msg - rx_window[vr_r].buf->buffer)); log->error("Cannot read %d bytes from rx_window. vr_r=%d, msg-buffer=%ld bytes\n", len, vr_r, (rx_window[vr_r].buf->msg - rx_window[vr_r].buf->buffer));
pool->deallocate(rx_sdu); rx_sdu.reset();
goto exit; goto exit;
} }
} else { } else {
log->error("Cannot fit RLC PDU in SDU buffer, dropping both.\n"); log->error("Cannot fit RLC PDU in SDU buffer, dropping both.\n");
pool->deallocate(rx_sdu); rx_sdu.reset();
goto exit; goto exit;
} }
} }
@ -1506,16 +1473,15 @@ void rlc_am::rlc_am_rx::reassemble_rx_sdus()
rx_sdu->N_bytes += rx_window[vr_r].buf->N_bytes; rx_sdu->N_bytes += rx_window[vr_r].buf->N_bytes;
} else { } else {
log->error("Cannot fit RLC PDU in SDU buffer, dropping both. Erasing SN=%d.\n", vr_r); log->error("Cannot fit RLC PDU in SDU buffer, dropping both. Erasing SN=%d.\n", vr_r);
pool->deallocate(rx_sdu); rx_sdu.reset();
pool->deallocate(rx_window[vr_r].buf);
rx_window.erase(vr_r); rx_window.erase(vr_r);
} }
if (rlc_am_end_aligned(rx_window[vr_r].header.fi)) { if (rlc_am_end_aligned(rx_window[vr_r].header.fi)) {
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes);
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
parent->pdcp->write_pdu(parent->lcid, rx_sdu); parent->pdcp->write_pdu(parent->lcid, std::move(rx_sdu));
rx_sdu = pool_allocate_blocking; rx_sdu = allocate_unique_buffer(*pool, true);
if (rx_sdu == NULL) { if (rx_sdu == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG #ifdef RLC_AM_BUFFER_DEBUG
log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (3)\n"); log->console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (3)\n");
@ -1538,11 +1504,9 @@ exit:
std::list<rlc_amd_rx_pdu_t>::iterator segit; std::list<rlc_amd_rx_pdu_t>::iterator segit;
for(segit = it->second.segments.begin(); segit != it->second.segments.end(); ++segit) { for(segit = it->second.segments.begin(); segit != it->second.segments.end(); ++segit) {
log->debug(" Erasing segment of SN=%d SO=%d Len=%d N_li=%d\n", segit->header.sn, segit->header.so, segit->buf->N_bytes, segit->header.N_li); log->debug(" Erasing segment of SN=%d SO=%d Len=%d N_li=%d\n", segit->header.sn, segit->header.so, segit->buf->N_bytes, segit->header.N_li);
pool->deallocate(segit->buf);
} }
it->second.segments.clear(); it->second.segments.clear();
} }
pool->deallocate(rx_window[vr_r].buf);
rx_window.erase(vr_r); rx_window.erase(vr_r);
vr_r = (vr_r + 1)%MOD; vr_r = (vr_r + 1)%MOD;
vr_mr = (vr_mr + 1)%MOD; vr_mr = (vr_mr + 1)%MOD;
@ -1678,16 +1642,13 @@ void rlc_am::rlc_am_rx::print_rx_segments()
log->debug("%s\n", ss.str().c_str()); log->debug("%s\n", ss.str().c_str());
} }
// NOTE: Preference would be to capture by value, and then move; but header is stack allocated
bool rlc_am::rlc_am_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pdu_t *segment) bool rlc_am::rlc_am_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pdu_t *segment)
{ {
// Check for first segment // Check for first segment
if(0 == segment->header.so) { if(0 == segment->header.so) {
std::list<rlc_amd_rx_pdu_t>::iterator it;
for(it = pdu->segments.begin(); it != pdu->segments.end(); it++) {
pool->deallocate(it->buf);
}
pdu->segments.clear(); pdu->segments.clear();
pdu->segments.push_back(*segment); pdu->segments.push_back(std::move(*segment));
return false; return false;
} }
@ -1700,10 +1661,9 @@ bool rlc_am::rlc_am_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rl
if(segment->header.so != n) { if(segment->header.so != n) {
log->warning("Received PDU with SO=%d, expected %d. Discarding PDU.\n", segment->header.so, n); log->warning("Received PDU with SO=%d, expected %d. Discarding PDU.\n", segment->header.so, n);
pool->deallocate(segment->buf);
return false; return false;
} else { } else {
pdu->segments.push_back(*segment); pdu->segments.push_back(std::move(*segment));
} }
// Check for complete // Check for complete
@ -1775,7 +1735,7 @@ bool rlc_am::rlc_am_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rl
log->debug("Finished header reconstruction of %zd segments\n", pdu->segments.size()); log->debug("Finished header reconstruction of %zd segments\n", pdu->segments.size());
// Copy data // Copy data
byte_buffer_t *full_pdu = pool_allocate_blocking; unique_byte_buffer full_pdu = srslte::allocate_unique_buffer(*pool, true);
if (full_pdu == NULL) { if (full_pdu == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG #ifdef RLC_AM_BUFFER_DEBUG
log->console("Fatal Error: Could not allocate PDU in add_segment_and_check()\n"); log->console("Fatal Error: Could not allocate PDU in add_segment_and_check()\n");
@ -1791,7 +1751,6 @@ bool rlc_am::rlc_am_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rl
} }
handle_data_pdu(full_pdu->msg, full_pdu->N_bytes, header); handle_data_pdu(full_pdu->msg, full_pdu->N_bytes, header);
pool->deallocate(full_pdu);
return true; return true;
} }

View File

@ -63,9 +63,8 @@ bool rlc_tm::configure(srslte_rlc_config_t cnfg)
void rlc_tm::empty_queue() void rlc_tm::empty_queue()
{ {
// Drop all messages in TX queue // Drop all messages in TX queue
byte_buffer_t *buf; unique_byte_buffer buf;
while (ul_queue.try_read(&buf)) { while (ul_queue.try_read(&buf)) {
pool->deallocate(buf);
} }
ul_queue.reset(); ul_queue.reset();
} }
@ -92,25 +91,34 @@ uint32_t rlc_tm::get_bearer()
} }
// PDCP interface // PDCP interface
void rlc_tm::write_sdu(byte_buffer_t *sdu, bool blocking) void rlc_tm::write_sdu(unique_byte_buffer sdu, bool blocking)
{ {
if (!tx_enabled) { if (!tx_enabled) {
byte_buffer_pool::get_instance()->deallocate(sdu);
return; return;
} }
if (sdu) { if (sdu) {
if (blocking) { if (blocking) {
ul_queue.write(sdu);
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, queue size=%d, bytes=%d", log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, queue size=%d, bytes=%d",
rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes()); rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes());
ul_queue.write(std::move(sdu));
} else { } else {
if (ul_queue.try_write(sdu)) { uint8_t* msg_ptr = sdu->msg;
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, queue size=%d, bytes=%d", uint32_t nof_bytes = sdu->N_bytes;
rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes()); if (ul_queue.try_write(std::move(sdu))) {
log->info_hex(msg_ptr,
nof_bytes,
"%s Tx SDU, queue size=%d, bytes=%d",
rrc->get_rb_name(lcid).c_str(),
ul_queue.size(),
ul_queue.size_bytes());
} else { } else {
log->info_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU, queue size=%d, bytes=%d", #warning Find a more elegant solution - the msg was already deallocated at this point
rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes()); log->info("[Dropped SDU] %s Tx SDU, queue size=%d, bytes=%d",
pool->deallocate(sdu); rrc->get_rb_name(lcid).c_str(),
ul_queue.size(),
ul_queue.size());
// log->info_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU, queue size=%d, bytes=%d",
// rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes());
} }
} }
} else { } else {
@ -152,13 +160,12 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes)
log->error("TX %s PDU size larger than MAC opportunity (%d > %d)\n", rrc->get_rb_name(lcid).c_str(), pdu_size, nof_bytes); log->error("TX %s PDU size larger than MAC opportunity (%d > %d)\n", rrc->get_rb_name(lcid).c_str(), pdu_size, nof_bytes);
return -1; return -1;
} }
byte_buffer_t *buf; unique_byte_buffer buf;
if (ul_queue.try_read(&buf)) { if (ul_queue.try_read(&buf)) {
pdu_size = buf->N_bytes; pdu_size = buf->N_bytes;
memcpy(payload, buf->msg, buf->N_bytes); memcpy(payload, buf->msg, buf->N_bytes);
log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
rrc->get_rb_name(lcid).c_str(), buf->get_latency_us()); rrc->get_rb_name(lcid).c_str(), buf->get_latency_us());
pool->deallocate(buf);
log->info_hex(payload, pdu_size, "TX %s, %s PDU, queue size=%d, bytes=%d", log->info_hex(payload, pdu_size, "TX %s, %s PDU, queue size=%d, bytes=%d",
rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM], ul_queue.size(), ul_queue.size_bytes()); rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM], ul_queue.size(), ul_queue.size_bytes());
@ -176,13 +183,13 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes)
void rlc_tm::write_pdu(uint8_t *payload, uint32_t nof_bytes) void rlc_tm::write_pdu(uint8_t *payload, uint32_t nof_bytes)
{ {
byte_buffer_t *buf = pool_allocate; unique_byte_buffer buf = allocate_unique_buffer(*pool);
if (buf) { if (buf) {
memcpy(buf->msg, payload, nof_bytes); memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes; buf->N_bytes = nof_bytes;
buf->set_timestamp(); buf->set_timestamp();
num_rx_bytes += nof_bytes; num_rx_bytes += nof_bytes;
pdcp->write_pdu(lcid, buf); pdcp->write_pdu(lcid, std::move(buf));
} else { } else {
log->error("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu().\n"); log->error("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu().\n");
} }

View File

@ -140,12 +140,12 @@ uint32_t rlc_um::get_bearer()
/**************************************************************************** /****************************************************************************
* PDCP interface * PDCP interface
***************************************************************************/ ***************************************************************************/
void rlc_um::write_sdu(byte_buffer_t *sdu, bool blocking) void rlc_um::write_sdu(unique_byte_buffer sdu, bool blocking)
{ {
if (blocking) { if (blocking) {
tx.write_sdu(sdu); tx.write_sdu(std::move(sdu));
} else { } else {
tx.try_write_sdu(sdu); tx.try_write_sdu(std::move(sdu));
} }
} }
@ -213,7 +213,6 @@ std::string rlc_um::get_rb_name(srsue::rrc_interface_rlc *rrc, uint32_t lcid, bo
rlc_um::rlc_um_tx::rlc_um_tx() : rlc_um::rlc_um_tx::rlc_um_tx() :
pool(byte_buffer_pool::get_instance()), pool(byte_buffer_pool::get_instance()),
log(NULL), log(NULL),
tx_sdu(NULL),
vt_us(0), vt_us(0),
tx_enabled(false), tx_enabled(false),
num_tx_bytes(0) num_tx_bytes(0)
@ -272,16 +271,12 @@ void rlc_um::rlc_um_tx::empty_queue()
// deallocate all SDUs in transmit queue // deallocate all SDUs in transmit queue
while(tx_sdu_queue.size() > 0) { while(tx_sdu_queue.size() > 0) {
byte_buffer_t *buf; unique_byte_buffer buf;
tx_sdu_queue.read(&buf); tx_sdu_queue.read(&buf);
pool->deallocate(buf);
} }
// deallocate SDU that is currently processed // deallocate SDU that is currently processed
if(tx_sdu) { tx_sdu.reset();
pool->deallocate(tx_sdu);
tx_sdu = NULL;
}
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
} }
@ -329,36 +324,38 @@ uint32_t rlc_um::rlc_um_tx::get_buffer_state()
return n_bytes; return n_bytes;
} }
void rlc_um::rlc_um_tx::write_sdu(unique_byte_buffer sdu)
void rlc_um::rlc_um_tx::write_sdu(byte_buffer_t *sdu)
{ {
if (!tx_enabled) { if (!tx_enabled) {
byte_buffer_pool::get_instance()->deallocate(sdu);
return; return;
} }
if (sdu) { if (sdu) {
tx_sdu_queue.write(sdu);
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size());
tx_sdu_queue.write(std::move(sdu));
} else { } else {
log->warning("NULL SDU pointer in write_sdu()\n"); log->warning("NULL SDU pointer in write_sdu()\n");
} }
} }
void rlc_um::rlc_um_tx::try_write_sdu(unique_byte_buffer sdu)
void rlc_um::rlc_um_tx::try_write_sdu(byte_buffer_t *sdu)
{ {
if (!tx_enabled) { if (!tx_enabled) {
byte_buffer_pool::get_instance()->deallocate(sdu); sdu.reset();
return; return;
} }
if (sdu) { if (sdu) {
if (tx_sdu_queue.try_write(sdu)) { uint8_t* msg_ptr = sdu->msg;
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); uint32_t nof_bytes = sdu->N_bytes;
if (tx_sdu_queue.try_write(std::move(sdu))) {
log->info_hex(
msg_ptr, nof_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", get_rb_name(), nof_bytes, tx_sdu_queue.size());
} else { } else {
log->info_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", get_rb_name(), sdu->N_bytes, tx_sdu_queue.size()); #warning Find a more elegant solution - the msg was already deallocated at this point
pool->deallocate(sdu); log->info("[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", get_rb_name(), nof_bytes, tx_sdu_queue.size());
// log->info_hex(msg_ptr, nof_bytes, "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", get_rb_name(),
// nof_bytes, tx_sdu_queue.size());
} }
} else { } else {
log->warning("NULL SDU pointer in write_sdu()\n"); log->warning("NULL SDU pointer in write_sdu()\n");
@ -382,7 +379,7 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
return 0; return 0;
} }
byte_buffer_t *pdu = pool_allocate; unique_byte_buffer pdu = allocate_unique_buffer(*pool);
if(!pdu || pdu->N_bytes != 0) { if(!pdu || pdu->N_bytes != 0) {
log->error("Failed to allocate PDU buffer\n"); log->error("Failed to allocate PDU buffer\n");
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
@ -400,11 +397,10 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
uint8_t *pdu_ptr = pdu->msg; uint8_t *pdu_ptr = pdu->msg;
int head_len = rlc_um_packed_length(&header); int head_len = rlc_um_packed_length(&header);
int pdu_space = SRSLTE_MIN(nof_bytes, pdu->get_tailroom());; int pdu_space = SRSLTE_MIN(nof_bytes, pdu->get_tailroom());
if(pdu_space <= head_len + 1) if(pdu_space <= head_len + 1)
{ {
pool->deallocate(pdu);
log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n", log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n",
get_rb_name(), nof_bytes, head_len); get_rb_name(), nof_bytes, head_len);
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
@ -428,8 +424,7 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
get_rb_name(), tx_sdu->get_latency_us()); get_rb_name(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); tx_sdu.reset();
tx_sdu = NULL;
} }
pdu_space -= SRSLTE_MIN(to_move, pdu->get_tailroom()); pdu_space -= SRSLTE_MIN(to_move, pdu->get_tailroom());
header.fi |= RLC_FI_FIELD_NOT_START_ALIGNED; // First byte does not correspond to first byte of SDU header.fi |= RLC_FI_FIELD_NOT_START_ALIGNED; // First byte does not correspond to first byte of SDU
@ -456,8 +451,7 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
get_rb_name(), tx_sdu->get_latency_us()); get_rb_name(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu); tx_sdu.reset();
tx_sdu = NULL;
} }
pdu_space -= to_move; pdu_space -= to_move;
} }
@ -471,12 +465,11 @@ int rlc_um::rlc_um_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
vt_us = (vt_us + 1)%cfg.tx_mod; vt_us = (vt_us + 1)%cfg.tx_mod;
// Add header and TX // Add header and TX
rlc_um_write_data_pdu_header(&header, pdu); rlc_um_write_data_pdu_header(&header, pdu.get());
memcpy(payload, pdu->msg, pdu->N_bytes); memcpy(payload, pdu->msg, pdu->N_bytes);
uint32_t ret = pdu->N_bytes; uint32_t ret = pdu->N_bytes;
log->info_hex(payload, ret, "%s Tx PDU SN=%d (%d B)\n", get_rb_name(), header.sn, pdu->N_bytes); log->info_hex(payload, ret, "%s Tx PDU SN=%d (%d B)\n", get_rb_name(), header.sn, pdu->N_bytes);
pool->deallocate(pdu);
debug_state(); debug_state();
@ -509,7 +502,6 @@ rlc_um::rlc_um_rx::rlc_um_rx()
,log(NULL) ,log(NULL)
,pdcp(NULL) ,pdcp(NULL)
,rrc(NULL) ,rrc(NULL)
,rx_sdu(NULL)
,vr_ur(0) ,vr_ur(0)
,vr_ux (0) ,vr_ux (0)
,vr_uh(0) ,vr_uh(0)
@ -582,16 +574,9 @@ void rlc_um::rlc_um_rx::reset()
pdu_lost = false; pdu_lost = false;
rx_enabled = false; rx_enabled = false;
if (rx_sdu) { rx_sdu.reset();
pool->deallocate(rx_sdu);
rx_sdu = NULL;
}
// Drop all messages in RX window // Drop all messages in RX window
std::map<uint32_t, rlc_umd_pdu_t>::iterator it;
for(it = rx_window.begin(); it != rx_window.end(); it++) {
pool->deallocate(it->second.buf);
}
rx_window.clear(); rx_window.clear();
} }
@ -630,7 +615,7 @@ void rlc_um::rlc_um_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
} }
// Write to rx window // Write to rx window
pdu.buf = pool_allocate; pdu.buf = allocate_unique_buffer(*pool);
if (!pdu.buf) { if (!pdu.buf) {
log->error("Discarting packet: no space in buffer pool\n"); log->error("Discarting packet: no space in buffer pool\n");
goto unlock_and_exit; goto unlock_and_exit;
@ -642,7 +627,7 @@ void rlc_um::rlc_um_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
pdu.buf->msg += header_len; pdu.buf->msg += header_len;
pdu.buf->N_bytes -= header_len; pdu.buf->N_bytes -= header_len;
pdu.header = header; pdu.header = header;
rx_window[header.sn] = pdu; rx_window[header.sn] = std::move(pdu);
// Update vr_uh // Update vr_uh
if(!inside_reordering_window(header.sn)) { if(!inside_reordering_window(header.sn)) {
@ -681,7 +666,7 @@ unlock_and_exit:
void rlc_um::rlc_um_rx::reassemble_rx_sdus() void rlc_um::rlc_um_rx::reassemble_rx_sdus()
{ {
if(!rx_sdu) { if(!rx_sdu) {
rx_sdu = pool_allocate; rx_sdu = allocate_unique_buffer(*pool);
if (!rx_sdu) { if (!rx_sdu) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return; return;
@ -724,11 +709,11 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", get_rb_name(), vr_ur, i); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", get_rb_name(), vr_ur, i);
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
if(cfg.is_mrb){ if(cfg.is_mrb){
pdcp->write_pdu_mch(lcid, rx_sdu); pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} else { } else {
pdcp->write_pdu(lcid, rx_sdu); pdcp->write_pdu(lcid, std::move(rx_sdu));
} }
rx_sdu = pool_allocate; rx_sdu = allocate_unique_buffer(*pool);
if (!rx_sdu) { if (!rx_sdu) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return; return;
@ -754,11 +739,11 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", get_rb_name(), vr_ur); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", get_rb_name(), vr_ur);
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
if(cfg.is_mrb){ if(cfg.is_mrb){
pdcp->write_pdu_mch(lcid, rx_sdu); pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} else { } else {
pdcp->write_pdu(lcid, rx_sdu); pdcp->write_pdu(lcid, std::move(rx_sdu));
} }
rx_sdu = pool_allocate; rx_sdu = allocate_unique_buffer(*pool);
if (!rx_sdu) { if (!rx_sdu) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return; return;
@ -769,7 +754,6 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
} }
// Clean up rx_window // Clean up rx_window
pool->deallocate(rx_window[vr_ur].buf);
rx_window.erase(vr_ur); rx_window.erase(vr_ur);
} }
@ -835,11 +819,11 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", get_rb_name(), vr_ur, i); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", get_rb_name(), vr_ur, i);
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
if(cfg.is_mrb){ if(cfg.is_mrb){
pdcp->write_pdu_mch(lcid, rx_sdu); pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} else { } else {
pdcp->write_pdu(lcid, rx_sdu); pdcp->write_pdu(lcid, std::move(rx_sdu));
} }
rx_sdu = pool_allocate; rx_sdu = allocate_unique_buffer(*pool);
if (!rx_sdu) { if (!rx_sdu) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return; return;
@ -881,11 +865,11 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", get_rb_name(), vr_ur); log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", get_rb_name(), vr_ur);
rx_sdu->set_timestamp(); rx_sdu->set_timestamp();
if(cfg.is_mrb){ if(cfg.is_mrb){
pdcp->write_pdu_mch(lcid, rx_sdu); pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} else { } else {
pdcp->write_pdu(lcid, rx_sdu); pdcp->write_pdu(lcid, std::move(rx_sdu));
} }
rx_sdu = pool_allocate; rx_sdu = allocate_unique_buffer(*pool);
if (!rx_sdu) { if (!rx_sdu) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return; return;
@ -896,7 +880,6 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
clean_up_rx_window: clean_up_rx_window:
// Clean up rx_window // Clean up rx_window
pool->deallocate(rx_window[vr_ur].buf);
rx_window.erase(vr_ur); rx_window.erase(vr_ur);
vr_ur = (vr_ur + 1)%cfg.rx_mod; vr_ur = (vr_ur + 1)%cfg.rx_mod;
@ -1001,7 +984,7 @@ const char* rlc_um::rlc_um_rx::get_rb_name()
* Ref: 3GPP TS 36.322 v10.0.0 Section 6.2.1 * Ref: 3GPP TS 36.322 v10.0.0 Section 6.2.1
***************************************************************************/ ***************************************************************************/
void rlc_um_read_data_pdu_header(byte_buffer_t *pdu, rlc_umd_sn_size_t sn_size, rlc_umd_pdu_header_t *header) void rlc_um_read_data_pdu_header(byte_buffer_t* pdu, rlc_umd_sn_size_t sn_size, rlc_umd_pdu_header_t* header)
{ {
rlc_um_read_data_pdu_header(pdu->msg, pdu->N_bytes, sn_size, header); rlc_um_read_data_pdu_header(pdu->msg, pdu->N_bytes, sn_size, header);
} }
@ -1052,7 +1035,7 @@ void rlc_um_read_data_pdu_header(uint8_t *payload, uint32_t nof_bytes, rlc_umd_s
} }
} }
void rlc_um_write_data_pdu_header(rlc_umd_pdu_header_t *header, byte_buffer_t *pdu) void rlc_um_write_data_pdu_header(rlc_umd_pdu_header_t* header, byte_buffer_t* pdu)
{ {
uint32_t i; uint32_t i;
uint8_t ext = (header->N_li > 0) ? 1 : 0; uint8_t ext = (header->N_li > 0) ? 1 : 0;

View File

@ -21,8 +21,9 @@
#define NMSGS 1000000 #define NMSGS 1000000
#include <stdio.h> #include "srslte/common/buffer_pool.h"
#include "srslte/upper/rlc_tx_queue.h" #include "srslte/upper/rlc_tx_queue.h"
#include <stdio.h>
using namespace srslte; using namespace srslte;
@ -32,12 +33,13 @@ typedef struct {
void* write_thread(void *a) { void* write_thread(void *a) {
args_t *args = (args_t*)a; args_t *args = (args_t*)a;
byte_buffer_pool* pool = byte_buffer_pool::get_instance();
for(uint32_t i=0;i<NMSGS;i++) for(uint32_t i=0;i<NMSGS;i++)
{ {
byte_buffer_t *b = new byte_buffer_t; unique_byte_buffer b = srslte::allocate_unique_buffer(*pool, true);
memcpy(b->msg, &i, 4); memcpy(b->msg, &i, 4);
b->N_bytes = 4; b->N_bytes = 4;
args->q->write(b); args->q->write(std::move(b));
} }
return NULL; return NULL;
} }
@ -45,7 +47,7 @@ void* write_thread(void *a) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
bool result; bool result;
rlc_tx_queue q; rlc_tx_queue q;
byte_buffer_t *b; unique_byte_buffer b;
pthread_t thread; pthread_t thread;
args_t args; args_t args;
u_int32_t r; u_int32_t r;
@ -59,7 +61,6 @@ int main(int argc, char **argv) {
{ {
q.read(&b); q.read(&b);
memcpy(&r, b->msg, 4); memcpy(&r, b->msg, 4);
delete b;
if(r != i) if(r != i)
result = false; result = false;
} }

View File

@ -62,35 +62,26 @@ class rlc_am_tester
public: public:
rlc_am_tester(rlc_pcap *pcap_ = NULL) rlc_am_tester(rlc_pcap *pcap_ = NULL)
{ {
bzero(sdus, sizeof(sdus));
n_sdus = 0; n_sdus = 0;
pcap = pcap_; pcap = pcap_;
} }
~rlc_am_tester(){
for (uint32_t i = 0; i < 10; i++) {
if (sdus[i] != NULL) {
byte_buffer_pool::get_instance()->deallocate(sdus[i]);
}
}
}
// PDCP interface // PDCP interface
void write_pdu(uint32_t lcid, byte_buffer_t *sdu) void write_pdu(uint32_t lcid, unique_byte_buffer sdu)
{ {
assert(lcid == 1); assert(lcid == 1);
sdus[n_sdus++] = sdu; sdus[n_sdus++] = std::move(sdu);
} }
void write_pdu_bcch_bch(byte_buffer_t *sdu) {} void write_pdu_bcch_bch(unique_byte_buffer sdu) {}
void write_pdu_bcch_dlsch(byte_buffer_t *sdu) {} void write_pdu_bcch_dlsch(unique_byte_buffer sdu) {}
void write_pdu_pcch(byte_buffer_t *sdu) {} void write_pdu_pcch(unique_byte_buffer sdu) {}
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *pdu){} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer pdu) {}
// RRC interface // RRC interface
void max_retx_attempted(){} void max_retx_attempted(){}
std::string get_rb_name(uint32_t lcid) { return std::string(""); } std::string get_rb_name(uint32_t lcid) { return std::string(""); }
byte_buffer_t *sdus[10]; unique_byte_buffer sdus[10];
int n_sdus; int n_sdus;
rlc_pcap *pcap; rlc_pcap *pcap;
}; };
@ -116,7 +107,8 @@ private:
int sn = 0; int sn = 0;
running = true; running = true;
while(running) { while(running) {
byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate("rlc_tester::run_thread", true); byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, "rlc_tester::run_thread", true);
if (!pdu) { if (!pdu) {
printf("Error: Could not allocate PDU in rlc_tester::run_thread\n\n\n"); printf("Error: Could not allocate PDU in rlc_tester::run_thread\n\n\n");
// backoff for a bit // backoff for a bit
@ -128,7 +120,7 @@ private:
} }
sn++; sn++;
pdu->N_bytes = SDU_SIZE; pdu->N_bytes = SDU_SIZE;
rlc->write_sdu(pdu); rlc->write_sdu(std::move(pdu));
} }
running = false; running = false;
} }
@ -177,12 +169,14 @@ bool basic_test()
} }
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
*sdu_bufs[i].msg = i; // Write the index into the buffer sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
sdu_bufs[i].N_bytes = 1; // Give each buffer a size of 1 byte sdu_bufs[i]->msg[0] = i; // Write the index into the buffer
rlc1.write_sdu(&sdu_bufs[i]); sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte
rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(14 == rlc1.get_buffer_state()); assert(14 == rlc1.get_buffer_state());
@ -272,12 +266,14 @@ bool concat_test()
} }
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
*sdu_bufs[i].msg = i; // Write the index into the buffer sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
sdu_bufs[i].N_bytes = 1; // Give each buffer a size of 1 byte sdu_bufs[i]->msg[0] = i; // Write the index into the buffer
rlc1.write_sdu(&sdu_bufs[i]); sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte
rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(14 == rlc1.get_buffer_state()); assert(14 == rlc1.get_buffer_state());
@ -352,13 +348,15 @@ bool segment_test(bool in_seq_rx)
} }
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for(int j=0;j<10;j++) for(int j=0;j<10;j++)
sdu_bufs[i].msg[j] = j; sdu_bufs[i]->msg[j] = j;
sdu_bufs[i].N_bytes = 10; // Give each buffer a size of 10 bytes sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(59 == rlc1.get_buffer_state()); assert(59 == rlc1.get_buffer_state());
@ -460,12 +458,14 @@ bool retx_test()
} }
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
*sdu_bufs[i].msg = i; // Write the index into the buffer sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
sdu_bufs[i].N_bytes = 1; // Give each buffer a size of 1 byte sdu_bufs[i]->msg[0] = i; // Write the index into the buffer
rlc1.write_sdu(&sdu_bufs[i]); sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte
rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(14 == rlc1.get_buffer_state()); assert(14 == rlc1.get_buffer_state());
@ -567,13 +567,15 @@ bool resegment_test_1()
} }
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for(int j=0;j<10;j++) for(int j=0;j<10;j++)
sdu_bufs[i].msg[j] = j; sdu_bufs[i]->msg[j] = j;
sdu_bufs[i].N_bytes = 10; // Give each buffer a size of 10 bytes sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(59 == rlc1.get_buffer_state()); assert(59 == rlc1.get_buffer_state());
@ -687,13 +689,15 @@ bool resegment_test_2()
} }
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for(int j=0;j<10;j++) for(int j=0;j<10;j++)
sdu_bufs[i].msg[j] = j; sdu_bufs[i]->msg[j] = j;
sdu_bufs[i].N_bytes = 10; // Give each buffer a size of 10 bytes sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(59 == rlc1.get_buffer_state()); assert(59 == rlc1.get_buffer_state());
@ -804,13 +808,15 @@ bool resegment_test_3()
} }
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for(int j=0;j<10;j++) for(int j=0;j<10;j++)
sdu_bufs[i].msg[j] = j; sdu_bufs[i]->msg[j] = j;
sdu_bufs[i].N_bytes = 10; // Give each buffer a size of 10 bytes sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(59 == rlc1.get_buffer_state()); assert(59 == rlc1.get_buffer_state());
@ -916,13 +922,15 @@ bool resegment_test_4()
} }
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for(int j=0;j<10;j++) for(int j=0;j<10;j++)
sdu_bufs[i].msg[j] = j; sdu_bufs[i]->msg[j] = j;
sdu_bufs[i].N_bytes = 10; // Give each buffer a size of 10 bytes sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(59 == rlc1.get_buffer_state()); assert(59 == rlc1.get_buffer_state());
@ -1028,13 +1036,15 @@ bool resegment_test_5()
} }
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for(int j=0;j<10;j++) for(int j=0;j<10;j++)
sdu_bufs[i].msg[j] = j; sdu_bufs[i]->msg[j] = j;
sdu_bufs[i].N_bytes = 10; // Give each buffer a size of 10 bytes sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(59 == rlc1.get_buffer_state()); assert(59 == rlc1.get_buffer_state());
@ -1142,20 +1152,23 @@ bool resegment_test_6()
} }
// Push SDUs into RLC1 // Push SDUs into RLC1
byte_buffer_t sdu_bufs[9]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[9];
for(int i=0;i<3;i++) for(int i=0;i<3;i++)
{ {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for(int j=0;j<10;j++) for(int j=0;j<10;j++)
sdu_bufs[i].msg[j] = j; sdu_bufs[i]->msg[j] = j;
sdu_bufs[i].N_bytes = 10; sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
for(int i=3;i<9;i++) for(int i=3;i<9;i++)
{ {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for(int j=0;j<54;j++) for(int j=0;j<54;j++)
sdu_bufs[i].msg[j] = j; sdu_bufs[i]->msg[j] = j;
sdu_bufs[i].N_bytes = 54; sdu_bufs[i]->N_bytes = 54;
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(369 == rlc1.get_buffer_state()); assert(369 == rlc1.get_buffer_state());
@ -1290,14 +1303,16 @@ bool resegment_test_7()
} }
// Push 2 SDUs into RLC1 // Push 2 SDUs into RLC1
byte_buffer_t sdu_bufs[N_SDU_BUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[N_SDU_BUFS];
for(uint32_t i=0;i<N_SDU_BUFS;i++) for(uint32_t i=0;i<N_SDU_BUFS;i++)
{ {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for(uint32_t j=0;j<sdu_size;j++) { for(uint32_t j=0;j<sdu_size;j++) {
sdu_bufs[i].msg[j] = i; sdu_bufs[i]->msg[j] = i;
} }
sdu_bufs[i].N_bytes = sdu_size; // Give each buffer a size of 15 bytes sdu_bufs[i]->N_bytes = sdu_size; // Give each buffer a size of 15 bytes
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(65 == rlc1.get_buffer_state()); assert(65 == rlc1.get_buffer_state());
@ -1477,14 +1492,16 @@ bool resegment_test_8()
} }
// Push 2 SDUs into RLC1 // Push 2 SDUs into RLC1
byte_buffer_t sdu_bufs[N_SDU_BUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[N_SDU_BUFS];
for(uint32_t i=0;i<N_SDU_BUFS;i++) for(uint32_t i=0;i<N_SDU_BUFS;i++)
{ {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for(uint32_t j=0;j<sdu_size;j++) { for(uint32_t j=0;j<sdu_size;j++) {
sdu_bufs[i].msg[j] = i; sdu_bufs[i]->msg[j] = i;
} }
sdu_bufs[i].N_bytes = sdu_size; // Give each buffer a size of 15 bytes sdu_bufs[i]->N_bytes = sdu_size; // Give each buffer a size of 15 bytes
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
assert(65 == rlc1.get_buffer_state()); assert(65 == rlc1.get_buffer_state());
@ -1631,10 +1648,11 @@ bool reset_test()
} }
// Push 1 SDU of size 10 into RLC1 // Push 1 SDU of size 10 into RLC1
byte_buffer_t sdu_buf; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
*sdu_buf.msg = 1; // Write the index into the buffer unique_byte_buffer sdu_buf = srslte::allocate_unique_buffer(*pool, true);
sdu_buf.N_bytes = 100; sdu_buf->msg[0] = 1; // Write the index into the buffer
rlc1.write_sdu(&sdu_buf); sdu_buf->N_bytes = 100;
rlc1.write_sdu(std::move(sdu_buf));
// read 1 PDU from RLC1 and force segmentation // read 1 PDU from RLC1 and force segmentation
byte_buffer_t pdu_bufs; byte_buffer_t pdu_bufs;

View File

@ -146,7 +146,8 @@ public:
private: private:
void run_tti(rlc_interface_mac *tx_rlc, rlc_interface_mac *rx_rlc, bool is_dl) void run_tti(rlc_interface_mac *tx_rlc, rlc_interface_mac *rx_rlc, bool is_dl)
{ {
byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate(__PRETTY_FUNCTION__); byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, __PRETTY_FUNCTION__, true);
if (!pdu) { if (!pdu) {
printf("Fatal Error: Could not allocate PDU in mac_reader::run_thread\n"); printf("Fatal Error: Could not allocate PDU in mac_reader::run_thread\n");
exit(-1); exit(-1);
@ -175,7 +176,6 @@ private:
log.warning_hex(pdu->msg, pdu->N_bytes, "Dropping RLC PDU (%d B)\n", pdu->N_bytes); log.warning_hex(pdu->msg, pdu->N_bytes, "Dropping RLC PDU (%d B)\n", pdu->N_bytes);
} }
} }
byte_buffer_pool::get_instance()->deallocate(pdu);
} }
void run_thread() void run_thread()
@ -229,7 +229,7 @@ public:
} }
// PDCP interface // PDCP interface
void write_pdu(uint32_t rx_lcid, byte_buffer_t *sdu) void write_pdu(uint32_t rx_lcid, unique_byte_buffer sdu)
{ {
assert(rx_lcid == lcid); assert(rx_lcid == lcid);
if (sdu->N_bytes != args.sdu_size) { if (sdu->N_bytes != args.sdu_size) {
@ -237,13 +237,12 @@ public:
exit(-1); exit(-1);
} }
byte_buffer_pool::get_instance()->deallocate(sdu);
rx_pdus++; rx_pdus++;
} }
void write_pdu_bcch_bch(byte_buffer_t *sdu) {} void write_pdu_bcch_bch(unique_byte_buffer sdu) {}
void write_pdu_bcch_dlsch(byte_buffer_t *sdu) {} void write_pdu_bcch_dlsch(unique_byte_buffer sdu) {}
void write_pdu_pcch(byte_buffer_t *sdu) {} void write_pdu_pcch(unique_byte_buffer sdu) {}
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) {}
// RRC interface // RRC interface
void max_retx_attempted(){} void max_retx_attempted(){}
@ -254,8 +253,9 @@ public:
private: private:
void run_thread() { void run_thread() {
uint8_t sn = 0; uint8_t sn = 0;
byte_buffer_pool* pool = byte_buffer_pool::get_instance();
while(run_enable) { while(run_enable) {
byte_buffer_t *pdu = byte_buffer_pool::get_instance()->allocate("rlc_tester::run_thread"); unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, "rlc_tester::run_thread", true);
if (pdu == NULL) { if (pdu == NULL) {
printf("Error: Could not allocate PDU in rlc_tester::run_thread\n\n\n"); printf("Error: Could not allocate PDU in rlc_tester::run_thread\n\n\n");
// backoff for a bit // backoff for a bit
@ -267,7 +267,7 @@ private:
} }
sn++; sn++;
pdu->N_bytes = args.sdu_size; pdu->N_bytes = args.sdu_size;
rlc->write_sdu(lcid, pdu); rlc->write_sdu(lcid, std::move(pdu));
if (args.sdu_gen_delay_usec > 0) { if (args.sdu_gen_delay_usec > 0) {
usleep(args.sdu_gen_delay_usec); usleep(args.sdu_gen_delay_usec);
} }

View File

@ -67,29 +67,21 @@ public:
expected_sdu_len = 0; expected_sdu_len = 0;
} }
~rlc_um_tester(){
for (uint32_t i = 0; i < NBUFS; i++) {
if (sdus[i] != NULL) {
byte_buffer_pool::get_instance()->deallocate(sdus[i]);
}
}
}
// PDCP interface // PDCP interface
void write_pdu(uint32_t lcid, byte_buffer_t *sdu) void write_pdu(uint32_t lcid, unique_byte_buffer sdu)
{ {
if (lcid != 3 && sdu->N_bytes != expected_sdu_len) { if (lcid != 3 && sdu->N_bytes != expected_sdu_len) {
printf("Received PDU with size %d, expected %d. Exiting.\n", sdu->N_bytes, expected_sdu_len); printf("Received PDU with size %d, expected %d. Exiting.\n", sdu->N_bytes, expected_sdu_len);
exit(-1); exit(-1);
} }
sdus[n_sdus++] = sdu; sdus[n_sdus++] = std::move(sdu);
} }
void write_pdu_bcch_bch(byte_buffer_t *sdu) {} void write_pdu_bcch_bch(unique_byte_buffer sdu) {}
void write_pdu_bcch_dlsch(byte_buffer_t *sdu) {} void write_pdu_bcch_dlsch(unique_byte_buffer sdu) {}
void write_pdu_pcch(byte_buffer_t *sdu) {} void write_pdu_pcch(unique_byte_buffer sdu) {}
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu) void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu)
{ {
sdus[n_sdus++] = sdu; sdus[n_sdus++] = std::move(sdu);
} }
// RRC interface // RRC interface
@ -97,7 +89,7 @@ public:
std::string get_rb_name(uint32_t lcid) { return std::string(""); } std::string get_rb_name(uint32_t lcid) { return std::string(""); }
void set_expected_sdu_len(uint32_t len) { expected_sdu_len = len; } void set_expected_sdu_len(uint32_t len) { expected_sdu_len = len; }
byte_buffer_t *sdus[MAX_NBUFS]; unique_byte_buffer sdus[MAX_NBUFS];
int n_sdus; int n_sdus;
uint32_t expected_sdu_len; uint32_t expected_sdu_len;
}; };
@ -136,12 +128,14 @@ int basic_test()
tester.set_expected_sdu_len(1); tester.set_expected_sdu_len(1);
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
*sdu_bufs[i].msg = i; // Write the index into the buffer sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
sdu_bufs[i].N_bytes = 1; // Give each buffer a size of 1 byte *sdu_bufs[i]->msg = i; // Write the index into the buffer
rlc1.write_sdu(&sdu_bufs[i]); sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte
rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
TESTASSERT(14 == rlc1.get_buffer_state()); TESTASSERT(14 == rlc1.get_buffer_state());
@ -208,12 +202,14 @@ int loss_test()
tester.set_expected_sdu_len(1); tester.set_expected_sdu_len(1);
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
*sdu_bufs[i].msg = i; // Write the index into the buffer sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
sdu_bufs[i].N_bytes = 1; // Give each buffer a size of 1 byte sdu_bufs[i]->msg[0] = i; // Write the index into the buffer
rlc1.write_sdu(&sdu_bufs[i]); sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte
rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
TESTASSERT(14 == rlc1.get_buffer_state()); TESTASSERT(14 == rlc1.get_buffer_state());
@ -272,12 +268,14 @@ int basic_mbsfn_test()
tester.set_expected_sdu_len(1); tester.set_expected_sdu_len(1);
// Push 5 SDUs into RLC1 // Push 5 SDUs into RLC1
byte_buffer_t sdu_bufs[NBUFS*2]; byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[NBUFS * 2];
for(int i=0;i<NBUFS;i++) for(int i=0;i<NBUFS;i++)
{ {
*sdu_bufs[i].msg = i; // Write the index into the buffer sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
sdu_bufs[i].N_bytes = 1; // Give each buffer a size of 1 byte sdu_bufs[i]->msg[0] = i; // Write the index into the buffer
rlc1.write_sdu(&sdu_bufs[i]); sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte
rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
TESTASSERT(13 == rlc1.get_buffer_state()); TESTASSERT(13 == rlc1.get_buffer_state());
@ -358,16 +356,18 @@ int reassmble_test()
tester.set_expected_sdu_len(sdu_len); tester.set_expected_sdu_len(sdu_len);
byte_buffer_t sdu_bufs[n_sdus];
const int n_sdu_first_batch = 17; const int n_sdu_first_batch = 17;
byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[n_sdus];
for(int i=0;i<n_sdu_first_batch;i++) { for(int i=0;i<n_sdu_first_batch;i++) {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for (int k = 0; k < sdu_len; ++k) { for (int k = 0; k < sdu_len; ++k) {
sdu_bufs[i].msg[k] = i; sdu_bufs[i]->msg[k] = i;
} }
sdu_bufs[i].N_bytes = sdu_len; // Give each buffer a size of 1 byte sdu_bufs[i]->N_bytes = sdu_len; // Give each buffer a size of 1 byte
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
// Read PDUs from RLC1 (use smaller grant for first PDU and large for the rest) // Read PDUs from RLC1 (use smaller grant for first PDU and large for the rest)
@ -391,11 +391,12 @@ int reassmble_test()
// push second batch of SDUs // push second batch of SDUs
for (int i = n_sdu_first_batch; i < n_sdus; ++i) { for (int i = n_sdu_first_batch; i < n_sdus; ++i) {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for (int k = 0; k < sdu_len; ++k) { for (int k = 0; k < sdu_len; ++k) {
sdu_bufs[i].msg[k] = i; sdu_bufs[i]->msg[k] = i;
} }
sdu_bufs[i].N_bytes = sdu_len; // Give each buffer a size of 1 byte sdu_bufs[i]->N_bytes = sdu_len; // Give each buffer a size of 1 byte
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
// Read second batch of PDUs (use large grants) // Read second batch of PDUs (use large grants)
@ -475,15 +476,16 @@ int reassmble_test2()
tester.set_expected_sdu_len(sdu_len); tester.set_expected_sdu_len(sdu_len);
byte_buffer_t sdu_bufs[n_sdus];
const int n_sdu_first_batch = 17; const int n_sdu_first_batch = 17;
byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer sdu_bufs[n_sdus];
for(int i=0;i<n_sdu_first_batch;i++) { for(int i=0;i<n_sdu_first_batch;i++) {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for (int k = 0; k < sdu_len; ++k) { for (int k = 0; k < sdu_len; ++k) {
sdu_bufs[i].msg[k] = i; sdu_bufs[i]->msg[k] = i;
} }
sdu_bufs[i].N_bytes = sdu_len; sdu_bufs[i]->N_bytes = sdu_len;
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
const int max_n_pdus = 100; const int max_n_pdus = 100;
@ -506,11 +508,12 @@ int reassmble_test2()
// push second batch of SDUs // push second batch of SDUs
for (int i = n_sdu_first_batch; i < n_sdus; ++i) { for (int i = n_sdu_first_batch; i < n_sdus; ++i) {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
for (int k = 0; k < sdu_len; ++k) { for (int k = 0; k < sdu_len; ++k) {
sdu_bufs[i].msg[k] = i; sdu_bufs[i]->msg[k] = i;
} }
sdu_bufs[i].N_bytes = sdu_len; // Give each buffer a size of 1 byte sdu_bufs[i]->N_bytes = sdu_len; // Give each buffer a size of 1 byte
rlc1.write_sdu(&sdu_bufs[i]); rlc1.write_sdu(std::move(sdu_bufs[i]));
} }
// Read second batch of PDUs // Read second batch of PDUs

View File

@ -53,7 +53,7 @@ public:
void rem_user(uint16_t rnti); void rem_user(uint16_t rnti);
// gtpu_interface_pdcp // gtpu_interface_pdcp
void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_pool_buffer pdu); void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer pdu);
private: private:
static const int THREAD_PRIO = 65; static const int THREAD_PRIO = 65;

View File

@ -39,14 +39,14 @@ public:
void stop(); void stop();
// pdcp_interface_rlc // pdcp_interface_rlc
void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu); void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer sdu);
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu){} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) {}
// pdcp_interface_rrc // pdcp_interface_rrc
void reset(uint16_t rnti); void reset(uint16_t rnti);
void add_user(uint16_t rnti); void add_user(uint16_t rnti);
void rem_user(uint16_t rnti); void rem_user(uint16_t rnti);
void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_pool_buffer sdu); void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer sdu);
void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_pdcp_config_t cnfg); void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_pdcp_config_t cnfg);
void config_security(uint16_t rnti, void config_security(uint16_t rnti,
uint32_t lcid, uint32_t lcid,
@ -65,7 +65,7 @@ private:
uint16_t rnti; uint16_t rnti;
srsenb::rlc_interface_pdcp *rlc; srsenb::rlc_interface_pdcp *rlc;
// rlc_interface_pdcp // rlc_interface_pdcp
void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu, bool blocking); void write_sdu(uint32_t lcid, srslte::unique_byte_buffer sdu, bool blocking);
bool rb_is_um(uint32_t lcid); bool rb_is_um(uint32_t lcid);
}; };
@ -75,8 +75,8 @@ private:
uint16_t rnti; uint16_t rnti;
srsenb::gtpu_interface_pdcp *gtpu; srsenb::gtpu_interface_pdcp *gtpu;
// gw_interface_pdcp // gw_interface_pdcp
void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu); void write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu);
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu){} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) {}
}; };
class user_interface_rrc : public srsue::rrc_interface_pdcp class user_interface_rrc : public srsue::rrc_interface_pdcp
@ -85,11 +85,11 @@ private:
uint16_t rnti; uint16_t rnti;
srsenb::rrc_interface_pdcp *rrc; srsenb::rrc_interface_pdcp *rrc;
// rrc_interface_pdcp // rrc_interface_pdcp
void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu); void write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu);
void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu); void write_pdu_bcch_bch(srslte::unique_byte_buffer pdu);
void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu); void write_pdu_bcch_dlsch(srslte::unique_byte_buffer pdu);
void write_pdu_pcch(srslte::byte_buffer_t *pdu); void write_pdu_pcch(srslte::unique_byte_buffer pdu);
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *pdu){} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer pdu) {}
std::string get_rb_name(uint32_t lcid); std::string get_rb_name(uint32_t lcid);
}; };

View File

@ -55,7 +55,7 @@ public:
void add_bearer_mrb(uint16_t rnti, uint32_t lcid); void add_bearer_mrb(uint16_t rnti, uint32_t lcid);
// rlc_interface_pdcp // rlc_interface_pdcp
void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu); void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer sdu);
bool rb_is_um(uint16_t rnti, uint32_t lcid); bool rb_is_um(uint16_t rnti, uint32_t lcid);
std::string get_rb_name(uint32_t lcid); std::string get_rb_name(uint32_t lcid);
@ -72,11 +72,11 @@ private:
public srsue::ue_interface public srsue::ue_interface
{ {
public: public:
void write_pdu(uint32_t lcid, srslte::byte_buffer_t *sdu); void write_pdu(uint32_t lcid, srslte::unique_byte_buffer sdu);
void write_pdu_bcch_bch(srslte::byte_buffer_t *sdu); void write_pdu_bcch_bch(srslte::unique_byte_buffer sdu);
void write_pdu_bcch_dlsch(srslte::byte_buffer_t *sdu); void write_pdu_bcch_dlsch(srslte::unique_byte_buffer sdu);
void write_pdu_pcch(srslte::byte_buffer_t *sdu); void write_pdu_pcch(srslte::unique_byte_buffer sdu);
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu){} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) {}
void max_retx_attempted(); void max_retx_attempted();
std::string get_rb_name(uint32_t lcid); std::string get_rb_name(uint32_t lcid);
uint16_t rnti; uint16_t rnti;

View File

@ -153,7 +153,7 @@ public:
void max_retx_attempted(uint16_t rnti); void max_retx_attempted(uint16_t rnti);
// rrc_interface_s1ap // rrc_interface_s1ap
void write_dl_info(uint16_t rnti, srslte::byte_buffer_t *sdu); void write_dl_info(uint16_t rnti, srslte::unique_byte_buffer sdu);
void release_complete(uint16_t rnti); void release_complete(uint16_t rnti);
bool setup_ue_ctxt(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg); bool setup_ue_ctxt(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg);
bool setup_ue_erabs(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *msg); bool setup_ue_erabs(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *msg);
@ -161,7 +161,7 @@ public:
void add_paging_id(uint32_t ueid, LIBLTE_S1AP_UEPAGINGID_STRUCT UEPagingID); void add_paging_id(uint32_t ueid, LIBLTE_S1AP_UEPAGINGID_STRUCT UEPagingID);
// rrc_interface_pdcp // rrc_interface_pdcp
void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *pdu); void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_sibs(); void parse_sibs();
uint32_t get_nof_users(); uint32_t get_nof_users();
@ -207,17 +207,17 @@ public:
void send_connection_reject(); void send_connection_reject();
void send_connection_release(); void send_connection_release();
void send_connection_reest_rej(); void send_connection_reest_rej();
void send_connection_reconf(srslte::byte_buffer_t *sdu); void send_connection_reconf(srslte::unique_byte_buffer sdu);
void send_connection_reconf_new_bearer(LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT *e); void send_connection_reconf_new_bearer(LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT *e);
void send_connection_reconf_upd(srslte::byte_buffer_t *pdu); void send_connection_reconf_upd(srslte::unique_byte_buffer pdu);
void send_security_mode_command(); void send_security_mode_command();
void send_ue_cap_enquiry(); void send_ue_cap_enquiry();
void parse_ul_dcch(uint32_t lcid, srslte::byte_buffer_t* pdu); void parse_ul_dcch(uint32_t lcid, srslte::unique_byte_buffer pdu);
void handle_rrc_con_req(asn1::rrc::rrc_conn_request_s* msg); 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_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::byte_buffer_t* pdu); void handle_rrc_con_setup_complete(asn1::rrc::rrc_conn_setup_complete_s* msg, srslte::unique_byte_buffer pdu);
void handle_rrc_reconf_complete(asn1::rrc::rrc_conn_recfg_complete_s* msg, srslte::byte_buffer_t* pdu); void handle_rrc_reconf_complete(asn1::rrc::rrc_conn_recfg_complete_s* msg, srslte::unique_byte_buffer pdu);
void handle_security_mode_complete(asn1::rrc::security_mode_complete_s* msg); void handle_security_mode_complete(asn1::rrc::security_mode_complete_s* msg);
void handle_security_mode_failure(asn1::rrc::security_mode_fail_s* msg); void handle_security_mode_failure(asn1::rrc::security_mode_fail_s* msg);
bool handle_ue_cap_info(asn1::rrc::ue_cap_info_s* msg); bool handle_ue_cap_info(asn1::rrc::ue_cap_info_s* msg);
@ -246,7 +246,8 @@ public:
bool select_security_algorithms(); bool select_security_algorithms();
void send_dl_ccch(asn1::rrc::dl_ccch_msg_s* dl_ccch_msg); void send_dl_ccch(asn1::rrc::dl_ccch_msg_s* dl_ccch_msg);
void send_dl_dcch(asn1::rrc::dl_dcch_msg_s* dl_dcch_msg, srslte::byte_buffer_t* pdu = NULL); void send_dl_dcch(asn1::rrc::dl_dcch_msg_s* dl_dcch_msg,
srslte::unique_byte_buffer pdu = srslte::unique_byte_buffer());
uint16_t rnti; uint16_t rnti;
rrc* parent; rrc* parent;
@ -315,7 +316,7 @@ private:
activity_monitor act_monitor; activity_monitor act_monitor;
std::vector<srslte::byte_buffer_t*> sib_buffer; std::vector<srslte::unique_byte_buffer> sib_buffer;
// user connect notifier // user connect notifier
connect_notifier *cnotifier; connect_notifier *cnotifier;
@ -327,8 +328,8 @@ private:
void configure_mbsfn_sibs(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13); void configure_mbsfn_sibs(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13);
void config_mac(); void config_mac();
void parse_ul_dcch(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *pdu); void parse_ul_dcch(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_ul_ccch(uint16_t rnti, srslte::byte_buffer_t *pdu); void parse_ul_ccch(uint16_t rnti, srslte::unique_byte_buffer pdu);
void configure_security(uint16_t rnti, void configure_security(uint16_t rnti,
uint32_t lcid, uint32_t lcid,
uint8_t *k_rrc_enc, uint8_t *k_rrc_enc,
@ -353,7 +354,7 @@ private:
typedef struct{ typedef struct{
uint16_t rnti; uint16_t rnti;
uint32_t lcid; uint32_t lcid;
srslte::byte_buffer_t* pdu; srslte::unique_byte_buffer pdu;
}rrc_pdu; }rrc_pdu;
const static uint32_t LCID_EXIT = 0xffff0000; const static uint32_t LCID_EXIT = 0xffff0000;

View File

@ -68,9 +68,13 @@ public:
void run_thread(); void run_thread();
// RRC interface // RRC interface
void initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::byte_buffer_t *pdu); void initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::unique_byte_buffer pdu);
void initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::byte_buffer_t *pdu, uint32_t m_tmsi, uint8_t mmec); void initial_ue(uint16_t rnti,
void write_pdu(uint16_t rnti, srslte::byte_buffer_t *pdu); LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause,
srslte::unique_byte_buffer pdu,
uint32_t m_tmsi,
uint8_t mmec);
void write_pdu(uint16_t rnti, srslte::unique_byte_buffer pdu);
bool user_exists(uint16_t rnti); bool user_exists(uint16_t rnti);
bool user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio); bool user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio);
void ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *res); void ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *res);
@ -112,7 +116,7 @@ private:
bool connect_mme(); bool connect_mme();
bool setup_s1(); bool setup_s1();
bool handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu); bool handle_s1ap_rx_pdu(srslte::byte_buffer_t* pdu);
bool handle_initiatingmessage(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg); bool handle_initiatingmessage(LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg);
bool handle_successfuloutcome(LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT *msg); bool handle_successfuloutcome(LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT *msg);
bool handle_unsuccessfuloutcome(LIBLTE_S1AP_UNSUCCESSFULOUTCOME_STRUCT *msg); bool handle_unsuccessfuloutcome(LIBLTE_S1AP_UNSUCCESSFULOUTCOME_STRUCT *msg);
@ -125,8 +129,13 @@ private:
bool handle_s1setupfailure(LIBLTE_S1AP_MESSAGE_S1SETUPFAILURE_STRUCT *msg); bool handle_s1setupfailure(LIBLTE_S1AP_MESSAGE_S1SETUPFAILURE_STRUCT *msg);
bool handle_erabsetuprequest(LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *msg); bool handle_erabsetuprequest(LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *msg);
bool send_initialuemessage(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::byte_buffer_t *pdu, bool has_tmsi, uint32_t m_tmsi=0, uint8_t mmec=0); bool send_initialuemessage(uint16_t rnti,
bool send_ulnastransport(uint16_t rnti, srslte::byte_buffer_t *pdu); LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause,
srslte::unique_byte_buffer pdu,
bool has_tmsi,
uint32_t m_tmsi = 0,
uint8_t mmec = 0);
bool send_ulnastransport(uint16_t rnti, srslte::unique_byte_buffer pdu);
bool send_uectxtreleaserequest(uint16_t rnti, LIBLTE_S1AP_CAUSE_STRUCT *cause); bool send_uectxtreleaserequest(uint16_t rnti, LIBLTE_S1AP_CAUSE_STRUCT *cause);
bool send_uectxtreleasecomplete(uint16_t rnti, uint32_t mme_ue_id, uint32_t enb_ue_id); bool send_uectxtreleasecomplete(uint16_t rnti, uint32_t mme_ue_id, uint32_t enb_ue_id);
bool send_initial_ctxt_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *res_); bool send_initial_ctxt_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *res_);

View File

@ -42,12 +42,12 @@ enb* enb::get_instance(void)
void enb::cleanup(void) void enb::cleanup(void)
{ {
srslte_dft_exit(); srslte_dft_exit();
srslte::byte_buffer_pool::cleanup();
pthread_mutex_lock(&enb_instance_mutex); pthread_mutex_lock(&enb_instance_mutex);
if(NULL != instance) { if(NULL != instance) {
delete instance; delete instance;
instance = NULL; instance = NULL;
} }
srslte::byte_buffer_pool::cleanup(); // pool has to be cleaned after enb is deleted
pthread_mutex_unlock(&enb_instance_mutex); pthread_mutex_unlock(&enb_instance_mutex);
} }

View File

@ -111,7 +111,7 @@ void gtpu::stop()
} }
// gtpu_interface_pdcp // gtpu_interface_pdcp
void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_pool_buffer pdu) void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer pdu)
{ {
gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU, RNTI: 0x%x, LCID: %d, n_bytes=%d", rnti, lcid, pdu->N_bytes); gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU, RNTI: 0x%x, LCID: %d, n_bytes=%d", rnti, lcid, pdu->N_bytes);
gtpu_header_t header; gtpu_header_t header;
@ -191,8 +191,7 @@ void gtpu::rem_user(uint16_t rnti)
void gtpu::run_thread() void gtpu::run_thread()
{ {
unique_pool_buffer pdu(pool); unique_byte_buffer pdu = allocate_unique_buffer(*pool);
pdu.allocate();
if (!pdu.get()) { if (!pdu.get()) {
gtpu_log->error("Fatal Error: Couldn't allocate buffer in gtpu::run_thread().\n"); gtpu_log->error("Fatal Error: Couldn't allocate buffer in gtpu::run_thread().\n");
@ -258,7 +257,7 @@ void gtpu::run_thread()
pdcp->write_sdu(rnti, lcid, std::move(pdu)); pdcp->write_sdu(rnti, lcid, std::move(pdu));
do { do {
pdu.allocate(); pdu = allocate_unique_buffer(*pool);
if (!pdu.get()) { if (!pdu.get()) {
gtpu_log->console("GTPU Buffer pool empty. Trying again...\n"); gtpu_log->console("GTPU Buffer pool empty. Trying again...\n");
usleep(10000); usleep(10000);
@ -275,8 +274,7 @@ void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq)
gtpu_log->info("TX GTPU Echo Response, Seq: %d\n", seq); gtpu_log->info("TX GTPU Echo Response, Seq: %d\n", seq);
gtpu_header_t header; gtpu_header_t header;
unique_pool_buffer pdu(pool); unique_byte_buffer pdu = allocate_unique_buffer(*pool);
pdu.allocate();
//header //header
header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL | GTPU_FLAGS_SEQUENCE; header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL | GTPU_FLAGS_SEQUENCE;
@ -371,7 +369,7 @@ void gtpu::mch_thread::run_thread()
return; return;
} }
unique_pool_buffer pdu(pool); unique_byte_buffer pdu = allocate_unique_buffer(*pool);
int n; int n;
socklen_t addrlen; socklen_t addrlen;
sockaddr_in src_addr; sockaddr_in src_addr;
@ -385,8 +383,6 @@ void gtpu::mch_thread::run_thread()
run_enable = true; run_enable = true;
running=true; running=true;
pdu.allocate();
// Warning: Use mutex here if creating multiple services each with a different thread // Warning: Use mutex here if creating multiple services each with a different thread
uint16_t lcid = lcid_counter; uint16_t lcid = lcid_counter;
lcid_counter++; lcid_counter++;
@ -405,7 +401,7 @@ void gtpu::mch_thread::run_thread()
gtpu_read_header(pdu.get(), &header, gtpu_log); gtpu_read_header(pdu.get(), &header, gtpu_log);
pdcp->write_sdu(SRSLTE_MRNTI, lcid, std::move(pdu)); pdcp->write_sdu(SRSLTE_MRNTI, lcid, std::move(pdu));
do { do {
pdu.allocate(); pdu = allocate_unique_buffer(*pool);
if (!pdu.get()) { if (!pdu.get()) {
gtpu_log->console("GTPU Buffer pool empty. Trying again...\n"); gtpu_log->console("GTPU Buffer pool empty. Trying again...\n");
usleep(10000); usleep(10000);

View File

@ -130,60 +130,58 @@ void pdcp::enable_encryption(uint16_t rnti, uint32_t lcid)
pthread_rwlock_unlock(&rwlock); pthread_rwlock_unlock(&rwlock);
} }
void pdcp::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* sdu) void pdcp::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer sdu)
{ {
pthread_rwlock_rdlock(&rwlock); pthread_rwlock_rdlock(&rwlock);
if (users.count(rnti)) { if (users.count(rnti)) {
users[rnti].pdcp->write_pdu(lcid, sdu); users[rnti].pdcp->write_pdu(lcid, std::move(sdu));
} else {
pool->deallocate(sdu);
} }
pthread_rwlock_unlock(&rwlock); pthread_rwlock_unlock(&rwlock);
} }
void pdcp::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_pool_buffer sdu) void pdcp::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer sdu)
{ {
pthread_rwlock_rdlock(&rwlock); pthread_rwlock_rdlock(&rwlock);
if (users.count(rnti)) { if (users.count(rnti)) {
if(rnti != SRSLTE_MRNTI){ if(rnti != SRSLTE_MRNTI){
users[rnti].pdcp->write_sdu(lcid, sdu); users[rnti].pdcp->write_sdu(lcid, std::move(sdu));
}else { }else {
users[rnti].pdcp->write_sdu_mch(lcid, sdu); users[rnti].pdcp->write_sdu_mch(lcid, std::move(sdu));
} }
} }
pthread_rwlock_unlock(&rwlock); pthread_rwlock_unlock(&rwlock);
} }
void pdcp::user_interface_gtpu::write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) void pdcp::user_interface_gtpu::write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu)
{ {
gtpu->write_pdu(rnti, lcid, pdu); gtpu->write_pdu(rnti, lcid, std::move(pdu));
} }
void pdcp::user_interface_rlc::write_sdu(uint32_t lcid, srslte::byte_buffer_t* sdu, bool blocking) void pdcp::user_interface_rlc::write_sdu(uint32_t lcid, srslte::unique_byte_buffer sdu, bool blocking)
{ {
rlc->write_sdu(rnti, lcid, sdu); rlc->write_sdu(rnti, lcid, std::move(sdu));
} }
bool pdcp::user_interface_rlc::rb_is_um(uint32_t lcid) { bool pdcp::user_interface_rlc::rb_is_um(uint32_t lcid) {
return rlc->rb_is_um(rnti, lcid); return rlc->rb_is_um(rnti, lcid);
} }
void pdcp::user_interface_rrc::write_pdu(uint32_t lcid, srslte::byte_buffer_t* pdu) void pdcp::user_interface_rrc::write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu)
{ {
rrc->write_pdu(rnti, lcid, pdu); rrc->write_pdu(rnti, lcid, std::move(pdu));
} }
void pdcp::user_interface_rrc::write_pdu_bcch_bch(srslte::byte_buffer_t* pdu) void pdcp::user_interface_rrc::write_pdu_bcch_bch(srslte::unique_byte_buffer pdu)
{ {
ERROR("Error: Received BCCH from ue=%d\n", rnti); ERROR("Error: Received BCCH from ue=%d\n", rnti);
} }
void pdcp::user_interface_rrc::write_pdu_bcch_dlsch(srslte::byte_buffer_t* pdu) void pdcp::user_interface_rrc::write_pdu_bcch_dlsch(srslte::unique_byte_buffer pdu)
{ {
ERROR("Error: Received BCCH from ue=%d\n", rnti); ERROR("Error: Received BCCH from ue=%d\n", rnti);
} }
void pdcp::user_interface_rrc::write_pdu_pcch(srslte::byte_buffer_t* pdu) void pdcp::user_interface_rrc::write_pdu_pcch(srslte::unique_byte_buffer pdu)
{ {
ERROR("Error: Received PCCH from ue=%d\n", rnti); ERROR("Error: Received PCCH from ue=%d\n", rnti);
} }

View File

@ -177,18 +177,17 @@ void rlc::read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t *payload)
rrc->read_pdu_bcch_dlsch(sib_index, payload); rrc->read_pdu_bcch_dlsch(sib_index, payload);
} }
void rlc::write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* sdu) void rlc::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer sdu)
{ {
uint32_t tx_queue; uint32_t tx_queue;
pthread_rwlock_rdlock(&rwlock); pthread_rwlock_rdlock(&rwlock);
if (users.count(rnti)) { if (users.count(rnti)) {
if(rnti != SRSLTE_MRNTI){ if(rnti != SRSLTE_MRNTI){
users[rnti].rlc->write_sdu(lcid, sdu, false); users[rnti].rlc->write_sdu(lcid, std::move(sdu), false);
tx_queue = users[rnti].rlc->get_buffer_state(lcid); tx_queue = users[rnti].rlc->get_buffer_state(lcid);
}else { }else {
users[rnti].rlc->write_sdu_mch(lcid, sdu); users[rnti].rlc->write_sdu_mch(lcid, std::move(sdu));
tx_queue = users[rnti].rlc->get_total_mch_buffer_state(lcid); tx_queue = users[rnti].rlc->get_total_mch_buffer_state(lcid);
} }
// In the eNodeB, there is no polling for buffer state from the scheduler, thus // In the eNodeB, there is no polling for buffer state from the scheduler, thus
@ -197,8 +196,6 @@ void rlc::write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* sdu)
uint32_t retx_queue = 0; uint32_t retx_queue = 0;
mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue);
log_h->info("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d\n", rnti, lcid, tx_queue); log_h->info("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d\n", rnti, lcid, tx_queue);
} else {
pool->deallocate(sdu);
} }
pthread_rwlock_unlock(&rwlock); pthread_rwlock_unlock(&rwlock);
} }
@ -218,22 +215,22 @@ void rlc::user_interface::max_retx_attempted()
rrc->max_retx_attempted(rnti); rrc->max_retx_attempted(rnti);
} }
void rlc::user_interface::write_pdu(uint32_t lcid, srslte::byte_buffer_t* sdu) void rlc::user_interface::write_pdu(uint32_t lcid, srslte::unique_byte_buffer sdu)
{ {
pdcp->write_pdu(rnti, lcid, sdu); pdcp->write_pdu(rnti, lcid, std::move(sdu));
} }
void rlc::user_interface::write_pdu_bcch_bch(srslte::byte_buffer_t* sdu) void rlc::user_interface::write_pdu_bcch_bch(srslte::unique_byte_buffer sdu)
{ {
ERROR("Error: Received BCCH from ue=%d\n", rnti); ERROR("Error: Received BCCH from ue=%d\n", rnti);
} }
void rlc::user_interface::write_pdu_bcch_dlsch(srslte::byte_buffer_t* sdu) void rlc::user_interface::write_pdu_bcch_dlsch(srslte::unique_byte_buffer sdu)
{ {
ERROR("Error: Received BCCH from ue=%d\n", rnti); ERROR("Error: Received BCCH from ue=%d\n", rnti);
} }
void rlc::user_interface::write_pdu_pcch(srslte::byte_buffer_t* sdu) void rlc::user_interface::write_pdu_pcch(srslte::unique_byte_buffer sdu)
{ {
ERROR("Error: Received PCCH from ue=%d\n", rnti); ERROR("Error: Received PCCH from ue=%d\n", rnti);
} }

View File

@ -86,7 +86,7 @@ void rrc::stop()
if(running) { if(running) {
running = false; running = false;
rrc_pdu p = {0, LCID_EXIT, NULL}; rrc_pdu p = {0, LCID_EXIT, NULL};
rx_pdu_queue.push(p); rx_pdu_queue.push(std::move(p));
wait_thread_finish(); wait_thread_finish();
} }
act_monitor.stop(); act_monitor.stop();
@ -136,19 +136,19 @@ void rrc::read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t* payload)
void rrc::rl_failure(uint16_t rnti) void rrc::rl_failure(uint16_t rnti)
{ {
rrc_pdu p = {rnti, LCID_RLF_USER, NULL}; rrc_pdu p = {rnti, LCID_RLF_USER, NULL};
rx_pdu_queue.push(p); rx_pdu_queue.push(std::move(p));
} }
void rrc::set_activity_user(uint16_t rnti) void rrc::set_activity_user(uint16_t rnti)
{ {
rrc_pdu p = {rnti, LCID_ACT_USER, NULL}; rrc_pdu p = {rnti, LCID_ACT_USER, NULL};
rx_pdu_queue.push(p); rx_pdu_queue.push(std::move(p));
} }
void rrc::rem_user_thread(uint16_t rnti) void rrc::rem_user_thread(uint16_t rnti)
{ {
rrc_pdu p = {rnti, LCID_REM_USER, NULL}; rrc_pdu p = {rnti, LCID_REM_USER, NULL};
rx_pdu_queue.push(p); rx_pdu_queue.push(std::move(p));
} }
uint32_t rrc::get_nof_users() { uint32_t rrc::get_nof_users() {
@ -223,7 +223,7 @@ void rrc::upd_user(uint16_t new_rnti, uint16_t old_rnti)
pthread_mutex_lock(&user_mutex); pthread_mutex_lock(&user_mutex);
if (users.count(old_rnti) == 1) { if (users.count(old_rnti) == 1) {
if (users[old_rnti].is_connected()) { if (users[old_rnti].is_connected()) {
users[old_rnti].send_connection_reconf_upd(pool_allocate); users[old_rnti].send_connection_reconf_upd(srslte::allocate_unique_buffer(*pool));
} else { } else {
users[old_rnti].send_connection_release(); users[old_rnti].send_connection_release();
} }
@ -236,16 +236,16 @@ void rrc::upd_user(uint16_t new_rnti, uint16_t old_rnti)
/******************************************************************************* /*******************************************************************************
PDCP interface PDCP interface
*******************************************************************************/ *******************************************************************************/
void rrc::write_pdu(uint16_t rnti, uint32_t lcid, byte_buffer_t* pdu) void rrc::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer pdu)
{ {
rrc_pdu p = {rnti, lcid, pdu}; rrc_pdu p = {rnti, lcid, std::move(pdu)};
rx_pdu_queue.push(p); rx_pdu_queue.push(std::move(p));
} }
/******************************************************************************* /*******************************************************************************
S1AP interface S1AP interface
*******************************************************************************/ *******************************************************************************/
void rrc::write_dl_info(uint16_t rnti, byte_buffer_t* sdu) void rrc::write_dl_info(uint16_t rnti, srslte::unique_byte_buffer sdu)
{ {
dl_dcch_msg_s dl_dcch_msg; dl_dcch_msg_s dl_dcch_msg;
dl_dcch_msg.msg.set_c1(); dl_dcch_msg.msg.set_c1();
@ -265,7 +265,7 @@ void rrc::write_dl_info(uint16_t rnti, byte_buffer_t* sdu)
sdu->reset(); sdu->reset();
users[rnti].send_dl_dcch(&dl_dcch_msg, sdu); users[rnti].send_dl_dcch(&dl_dcch_msg, std::move(sdu));
} else { } else {
rrc_log->error("Rx SDU for unknown rnti=0x%x\n", rnti); rrc_log->error("Rx SDU for unknown rnti=0x%x\n", rnti);
} }
@ -275,7 +275,7 @@ void rrc::write_dl_info(uint16_t rnti, byte_buffer_t* sdu)
void rrc::release_complete(uint16_t rnti) { void rrc::release_complete(uint16_t rnti) {
rrc_pdu p = {rnti, LCID_REL_USER, NULL}; rrc_pdu p = {rnti, LCID_REL_USER, NULL};
rx_pdu_queue.push(p); rx_pdu_queue.push(std::move(p));
} }
bool rrc::setup_ue_ctxt(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg) bool rrc::setup_ue_ctxt(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg)
@ -517,7 +517,7 @@ void rrc::read_pdu_pcch(uint8_t* payload, uint32_t buffer_size)
from either a public function or the internal thread from either a public function or the internal thread
*******************************************************************************/ *******************************************************************************/
void rrc::parse_ul_ccch(uint16_t rnti, byte_buffer_t *pdu) void rrc::parse_ul_ccch(uint16_t rnti, srslte::unique_byte_buffer pdu)
{ {
uint16_t old_rnti = 0; uint16_t old_rnti = 0;
@ -527,10 +527,10 @@ void rrc::parse_ul_ccch(uint16_t rnti, byte_buffer_t *pdu)
if (ul_ccch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or if (ul_ccch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or
ul_ccch_msg.msg.type().value != ul_ccch_msg_type_c::types_opts::c1) { ul_ccch_msg.msg.type().value != ul_ccch_msg_type_c::types_opts::c1) {
rrc_log->error("Failed to unpack UL-CCCH message\n"); rrc_log->error("Failed to unpack UL-CCCH message\n");
goto exit; return;
} }
log_rrc_message("SRB0", Rx, pdu, ul_ccch_msg); log_rrc_message("SRB0", Rx, pdu.get(), ul_ccch_msg);
switch (ul_ccch_msg.msg.c1().type()) { switch (ul_ccch_msg.msg.c1().type()) {
case ul_ccch_msg_type_c::c1_c_::types::rrc_conn_request: case ul_ccch_msg_type_c::c1_c_::types::rrc_conn_request:
@ -580,17 +580,14 @@ void rrc::parse_ul_ccch(uint16_t rnti, byte_buffer_t *pdu)
rrc_log->error("UL CCCH message not recognised\n"); rrc_log->error("UL CCCH message not recognised\n");
break; break;
} }
exit:
pool->deallocate(pdu);
} }
} }
void rrc::parse_ul_dcch(uint16_t rnti, uint32_t lcid, byte_buffer_t *pdu) void rrc::parse_ul_dcch(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer pdu)
{ {
if (pdu) { if (pdu) {
if (users.count(rnti)) { if (users.count(rnti)) {
users[rnti].parse_ul_dcch(lcid, pdu); users[rnti].parse_ul_dcch(lcid, std::move(pdu));
} else { } else {
rrc_log->error("Processing %s: Unknown rnti=0x%x\n", rb_id_text[lcid], rnti); rrc_log->error("Processing %s: Unknown rnti=0x%x\n", rb_id_text[lcid], rnti);
} }
@ -729,15 +726,15 @@ uint32_t rrc::generate_sibs()
// Pack payload for all messages // Pack payload for all messages
for (uint32_t msg_index = 0; msg_index < nof_messages; msg_index++) { for (uint32_t msg_index = 0; msg_index < nof_messages; msg_index++) {
srslte::byte_buffer_t* sib = pool_allocate; srslte::unique_byte_buffer sib = srslte::allocate_unique_buffer(*pool);
asn1::bit_ref bref(sib->msg, sib->get_tailroom()); asn1::bit_ref bref(sib->msg, sib->get_tailroom());
asn1::bit_ref bref0 = bref; asn1::bit_ref bref0 = bref;
msg[msg_index].pack(bref); msg[msg_index].pack(bref);
sib->N_bytes = static_cast<uint32_t>((bref.distance(bref0) - 1) / 8 + 1); sib->N_bytes = static_cast<uint32_t>((bref.distance(bref0) - 1) / 8 + 1);
sib_buffer.push_back(sib); sib_buffer.push_back(std::move(sib));
// Log SIBs in JSON format // Log SIBs in JSON format
log_rrc_message("SIB payload", Tx, sib_buffer[msg_index], msg[msg_index]); log_rrc_message("SIB payload", Tx, sib_buffer[msg_index].get(), msg[msg_index]);
} }
return nof_messages; return nof_messages;
@ -829,11 +826,11 @@ void rrc::run_thread()
switch(p.lcid) switch(p.lcid)
{ {
case RB_ID_SRB0: case RB_ID_SRB0:
parse_ul_ccch(p.rnti, p.pdu); parse_ul_ccch(p.rnti, std::move(p.pdu));
break; break;
case RB_ID_SRB1: case RB_ID_SRB1:
case RB_ID_SRB2: case RB_ID_SRB2:
parse_ul_dcch(p.rnti, p.lcid, p.pdu); parse_ul_dcch(p.rnti, p.lcid, std::move(p.pdu));
break; break;
case LCID_REM_USER: case LCID_REM_USER:
rem_user(p.rnti); rem_user(p.rnti);
@ -1035,7 +1032,7 @@ bool rrc::ue::is_timeout()
return false; return false;
} }
void rrc::ue::parse_ul_dcch(uint32_t lcid, byte_buffer_t *pdu) void rrc::ue::parse_ul_dcch(uint32_t lcid, srslte::unique_byte_buffer pdu)
{ {
set_activity(); set_activity();
@ -1044,19 +1041,19 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, byte_buffer_t *pdu)
if (ul_dcch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or if (ul_dcch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or
ul_dcch_msg.msg.type().value != ul_dcch_msg_type_c::types_opts::c1) { ul_dcch_msg.msg.type().value != ul_dcch_msg_type_c::types_opts::c1) {
parent->rrc_log->error("Failed to unpack UL-DCCH message\n"); parent->rrc_log->error("Failed to unpack UL-DCCH message\n");
pool->deallocate(pdu);
return; return;
} }
parent->log_rrc_message(rb_id_text[lcid], Rx, pdu, ul_dcch_msg); parent->log_rrc_message(rb_id_text[lcid], Rx, pdu.get(), ul_dcch_msg);
pdu->reset(); // reuse PDU
pdu->reset(); // FIXME: name collision with byte_buffer reset
transaction_id = 0; transaction_id = 0;
switch (ul_dcch_msg.msg.c1().type()) { switch (ul_dcch_msg.msg.c1().type()) {
case ul_dcch_msg_type_c::c1_c_::types::rrc_conn_setup_complete: case ul_dcch_msg_type_c::c1_c_::types::rrc_conn_setup_complete:
handle_rrc_con_setup_complete(&ul_dcch_msg.msg.c1().rrc_conn_setup_complete(), pdu); handle_rrc_con_setup_complete(&ul_dcch_msg.msg.c1().rrc_conn_setup_complete(), std::move(pdu));
break; break;
case ul_dcch_msg_type_c::c1_c_::types::ul_info_transfer: case ul_dcch_msg_type_c::c1_c_::types::ul_info_transfer:
pdu->N_bytes = ul_dcch_msg.msg.c1() pdu->N_bytes = ul_dcch_msg.msg.c1()
@ -1073,10 +1070,10 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, byte_buffer_t *pdu)
.ded_info_type.ded_info_nas() .ded_info_type.ded_info_nas()
.data(), .data(),
pdu->N_bytes); pdu->N_bytes);
parent->s1ap->write_pdu(rnti, pdu); parent->s1ap->write_pdu(rnti, std::move(pdu));
break; break;
case ul_dcch_msg_type_c::c1_c_::types::rrc_conn_recfg_complete: case ul_dcch_msg_type_c::c1_c_::types::rrc_conn_recfg_complete:
handle_rrc_reconf_complete(&ul_dcch_msg.msg.c1().rrc_conn_recfg_complete(), pdu); handle_rrc_reconf_complete(&ul_dcch_msg.msg.c1().rrc_conn_recfg_complete(), std::move(pdu));
parent->rrc_log->console("User 0x%x connected\n", rnti); parent->rrc_log->console("User 0x%x connected\n", rnti);
state = RRC_STATE_REGISTERED; state = RRC_STATE_REGISTERED;
break; break;
@ -1085,7 +1082,7 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, byte_buffer_t *pdu)
// Skipping send_ue_cap_enquiry() procedure for now // Skipping send_ue_cap_enquiry() procedure for now
// state = RRC_STATE_WAIT_FOR_UE_CAP_INFO; // state = RRC_STATE_WAIT_FOR_UE_CAP_INFO;
notify_s1ap_ue_ctxt_setup_complete(); notify_s1ap_ue_ctxt_setup_complete();
send_connection_reconf(pdu); send_connection_reconf(std::move(pdu));
state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE; state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE;
break; break;
case ul_dcch_msg_type_c::c1_c_::types::security_mode_fail: case ul_dcch_msg_type_c::c1_c_::types::security_mode_fail:
@ -1093,7 +1090,7 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, byte_buffer_t *pdu)
break; break;
case ul_dcch_msg_type_c::c1_c_::types::ue_cap_info: case ul_dcch_msg_type_c::c1_c_::types::ue_cap_info:
if (handle_ue_cap_info(&ul_dcch_msg.msg.c1().ue_cap_info())) { if (handle_ue_cap_info(&ul_dcch_msg.msg.c1().ue_cap_info())) {
send_connection_reconf(pdu); send_connection_reconf(std::move(pdu));
state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE; state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE;
} else { } else {
send_connection_reject(); send_connection_reject();
@ -1133,7 +1130,7 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_r8_ies_s* msg)
} }
void rrc::ue::handle_rrc_con_setup_complete(rrc_conn_setup_complete_s* msg, srslte::byte_buffer_t* pdu) void rrc::ue::handle_rrc_con_setup_complete(rrc_conn_setup_complete_s* msg, srslte::unique_byte_buffer pdu)
{ {
parent->rrc_log->info("RRCConnectionSetupComplete transaction ID: %d\n", msg->rrc_transaction_id); parent->rrc_log->info("RRCConnectionSetupComplete transaction ID: %d\n", msg->rrc_transaction_id);
rrc_conn_setup_complete_r8_ies_s* msg_r8 = &msg->crit_exts.c1().rrc_conn_setup_complete_r8(); rrc_conn_setup_complete_r8_ies_s* msg_r8 = &msg->crit_exts.c1().rrc_conn_setup_complete_r8();
@ -1148,15 +1145,15 @@ void rrc::ue::handle_rrc_con_setup_complete(rrc_conn_setup_complete_s* msg, srsl
parent->mac->phy_config_enabled(rnti, true); parent->mac->phy_config_enabled(rnti, true);
if(has_tmsi) { if(has_tmsi) {
parent->s1ap->initial_ue(rnti, (LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM)establishment_cause.value, pdu, m_tmsi, parent->s1ap->initial_ue(
mmec); rnti, (LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM)establishment_cause.value, std::move(pdu), m_tmsi, mmec);
} else { } else {
parent->s1ap->initial_ue(rnti, (LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM)establishment_cause.value, pdu); parent->s1ap->initial_ue(rnti, (LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM)establishment_cause.value, std::move(pdu));
} }
state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE; state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE;
} }
void rrc::ue::handle_rrc_reconf_complete(rrc_conn_recfg_complete_s* msg, srslte::byte_buffer_t* pdu) void rrc::ue::handle_rrc_reconf_complete(rrc_conn_recfg_complete_s* msg, srslte::unique_byte_buffer pdu)
{ {
parent->rrc_log->info("RRCReconfigurationComplete transaction ID: %d\n", msg->rrc_transaction_id); parent->rrc_log->info("RRCReconfigurationComplete transaction ID: %d\n", msg->rrc_transaction_id);
@ -1602,7 +1599,7 @@ int rrc::ue::get_drbid_config(drb_to_add_mod_s* drb, int drb_id)
return 0; return 0;
} }
void rrc::ue::send_connection_reconf_upd(srslte::byte_buffer_t *pdu) void rrc::ue::send_connection_reconf_upd(srslte::unique_byte_buffer pdu)
{ {
dl_dcch_msg_s dl_dcch_msg; dl_dcch_msg_s dl_dcch_msg;
rrc_conn_recfg_s* rrc_conn_recfg = &dl_dcch_msg.msg.set_c1().set_rrc_conn_recfg(); rrc_conn_recfg_s* rrc_conn_recfg = &dl_dcch_msg.msg.set_c1().set_rrc_conn_recfg();
@ -1647,13 +1644,13 @@ void rrc::ue::send_connection_reconf_upd(srslte::byte_buffer_t *pdu)
pdu->reset(); pdu->reset();
send_dl_dcch(&dl_dcch_msg, pdu); send_dl_dcch(&dl_dcch_msg, std::move(pdu));
state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE; state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE;
} }
void rrc::ue::send_connection_reconf(srslte::byte_buffer_t *pdu) void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer pdu)
{ {
dl_dcch_msg_s dl_dcch_msg; dl_dcch_msg_s dl_dcch_msg;
dl_dcch_msg.msg.set_c1().set_rrc_conn_recfg().crit_exts.set_c1().set_rrc_conn_recfg_r8(); dl_dcch_msg.msg.set_c1().set_rrc_conn_recfg().crit_exts.set_c1().set_rrc_conn_recfg_r8();
@ -1781,14 +1778,14 @@ void rrc::ue::send_connection_reconf(srslte::byte_buffer_t *pdu)
// Reuse same PDU // Reuse same PDU
pdu->reset(); pdu->reset();
send_dl_dcch(&dl_dcch_msg, pdu); send_dl_dcch(&dl_dcch_msg, std::move(pdu));
state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE; state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE;
} }
void rrc::ue::send_connection_reconf_new_bearer(LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT *e) void rrc::ue::send_connection_reconf_new_bearer(LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT *e)
{ {
srslte::byte_buffer_t *pdu = pool_allocate; srslte::unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool);
dl_dcch_msg_s dl_dcch_msg; dl_dcch_msg_s dl_dcch_msg;
dl_dcch_msg.msg.set_c1().set_rrc_conn_recfg().crit_exts.set_c1().set_rrc_conn_recfg_r8(); dl_dcch_msg.msg.set_c1().set_rrc_conn_recfg().crit_exts.set_c1().set_rrc_conn_recfg_r8();
@ -1835,7 +1832,7 @@ void rrc::ue::send_connection_reconf_new_bearer(LIBLTE_S1AP_E_RABTOBESETUPLISTBE
conn_reconf->rr_cfg_ded.drb_to_add_mod_list_present = conn_reconf->rr_cfg_ded.drb_to_add_mod_list.size() > 0; conn_reconf->rr_cfg_ded.drb_to_add_mod_list_present = conn_reconf->rr_cfg_ded.drb_to_add_mod_list.size() > 0;
conn_reconf->ded_info_nas_list_present = conn_reconf->ded_info_nas_list.size() > 0; conn_reconf->ded_info_nas_list_present = conn_reconf->ded_info_nas_list.size() > 0;
send_dl_dcch(&dl_dcch_msg, pdu); send_dl_dcch(&dl_dcch_msg, std::move(pdu));
} }
void rrc::ue::send_security_mode_command() void rrc::ue::send_security_mode_command()
@ -1975,7 +1972,7 @@ bool rrc::ue::select_security_algorithms()
void rrc::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg) void rrc::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg)
{ {
// Allocate a new PDU buffer, pack the message and send to PDCP // Allocate a new PDU buffer, pack the message and send to PDCP
byte_buffer_t* pdu = pool_allocate_blocking; srslte::unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool);
if (pdu) { if (pdu) {
asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); asn1::bit_ref bref(pdu->msg, pdu->get_tailroom());
dl_ccch_msg->pack(bref); dl_ccch_msg->pack(bref);
@ -1983,18 +1980,18 @@ void rrc::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg)
char buf[32]; char buf[32];
sprintf(buf, "SRB0 - rnti=0x%x", rnti); sprintf(buf, "SRB0 - rnti=0x%x", rnti);
parent->log_rrc_message(buf, Tx, pdu, *dl_ccch_msg); parent->log_rrc_message(buf, Tx, pdu.get(), *dl_ccch_msg);
parent->pdcp->write_sdu(rnti, RB_ID_SRB0, pdu); parent->pdcp->write_sdu(rnti, RB_ID_SRB0, std::move(pdu));
} else { } else {
parent->rrc_log->error("Allocating pdu\n"); parent->rrc_log->error("Allocating pdu\n");
} }
} }
void rrc::ue::send_dl_dcch(dl_dcch_msg_s* dl_dcch_msg, byte_buffer_t* pdu) void rrc::ue::send_dl_dcch(dl_dcch_msg_s* dl_dcch_msg, srslte::unique_byte_buffer pdu)
{ {
if (!pdu) { if (!pdu) {
pdu = pool_allocate_blocking; pdu = srslte::allocate_unique_buffer(*pool);
} }
if (pdu) { if (pdu) {
asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); asn1::bit_ref bref(pdu->msg, pdu->get_tailroom());
@ -2003,9 +2000,9 @@ void rrc::ue::send_dl_dcch(dl_dcch_msg_s* dl_dcch_msg, byte_buffer_t* pdu)
char buf[32]; char buf[32];
sprintf(buf, "SRB1 - rnti=0x%x", rnti); sprintf(buf, "SRB1 - rnti=0x%x", rnti);
parent->log_rrc_message(buf, Tx, pdu, *dl_dcch_msg); parent->log_rrc_message(buf, Tx, pdu.get(), *dl_dcch_msg);
parent->pdcp->write_sdu(rnti, RB_ID_SRB1, pdu); parent->pdcp->write_sdu(rnti, RB_ID_SRB1, std::move(pdu));
} else { } else {
parent->rrc_log->error("Allocating pdu\n"); parent->rrc_log->error("Allocating pdu\n");

View File

@ -87,7 +87,7 @@ void s1ap::get_metrics(s1ap_metrics_t &m)
void s1ap::run_thread() void s1ap::run_thread()
{ {
srslte::byte_buffer_t *pdu = pool->allocate("s1ap::run_thread"); srslte::unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, "s1ap::run_thread");
if (!pdu) { if (!pdu) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n"); s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n");
return; return;
@ -131,7 +131,7 @@ void s1ap::run_thread()
} }
s1ap_log->info_hex(pdu->msg, pdu->N_bytes, "Received S1AP PDU"); s1ap_log->info_hex(pdu->msg, pdu->N_bytes, "Received S1AP PDU");
handle_s1ap_rx_pdu(pdu); handle_s1ap_rx_pdu(pdu.get());
} }
} }
@ -174,25 +174,29 @@ void s1ap::build_tai_cgi()
/******************************************************************************* /*******************************************************************************
/* RRC interface /* RRC interface
********************************************************************************/ ********************************************************************************/
void s1ap::initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::byte_buffer_t *pdu) void s1ap::initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::unique_byte_buffer pdu)
{ {
ue_ctxt_map[rnti].eNB_UE_S1AP_ID = next_eNB_UE_S1AP_ID++; ue_ctxt_map[rnti].eNB_UE_S1AP_ID = next_eNB_UE_S1AP_ID++;
ue_ctxt_map[rnti].stream_id = 1; ue_ctxt_map[rnti].stream_id = 1;
ue_ctxt_map[rnti].release_requested = false; ue_ctxt_map[rnti].release_requested = false;
enbid_to_rnti_map[ue_ctxt_map[rnti].eNB_UE_S1AP_ID] = rnti; enbid_to_rnti_map[ue_ctxt_map[rnti].eNB_UE_S1AP_ID] = rnti;
send_initialuemessage(rnti, cause, pdu, false); send_initialuemessage(rnti, cause, std::move(pdu), false);
} }
void s1ap::initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::byte_buffer_t *pdu, uint32_t m_tmsi, uint8_t mmec) void s1ap::initial_ue(uint16_t rnti,
LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause,
srslte::unique_byte_buffer pdu,
uint32_t m_tmsi,
uint8_t mmec)
{ {
ue_ctxt_map[rnti].eNB_UE_S1AP_ID = next_eNB_UE_S1AP_ID++; ue_ctxt_map[rnti].eNB_UE_S1AP_ID = next_eNB_UE_S1AP_ID++;
ue_ctxt_map[rnti].stream_id = 1; ue_ctxt_map[rnti].stream_id = 1;
ue_ctxt_map[rnti].release_requested = false; ue_ctxt_map[rnti].release_requested = false;
enbid_to_rnti_map[ue_ctxt_map[rnti].eNB_UE_S1AP_ID] = rnti; enbid_to_rnti_map[ue_ctxt_map[rnti].eNB_UE_S1AP_ID] = rnti;
send_initialuemessage(rnti, cause, pdu, true, m_tmsi, mmec); send_initialuemessage(rnti, cause, std::move(pdu), true, m_tmsi, mmec);
} }
void s1ap::write_pdu(uint16_t rnti, srslte::byte_buffer_t *pdu) void s1ap::write_pdu(uint16_t rnti, srslte::unique_byte_buffer pdu)
{ {
s1ap_log->info_hex(pdu->msg, pdu->N_bytes, "Received RRC SDU"); s1ap_log->info_hex(pdu->msg, pdu->N_bytes, "Received RRC SDU");
@ -201,7 +205,7 @@ void s1ap::write_pdu(uint16_t rnti, srslte::byte_buffer_t *pdu)
return; return;
} }
send_ulnastransport(rnti, pdu); send_ulnastransport(rnti, std::move(pdu));
} }
bool s1ap::user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio) bool s1ap::user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio)
@ -382,7 +386,7 @@ bool s1ap::setup_s1()
/* S1AP message handlers /* S1AP message handlers
********************************************************************************/ ********************************************************************************/
bool s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu) bool s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t* pdu)
{ {
LIBLTE_S1AP_S1AP_PDU_STRUCT rx_pdu; LIBLTE_S1AP_S1AP_PDU_STRUCT rx_pdu;
@ -394,13 +398,10 @@ bool s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu)
switch(rx_pdu.choice_type) { switch(rx_pdu.choice_type) {
case LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE: case LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE:
return handle_initiatingmessage(&rx_pdu.choice.initiatingMessage); return handle_initiatingmessage(&rx_pdu.choice.initiatingMessage);
break;
case LIBLTE_S1AP_S1AP_PDU_CHOICE_SUCCESSFULOUTCOME: case LIBLTE_S1AP_S1AP_PDU_CHOICE_SUCCESSFULOUTCOME:
return handle_successfuloutcome(&rx_pdu.choice.successfulOutcome); return handle_successfuloutcome(&rx_pdu.choice.successfulOutcome);
break;
case LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME: case LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME:
return handle_unsuccessfuloutcome(&rx_pdu.choice.unsuccessfulOutcome); return handle_unsuccessfuloutcome(&rx_pdu.choice.unsuccessfulOutcome);
break;
default: default:
s1ap_log->error("Unhandled PDU type %d\n", rx_pdu.choice_type); s1ap_log->error("Unhandled PDU type %d\n", rx_pdu.choice_type);
return false; return false;
@ -478,11 +479,11 @@ bool s1ap::handle_dlnastransport(LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT
s1ap_log->warning("Not handling SubscriberProfileIDforRFP\n"); s1ap_log->warning("Not handling SubscriberProfileIDforRFP\n");
} }
srslte::byte_buffer_t *pdu = pool_allocate; srslte::unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool);
if (pdu) { if (pdu) {
memcpy(pdu->msg, msg->NAS_PDU.buffer, msg->NAS_PDU.n_octets); memcpy(pdu->msg, msg->NAS_PDU.buffer, msg->NAS_PDU.n_octets);
pdu->N_bytes = msg->NAS_PDU.n_octets; pdu->N_bytes = msg->NAS_PDU.n_octets;
rrc->write_dl_info(rnti, pdu); rrc->write_dl_info(rnti, std::move(pdu));
return true; return true;
} else { } else {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n"); s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n");
@ -617,7 +618,12 @@ bool s1ap::handle_s1setupfailure(LIBLTE_S1AP_MESSAGE_S1SETUPFAILURE_STRUCT *msg)
/* S1AP message senders /* S1AP message senders
********************************************************************************/ ********************************************************************************/
bool s1ap::send_initialuemessage(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::byte_buffer_t *pdu, bool has_tmsi, uint32_t m_tmsi, uint8_t mmec) bool s1ap::send_initialuemessage(uint16_t rnti,
LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause,
srslte::unique_byte_buffer pdu,
bool has_tmsi,
uint32_t m_tmsi,
uint8_t mmec)
{ {
if(!mme_connected) { if(!mme_connected) {
return false; return false;
@ -686,7 +692,7 @@ bool s1ap::send_initialuemessage(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CA
return true; return true;
} }
bool s1ap::send_ulnastransport(uint16_t rnti, srslte::byte_buffer_t *pdu) bool s1ap::send_ulnastransport(uint16_t rnti, srslte::unique_byte_buffer pdu)
{ {
if(!mme_connected) { if(!mme_connected) {
return false; return false;
@ -819,7 +825,7 @@ bool s1ap::send_initial_ctxt_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_I
if(!mme_connected) { if(!mme_connected) {
return false; return false;
} }
srslte::byte_buffer_t *buf = pool_allocate; srslte::unique_byte_buffer buf = srslte::allocate_unique_buffer(*pool);
if (!buf) { if (!buf) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_response().\n"); s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_response().\n");
return false; return false;
@ -851,15 +857,13 @@ bool s1ap::send_initial_ctxt_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_I
res->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ctxt_map[rnti].MME_UE_S1AP_ID; res->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ctxt_map[rnti].MME_UE_S1AP_ID;
res->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctxt_map[rnti].eNB_UE_S1AP_ID; res->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctxt_map[rnti].eNB_UE_S1AP_ID;
liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT*)buf); liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT*)buf.get());
s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending InitialContextSetupResponse for RNTI:0x%x", rnti); s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending InitialContextSetupResponse for RNTI:0x%x", rnti);
ssize_t n_sent = sctp_sendmsg(socket_fd, buf->msg, buf->N_bytes, ssize_t n_sent = sctp_sendmsg(socket_fd, buf->msg, buf->N_bytes,
(struct sockaddr*)&mme_addr, sizeof(struct sockaddr_in), (struct sockaddr*)&mme_addr, sizeof(struct sockaddr_in),
htonl(PPID), 0, ue_ctxt_map[rnti].stream_id, 0, 0); htonl(PPID), 0, ue_ctxt_map[rnti].stream_id, 0, 0);
pool->deallocate(buf);
if(n_sent == -1) { if(n_sent == -1) {
s1ap_log->error("Failed to send InitialContextSetupResponse for RNTI:0x%x\n", rnti); s1ap_log->error("Failed to send InitialContextSetupResponse for RNTI:0x%x\n", rnti);
return false; return false;
@ -873,7 +877,7 @@ bool s1ap::send_erab_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETU
if(!mme_connected) { if(!mme_connected) {
return false; return false;
} }
srslte::byte_buffer_t *buf = pool_allocate; srslte::unique_byte_buffer buf = srslte::allocate_unique_buffer(*pool);
if (!buf) { if (!buf) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_erab_setup_response().\n"); s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_erab_setup_response().\n");
return false; return false;
@ -905,15 +909,13 @@ bool s1ap::send_erab_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETU
res->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ctxt_map[rnti].MME_UE_S1AP_ID; res->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ctxt_map[rnti].MME_UE_S1AP_ID;
res->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctxt_map[rnti].eNB_UE_S1AP_ID; res->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctxt_map[rnti].eNB_UE_S1AP_ID;
liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT*)buf); liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT*)buf.get());
s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending E_RABSetupResponse for RNTI:0x%x", rnti); s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending E_RABSetupResponse for RNTI:0x%x", rnti);
ssize_t n_sent = sctp_sendmsg(socket_fd, buf->msg, buf->N_bytes, ssize_t n_sent = sctp_sendmsg(socket_fd, buf->msg, buf->N_bytes,
(struct sockaddr*)&mme_addr, sizeof(struct sockaddr_in), (struct sockaddr*)&mme_addr, sizeof(struct sockaddr_in),
htonl(PPID), 0, ue_ctxt_map[rnti].stream_id, 0, 0); htonl(PPID), 0, ue_ctxt_map[rnti].stream_id, 0, 0);
pool->deallocate(buf);
if(n_sent == -1) { if(n_sent == -1) {
s1ap_log->error("Failed to send E_RABSetupResponse for RNTI:0x%x\n", rnti); s1ap_log->error("Failed to send E_RABSetupResponse for RNTI:0x%x\n", rnti);
return false; return false;
@ -927,7 +929,7 @@ bool s1ap::send_initial_ctxt_setup_failure(uint16_t rnti)
if(!mme_connected) { if(!mme_connected) {
return false; return false;
} }
srslte::byte_buffer_t *buf = pool_allocate; srslte::unique_byte_buffer buf = srslte::allocate_unique_buffer(*pool);
if (!buf) { if (!buf) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_failure().\n"); s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_failure().\n");
return false; return false;
@ -953,15 +955,13 @@ bool s1ap::send_initial_ctxt_setup_failure(uint16_t rnti)
fail->Cause.choice.radioNetwork.ext = false; fail->Cause.choice.radioNetwork.ext = false;
fail->Cause.choice.radioNetwork.e = LIBLTE_S1AP_CAUSERADIONETWORK_UNSPECIFIED; fail->Cause.choice.radioNetwork.e = LIBLTE_S1AP_CAUSERADIONETWORK_UNSPECIFIED;
liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT*)buf); liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT*)buf.get());
s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending InitialContextSetupFailure for RNTI:0x%x", rnti); s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending InitialContextSetupFailure for RNTI:0x%x", rnti);
ssize_t n_sent = sctp_sendmsg(socket_fd, buf->msg, buf->N_bytes, ssize_t n_sent = sctp_sendmsg(socket_fd, buf->msg, buf->N_bytes,
(struct sockaddr*)&mme_addr, sizeof(struct sockaddr_in), (struct sockaddr*)&mme_addr, sizeof(struct sockaddr_in),
htonl(PPID), 0, ue_ctxt_map[rnti].stream_id, 0, 0); htonl(PPID), 0, ue_ctxt_map[rnti].stream_id, 0, 0);
pool->deallocate(buf);
if(n_sent == -1) { if(n_sent == -1) {
s1ap_log->error("Failed to send UplinkNASTransport for RNTI:0x%x\n", rnti); s1ap_log->error("Failed to send UplinkNASTransport for RNTI:0x%x\n", rnti);
return false; return false;

View File

@ -49,8 +49,8 @@ public:
void set_tundevname(const std::string & devname); void set_tundevname(const std::string & devname);
// PDCP interface // PDCP interface
void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu); void write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu);
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *pdu); void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer pdu);
// NAS interface // NAS interface
srslte::error_t setup_if_addr(uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char *err_str); srslte::error_t setup_if_addr(uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char *err_str);

View File

@ -82,7 +82,7 @@ public:
// RRC interface // RRC interface
void paging(asn1::rrc::s_tmsi_s* ue_identiy); void paging(asn1::rrc::s_tmsi_s* ue_identiy);
void set_barring(barring_t barring); void set_barring(barring_t barring);
void write_pdu(uint32_t lcid, unique_pool_buffer pdu); void write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu);
uint32_t get_k_enb_count(); uint32_t get_k_enb_count();
bool is_attached(); bool is_attached();
bool get_k_asme(uint8_t *k_asme_, uint32_t n); bool get_k_asme(uint8_t *k_asme_, uint32_t n);
@ -161,9 +161,9 @@ private:
uint8_t *msg, uint8_t *msg,
uint32_t msg_len, uint32_t msg_len,
uint8_t *mac); uint8_t *mac);
bool integrity_check(byte_buffer_t *pdu); bool integrity_check(srslte::unique_byte_buffer& pdu);
void cipher_encrypt(byte_buffer_t *pdu); void cipher_encrypt(srslte::unique_byte_buffer& pdu);
void cipher_decrypt(byte_buffer_t *pdu); void cipher_decrypt(srslte::unique_byte_buffer& pdu);
void set_k_enb_count(uint32_t count); void set_k_enb_count(uint32_t count);
bool check_cap_replay(LIBLTE_MME_UE_SECURITY_CAPABILITIES_STRUCT *caps); bool check_cap_replay(LIBLTE_MME_UE_SECURITY_CAPABILITIES_STRUCT *caps);
@ -171,21 +171,21 @@ private:
void select_plmn(); void select_plmn();
// Parsers // Parsers
void parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu); void parse_attach_accept(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_attach_reject(uint32_t lcid, byte_buffer_t *pdu); void parse_attach_reject(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu, const uint8_t sec_hdr_type); void parse_authentication_request(uint32_t lcid, srslte::unique_byte_buffer pdu, const uint8_t sec_hdr_type);
void parse_authentication_reject(uint32_t lcid, byte_buffer_t *pdu); void parse_authentication_reject(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_identity_request(uint32_t lcid, byte_buffer_t *pdu); void parse_identity_request(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu); void parse_security_mode_command(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_service_reject(uint32_t lcid, byte_buffer_t *pdu); void parse_service_reject(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu); void parse_esm_information_request(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_emm_information(uint32_t lcid, byte_buffer_t *pdu); void parse_emm_information(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_detach_request(uint32_t lcid, byte_buffer_t *pdu); void parse_detach_request(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_emm_status(uint32_t lcid, byte_buffer_t *pdu); void parse_emm_status(uint32_t lcid, srslte::unique_byte_buffer pdu);
// Packet generators // Packet generators
void gen_attach_request(byte_buffer_t *msg); void gen_attach_request(srslte::unique_byte_buffer& msg);
void gen_service_request(byte_buffer_t *msg); void gen_service_request(srslte::unique_byte_buffer& msg);
// Senders // Senders
void send_identity_response(uint32_t lcid, uint8 id_type); void send_identity_response(uint32_t lcid, uint8 id_type);

View File

@ -307,20 +307,19 @@ public:
typedef enum { Rx = 0, Tx } direction_t; typedef enum { Rx = 0, Tx } direction_t;
template <class T> template <class T>
void void log_rrc_message(const std::string source, const direction_t dir, const srslte::byte_buffer_t* pdu, const T& msg);
log_rrc_message(const std::string source, const direction_t dir, const srslte::unique_pool_buffer& pdu, const T& msg);
void print_mbms(); void print_mbms();
bool mbms_service_start(uint32_t serv, uint32_t port); bool mbms_service_start(uint32_t serv, uint32_t port);
// NAS interface // NAS interface
void write_sdu(srslte::unique_pool_buffer sdu); void write_sdu(srslte::unique_byte_buffer sdu);
void enable_capabilities(); void enable_capabilities();
uint16_t get_mcc(); uint16_t get_mcc();
uint16_t get_mnc(); uint16_t get_mnc();
int plmn_search(found_plmn_t found_plmns[MAX_FOUND_PLMNS]); int plmn_search(found_plmn_t found_plmns[MAX_FOUND_PLMNS]);
void plmn_select(asn1::rrc::plmn_id_s plmn_id); void plmn_select(asn1::rrc::plmn_id_s plmn_id);
bool connection_request(asn1::rrc::establishment_cause_e cause, srslte::unique_pool_buffer dedicated_info_nas); bool connection_request(asn1::rrc::establishment_cause_e cause, srslte::unique_byte_buffer dedicated_info_nas);
void set_ue_idenity(asn1::rrc::s_tmsi_s s_tmsi); void set_ue_idenity(asn1::rrc::s_tmsi_s s_tmsi);
// PHY interface // PHY interface
@ -339,11 +338,11 @@ public:
bool have_drb(); bool have_drb();
// PDCP interface // PDCP interface
void write_pdu(uint32_t lcid, srslte::unique_pool_buffer pdu); void write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu);
void write_pdu_bcch_bch(srslte::unique_pool_buffer pdu); void write_pdu_bcch_bch(srslte::unique_byte_buffer pdu);
void write_pdu_bcch_dlsch(srslte::unique_pool_buffer pdu); void write_pdu_bcch_dlsch(srslte::unique_byte_buffer pdu);
void write_pdu_pcch(srslte::unique_pool_buffer pdu); void write_pdu_pcch(srslte::unique_byte_buffer pdu);
void write_pdu_mch(uint32_t lcid, srslte::unique_pool_buffer pdu); void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer pdu);
private: private:
@ -353,7 +352,7 @@ private:
PCCH, PCCH,
STOP STOP
} command; } command;
srslte::unique_pool_buffer pdu; srslte::unique_byte_buffer pdu;
uint16_t lcid; uint16_t lcid;
} cmd_msg_t; } cmd_msg_t;
@ -361,7 +360,7 @@ private:
srslte::block_queue<cmd_msg_t> cmd_q; srslte::block_queue<cmd_msg_t> cmd_q;
void run_thread(); void run_thread();
void process_pcch(srslte::unique_pool_buffer pdu); void process_pcch(srslte::unique_byte_buffer pdu);
srslte::byte_buffer_pool *pool; srslte::byte_buffer_pool *pool;
srslte::log *rrc_log; srslte::log *rrc_log;
@ -373,7 +372,7 @@ private:
usim_interface_rrc *usim; usim_interface_rrc *usim;
gw_interface_rrc *gw; gw_interface_rrc *gw;
srslte::unique_pool_buffer dedicated_info_nas; srslte::unique_byte_buffer dedicated_info_nas;
void send_ul_ccch_msg(const asn1::rrc::ul_ccch_msg_s& msg); void send_ul_ccch_msg(const asn1::rrc::ul_ccch_msg_s& msg);
void send_ul_dcch_msg(uint32_t lcid, const asn1::rrc::ul_dcch_msg_s& msg); void send_ul_dcch_msg(uint32_t lcid, const asn1::rrc::ul_dcch_msg_s& msg);
@ -626,17 +625,17 @@ private:
void send_con_request(asn1::rrc::establishment_cause_e cause); void send_con_request(asn1::rrc::establishment_cause_e cause);
void send_con_restablish_request(asn1::rrc::reest_cause_e cause); void send_con_restablish_request(asn1::rrc::reest_cause_e cause);
void send_con_restablish_complete(); void send_con_restablish_complete();
void send_con_setup_complete(srslte::unique_pool_buffer nas_msg); void send_con_setup_complete(srslte::unique_byte_buffer nas_msg);
void send_ul_info_transfer(srslte::unique_pool_buffer nas_msg); void send_ul_info_transfer(srslte::unique_byte_buffer nas_msg);
void send_security_mode_complete(); void send_security_mode_complete();
void send_rrc_con_reconfig_complete(); void send_rrc_con_reconfig_complete();
void send_rrc_ue_cap_info(); void send_rrc_ue_cap_info();
// Parsers // Parsers
void process_pdu(uint32_t lcid, srslte::unique_pool_buffer pdu); void process_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_dl_ccch(srslte::unique_pool_buffer pdu); void parse_dl_ccch(srslte::unique_byte_buffer pdu);
void parse_dl_dcch(uint32_t lcid, srslte::unique_pool_buffer pdu); void parse_dl_dcch(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_dl_info_transfer(uint32_t lcid, srslte::unique_pool_buffer pdu); void parse_dl_info_transfer(uint32_t lcid, srslte::unique_byte_buffer pdu);
// Helpers // Helpers
bool con_reconfig(asn1::rrc::rrc_conn_recfg_s* reconfig); bool con_reconfig(asn1::rrc::rrc_conn_recfg_s* reconfig);

View File

@ -162,7 +162,7 @@ void gw::set_tundevname(const std::string & devname)
/******************************************************************************* /*******************************************************************************
PDCP interface PDCP interface
*******************************************************************************/ *******************************************************************************/
void gw::write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) void gw::write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu)
{ {
gw_log->info_hex(pdu->msg, pdu->N_bytes, "RX PDU. Stack latency: %ld us\n", pdu->get_latency_us()); gw_log->info_hex(pdu->msg, pdu->N_bytes, "RX PDU. Stack latency: %ld us\n", pdu->get_latency_us());
dl_tput_bytes += pdu->N_bytes; dl_tput_bytes += pdu->N_bytes;
@ -181,10 +181,9 @@ void gw::write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu)
gw_log->error("Unsupported IP version. Dropping packet with %d B\n", pdu->N_bytes); gw_log->error("Unsupported IP version. Dropping packet with %d B\n", pdu->N_bytes);
} }
} }
pool->deallocate(pdu);
} }
void gw::write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *pdu) void gw::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer pdu)
{ {
if(pdu->N_bytes>2) if(pdu->N_bytes>2)
{ {
@ -206,7 +205,6 @@ void gw::write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *pdu)
} }
} }
} }
pool->deallocate(pdu);
} }
/******************************************************************************* /*******************************************************************************
@ -253,7 +251,7 @@ void gw::run_thread()
uint32 idx = 0; uint32 idx = 0;
int32 N_bytes = 0; int32 N_bytes = 0;
srslte::byte_buffer_t *pdu = pool_allocate_blocking; srslte::unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu) { if (!pdu) {
gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n"); gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n");
return; return;
@ -315,9 +313,9 @@ void gw::run_thread()
if (pdcp->is_lcid_enabled(cfg.lcid)) { if (pdcp->is_lcid_enabled(cfg.lcid)) {
pdu->set_timestamp(); pdu->set_timestamp();
ul_tput_bytes += pdu->N_bytes; ul_tput_bytes += pdu->N_bytes;
pdcp->write_sdu(cfg.lcid, pdu, false); pdcp->write_sdu(cfg.lcid, std::move(pdu), false);
do { do {
pdu = pool_allocate; pdu = srslte::allocate_unique_buffer(*pool);
if (!pdu) { if (!pdu) {
gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n"); gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n");
usleep(100000); usleep(100000);

View File

@ -257,7 +257,7 @@ bool nas::rrc_connect() {
} }
// Generate service request or attach request message // Generate service request or attach request message
byte_buffer_t *dedicatedInfoNAS = pool_allocate_blocking; unique_byte_buffer dedicatedInfoNAS = srslte::allocate_unique_buffer(*pool, true);
if (!dedicatedInfoNAS) { if (!dedicatedInfoNAS) {
nas_log->error("Fatal Error: Couldn't allocate PDU in rrc_connect().\n"); nas_log->error("Fatal Error: Couldn't allocate PDU in rrc_connect().\n");
return false; return false;
@ -280,8 +280,7 @@ bool nas::rrc_connect() {
// Set establishment cause // Set establishment cause
establishment_cause_e establish_cause = establishment_cause_e::mo_sig; establishment_cause_e establish_cause = establishment_cause_e::mo_sig;
if (rrc->connection_request(establish_cause, dedicatedInfoNAS)) if (rrc->connection_request(establish_cause, std::move(dedicatedInfoNAS))) {
{
nas_log->info("Connection established correctly. Waiting for Attach\n"); nas_log->info("Connection established correctly. Waiting for Attach\n");
// Wait until attachment. If doing a service request is already attached // Wait until attachment. If doing a service request is already attached
@ -335,8 +334,8 @@ void nas::select_plmn() {
} }
} }
void nas::write_pdu(uint32_t lcid, unique_byte_buffer pdu)
void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { {
uint8 pd = 0; uint8 pd = 0;
uint8 msg_type = 0; uint8 msg_type = 0;
uint8 sec_hdr_type = 0; uint8 sec_hdr_type = 0;
@ -344,7 +343,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str()); nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str());
// Parse the message security header // Parse the message security header
liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)pdu, &pd, &sec_hdr_type); liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &pd, &sec_hdr_type);
switch (sec_hdr_type) switch (sec_hdr_type)
{ {
case LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS: case LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS:
@ -360,14 +359,12 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
break; break;
} else { } else {
nas_log->error("Not handling NAS message with integrity check error\n"); nas_log->error("Not handling NAS message with integrity check error\n");
pool->deallocate(pdu);
return; return;
} }
case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT: case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT:
break; break;
default: default:
nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type); nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type);
pool->deallocate(pdu);
return; return;
} }
@ -377,47 +374,46 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
} }
// Parse the message header // Parse the message header
liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT *) pdu, &pd, &msg_type); liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &pd, &msg_type);
nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s Decrypted PDU", rrc->get_rb_name(lcid).c_str()); nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s Decrypted PDU", rrc->get_rb_name(lcid).c_str());
// TODO: Check if message type requieres specical security header type and if it isvalid // TODO: Check if message type requieres specical security header type and if it isvalid
switch (msg_type) { switch (msg_type) {
case LIBLTE_MME_MSG_TYPE_ATTACH_ACCEPT: case LIBLTE_MME_MSG_TYPE_ATTACH_ACCEPT:
parse_attach_accept(lcid, pdu); parse_attach_accept(lcid, std::move(pdu));
break; break;
case LIBLTE_MME_MSG_TYPE_ATTACH_REJECT: case LIBLTE_MME_MSG_TYPE_ATTACH_REJECT:
parse_attach_reject(lcid, pdu); parse_attach_reject(lcid, std::move(pdu));
break; break;
case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REQUEST: case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REQUEST:
parse_authentication_request(lcid, pdu, sec_hdr_type); parse_authentication_request(lcid, std::move(pdu), sec_hdr_type);
break; break;
case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REJECT: case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REJECT:
parse_authentication_reject(lcid, pdu); parse_authentication_reject(lcid, std::move(pdu));
break; break;
case LIBLTE_MME_MSG_TYPE_IDENTITY_REQUEST: case LIBLTE_MME_MSG_TYPE_IDENTITY_REQUEST:
parse_identity_request(lcid, pdu); parse_identity_request(lcid, std::move(pdu));
break; break;
case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMMAND: case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMMAND:
parse_security_mode_command(lcid, pdu); parse_security_mode_command(lcid, std::move(pdu));
break; break;
case LIBLTE_MME_MSG_TYPE_SERVICE_REJECT: case LIBLTE_MME_MSG_TYPE_SERVICE_REJECT:
parse_service_reject(lcid, pdu); parse_service_reject(lcid, std::move(pdu));
break; break;
case LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_REQUEST: case LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_REQUEST:
parse_esm_information_request(lcid, pdu); parse_esm_information_request(lcid, std::move(pdu));
break; break;
case LIBLTE_MME_MSG_TYPE_EMM_INFORMATION: case LIBLTE_MME_MSG_TYPE_EMM_INFORMATION:
parse_emm_information(lcid, pdu); parse_emm_information(lcid, std::move(pdu));
break; break;
case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST:
parse_detach_request(lcid, pdu); parse_detach_request(lcid, std::move(pdu));
break; break;
case LIBLTE_MME_MSG_TYPE_EMM_STATUS: case LIBLTE_MME_MSG_TYPE_EMM_STATUS:
parse_emm_status(lcid, pdu); parse_emm_status(lcid, std::move(pdu));
break; break;
default: default:
nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type); nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type);
pool->deallocate(pdu);
return; return;
} }
} }
@ -510,7 +506,7 @@ void nas::integrity_generate(uint8_t *key_128,
// This function depends to a valid k_nas_int. // This function depends to a valid k_nas_int.
// This key is generated in the security mode command. // This key is generated in the security mode command.
bool nas::integrity_check(byte_buffer_t *pdu) bool nas::integrity_check(unique_byte_buffer& pdu)
{ {
if (!pdu) { if (!pdu) {
nas_log->error("Invalid PDU\n"); nas_log->error("Invalid PDU\n");
@ -547,7 +543,7 @@ bool nas::integrity_check(byte_buffer_t *pdu)
} }
} }
void nas::cipher_encrypt(byte_buffer_t *pdu) void nas::cipher_encrypt(unique_byte_buffer& pdu)
{ {
byte_buffer_t pdu_tmp; byte_buffer_t pdu_tmp;
switch(ctxt.cipher_algo) switch(ctxt.cipher_algo)
@ -580,7 +576,7 @@ void nas::cipher_encrypt(byte_buffer_t *pdu)
} }
} }
void nas::cipher_decrypt(byte_buffer_t *pdu) void nas::cipher_decrypt(unique_byte_buffer& pdu)
{ {
byte_buffer_t tmp_pdu; byte_buffer_t tmp_pdu;
switch(ctxt.cipher_algo) switch(ctxt.cipher_algo)
@ -629,7 +625,8 @@ bool nas::check_cap_replay(LIBLTE_MME_UE_SECURITY_CAPABILITIES_STRUCT *caps)
* Parsers * Parsers
******************************************************************************/ ******************************************************************************/
void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) { void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer pdu)
{
if (!pdu) { if (!pdu) {
nas_log->error("Invalid PDU\n"); nas_log->error("Invalid PDU\n");
@ -638,7 +635,6 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
if (pdu->N_bytes <= 5) { if (pdu->N_bytes <= 5) {
nas_log->error("Invalid attach accept PDU size (%d)\n", pdu->N_bytes); nas_log->error("Invalid attach accept PDU size (%d)\n", pdu->N_bytes);
pool->deallocate(pdu);
return; return;
} }
@ -653,7 +649,7 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
nas_log->info("Received Attach Accept\n"); nas_log->info("Received Attach Accept\n");
liblte_mme_unpack_attach_accept_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &attach_accept); liblte_mme_unpack_attach_accept_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &attach_accept);
if (attach_accept.eps_attach_result == LIBLTE_MME_EPS_ATTACH_RESULT_EPS_ONLY) { if (attach_accept.eps_attach_result == LIBLTE_MME_EPS_ATTACH_RESULT_EPS_ONLY) {
//FIXME: Handle t3412.unit //FIXME: Handle t3412.unit
@ -684,7 +680,6 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
if ( (cfg.apn_protocol == "ipv4" && LIBLTE_MME_PDN_TYPE_IPV6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) || if ( (cfg.apn_protocol == "ipv4" && LIBLTE_MME_PDN_TYPE_IPV6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) ||
(cfg.apn_protocol == "ipv6" && LIBLTE_MME_PDN_TYPE_IPV4 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) ){ (cfg.apn_protocol == "ipv6" && LIBLTE_MME_PDN_TYPE_IPV4 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) ){
nas_log->error("Failed to attach -- Mismatch between PDN protocol and PDN type in attach accept.\n"); nas_log->error("Failed to attach -- Mismatch between PDN protocol and PDN type in attach accept.\n");
pool->deallocate(pdu);
return; return;
} }
if ( ("ipv4v6" == cfg.apn_protocol && LIBLTE_MME_PDN_TYPE_IPV4 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) || if ( ("ipv4v6" == cfg.apn_protocol && LIBLTE_MME_PDN_TYPE_IPV4 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) ||
@ -790,7 +785,6 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
} }
} else { } else {
nas_log->error("PDN type not IPv4, IPv6 nor IPv4v6\n"); nas_log->error("PDN type not IPv4, IPv6 nor IPv4v6\n");
pool->deallocate(pdu);
return; return;
} }
eps_bearer_id = act_def_eps_bearer_context_req.eps_bearer_id; eps_bearer_id = act_def_eps_bearer_context_req.eps_bearer_id;
@ -846,7 +840,7 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
liblte_mme_pack_attach_complete_msg(&attach_complete, liblte_mme_pack_attach_complete_msg(&attach_complete,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED,
ctxt.tx_count, ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *) pdu); (LIBLTE_BYTE_MSG_STRUCT*)pdu.get());
// Write NAS pcap // Write NAS pcap
if (pcap != NULL) { if (pcap != NULL) {
pcap->write_nas(pdu->msg, pdu->N_bytes); pcap->write_nas(pdu->msg, pdu->N_bytes);
@ -864,36 +858,33 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
rrc->enable_capabilities(); rrc->enable_capabilities();
nas_log->info("Sending Attach Complete\n"); nas_log->info("Sending Attach Complete\n");
rrc->write_sdu(pdu); rrc->write_sdu(std::move(pdu));
ctxt.tx_count++; ctxt.tx_count++;
} else { } else {
nas_log->info("Not handling attach type %u\n", attach_accept.eps_attach_result); nas_log->info("Not handling attach type %u\n", attach_accept.eps_attach_result);
state = EMM_STATE_DEREGISTERED; state = EMM_STATE_DEREGISTERED;
pool->deallocate(pdu);
} }
} }
void nas::parse_attach_reject(uint32_t lcid, byte_buffer_t *pdu) { void nas::parse_attach_reject(uint32_t lcid, unique_byte_buffer pdu)
{
LIBLTE_MME_ATTACH_REJECT_MSG_STRUCT attach_rej; LIBLTE_MME_ATTACH_REJECT_MSG_STRUCT attach_rej;
ZERO_OBJECT(attach_rej); ZERO_OBJECT(attach_rej);
liblte_mme_unpack_attach_reject_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &attach_rej); liblte_mme_unpack_attach_reject_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &attach_rej);
nas_log->warning("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause); nas_log->warning("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause);
nas_log->console("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause); nas_log->console("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause);
state = EMM_STATE_DEREGISTERED; state = EMM_STATE_DEREGISTERED;
pool->deallocate(pdu);
// FIXME: Command RRC to release? // FIXME: Command RRC to release?
} }
void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu, const uint8_t sec_hdr_type) { void nas::parse_authentication_request(uint32_t lcid, unique_byte_buffer pdu, const uint8_t sec_hdr_type)
{
LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT auth_req; LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT auth_req;
bzero(&auth_req, sizeof(LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT)); bzero(&auth_req, sizeof(LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT));
nas_log->info("Received Authentication Request\n"); nas_log->info("Received Authentication Request\n");
liblte_mme_unpack_authentication_request_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &auth_req); liblte_mme_unpack_authentication_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &auth_req);
// Deallocate PDU after parsing
pool->deallocate(pdu);
ctxt.rx_count++; ctxt.rx_count++;
@ -933,23 +924,23 @@ void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu, const
} }
} }
void nas::parse_authentication_reject(uint32_t lcid, byte_buffer_t *pdu) { void nas::parse_authentication_reject(uint32_t lcid, unique_byte_buffer pdu)
{
nas_log->warning("Received Authentication Reject\n"); nas_log->warning("Received Authentication Reject\n");
pool->deallocate(pdu);
state = EMM_STATE_DEREGISTERED; state = EMM_STATE_DEREGISTERED;
// FIXME: Command RRC to release? // FIXME: Command RRC to release?
} }
void nas::parse_identity_request(uint32_t lcid, byte_buffer_t *pdu) { void nas::parse_identity_request(uint32_t lcid, unique_byte_buffer pdu)
{
LIBLTE_MME_ID_REQUEST_MSG_STRUCT id_req; LIBLTE_MME_ID_REQUEST_MSG_STRUCT id_req;
ZERO_OBJECT(id_req); ZERO_OBJECT(id_req);
LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp; LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp;
ZERO_OBJECT(id_resp); ZERO_OBJECT(id_resp);
liblte_mme_unpack_identity_request_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &id_req); liblte_mme_unpack_identity_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &id_req);
// Deallocate PDU after parsing // Deallocate PDU after parsing
pool->deallocate(pdu);
ctxt.rx_count++; ctxt.rx_count++;
@ -958,7 +949,7 @@ void nas::parse_identity_request(uint32_t lcid, byte_buffer_t *pdu) {
send_identity_response(lcid, id_req.id_type); send_identity_response(lcid, id_req.id_type);
} }
void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu) void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer pdu)
{ {
if (!pdu) { if (!pdu) {
nas_log->error("Invalid PDU\n"); nas_log->error("Invalid PDU\n");
@ -975,7 +966,7 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp; LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp;
bzero(&sec_mode_comp, sizeof(LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT)); bzero(&sec_mode_comp, sizeof(LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT));
liblte_mme_unpack_security_mode_command_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &sec_mode_cmd); liblte_mme_unpack_security_mode_command_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &sec_mode_cmd);
nas_log->info("Received Security Mode Command ksi: %d, eea: %s, eia: %s\n", nas_log->info("Received Security Mode Command ksi: %d, eea: %s, eia: %s\n",
sec_mode_cmd.nas_ksi.nas_ksi, sec_mode_cmd.nas_ksi.nas_ksi,
ciphering_algorithm_id_text[sec_mode_cmd.selected_nas_sec_algs.type_of_eea], ciphering_algorithm_id_text[sec_mode_cmd.selected_nas_sec_algs.type_of_eea],
@ -983,7 +974,6 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
if(sec_mode_cmd.nas_ksi.tsc_flag != LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE) { if(sec_mode_cmd.nas_ksi.tsc_flag != LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE) {
nas_log->error("Mapped security context not supported\n"); nas_log->error("Mapped security context not supported\n");
pool->deallocate(pdu);
return; return;
} }
@ -991,7 +981,6 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
if(sec_mode_cmd.nas_ksi.nas_ksi != ctxt.ksi) { if(sec_mode_cmd.nas_ksi.nas_ksi != ctxt.ksi) {
nas_log->warning("Sending Security Mode Reject due to key set ID mismatch\n"); nas_log->warning("Sending Security Mode Reject due to key set ID mismatch\n");
send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED); send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED);
pool->deallocate(pdu);
return; return;
} }
} }
@ -1004,7 +993,6 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
if(!check_cap_replay(&sec_mode_cmd.ue_security_cap)) { if(!check_cap_replay(&sec_mode_cmd.ue_security_cap)) {
nas_log->warning("Sending Security Mode Reject due to security capabilities mismatch\n"); nas_log->warning("Sending Security Mode Reject due to security capabilities mismatch\n");
send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH); send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH);
pool->deallocate(pdu);
return; return;
} }
@ -1022,7 +1010,6 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
if(!eea_caps[ctxt.cipher_algo] || !eia_caps[ctxt.integ_algo]) { if(!eea_caps[ctxt.cipher_algo] || !eia_caps[ctxt.integ_algo]) {
nas_log->warning("Sending Security Mode Reject due to security capabilities mismatch\n"); nas_log->warning("Sending Security Mode Reject due to security capabilities mismatch\n");
send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH); send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH);
pool->deallocate(pdu);
return; return;
} }
@ -1038,7 +1025,6 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
if (integrity_check(pdu) != true) { if (integrity_check(pdu) != true) {
nas_log->warning("Sending Security Mode Reject due to integrity check failure\n"); nas_log->warning("Sending Security Mode Reject due to integrity check failure\n");
send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_MAC_FAILURE); send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_MAC_FAILURE);
pool->deallocate(pdu);
return; return;
} }
@ -1059,10 +1045,11 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
// Send response // Send response
pdu->reset(); pdu->reset();
liblte_mme_pack_security_mode_complete_msg(&sec_mode_comp, liblte_mme_pack_security_mode_complete_msg(
&sec_mode_comp,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT,
ctxt.tx_count, ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *) pdu); (LIBLTE_BYTE_MSG_STRUCT*)pdu.get());
if(pcap != NULL) { if(pcap != NULL) {
pcap->write_nas(pdu->msg, pdu->N_bytes); pcap->write_nas(pdu->msg, pdu->N_bytes);
} }
@ -1076,14 +1063,14 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
nas_log->info("Sending Security Mode Complete nas_current_ctxt.tx_count=%d, RB=%s\n", nas_log->info("Sending Security Mode Complete nas_current_ctxt.tx_count=%d, RB=%s\n",
ctxt.tx_count, ctxt.tx_count,
rrc->get_rb_name(lcid).c_str()); rrc->get_rb_name(lcid).c_str());
rrc->write_sdu(pdu); rrc->write_sdu(std::move(pdu));
ctxt.tx_count++; ctxt.tx_count++;
} }
void nas::parse_service_reject(uint32_t lcid, byte_buffer_t* pdu) void nas::parse_service_reject(uint32_t lcid, unique_byte_buffer pdu)
{ {
LIBLTE_MME_SERVICE_REJECT_MSG_STRUCT service_reject; LIBLTE_MME_SERVICE_REJECT_MSG_STRUCT service_reject;
if (liblte_mme_unpack_service_reject_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu, &service_reject)) { if (liblte_mme_unpack_service_reject_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &service_reject)) {
nas_log->error("Error unpacking service reject.\n"); nas_log->error("Error unpacking service reject.\n");
goto exit; goto exit;
} }
@ -1098,36 +1085,34 @@ void nas::parse_service_reject(uint32_t lcid, byte_buffer_t* pdu)
exit: exit:
ctxt.rx_count++; ctxt.rx_count++;
pool->deallocate(pdu);
} }
void nas::parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu) { void nas::parse_esm_information_request(uint32_t lcid, unique_byte_buffer pdu)
{
LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT esm_info_req; LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT esm_info_req;
liblte_mme_unpack_esm_information_request_msg((LIBLTE_BYTE_MSG_STRUCT *)pdu, &esm_info_req); liblte_mme_unpack_esm_information_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &esm_info_req);
nas_log->info("ESM information request received for beaser=%d, transaction_id=%d\n", esm_info_req.eps_bearer_id, esm_info_req.proc_transaction_id); nas_log->info("ESM information request received for beaser=%d, transaction_id=%d\n", esm_info_req.eps_bearer_id, esm_info_req.proc_transaction_id);
ctxt.rx_count++; ctxt.rx_count++;
pool->deallocate(pdu);
// send response // send response
send_esm_information_response(esm_info_req.proc_transaction_id); send_esm_information_response(esm_info_req.proc_transaction_id);
} }
void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { void nas::parse_emm_information(uint32_t lcid, unique_byte_buffer pdu)
liblte_mme_unpack_emm_information_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &emm_info); {
liblte_mme_unpack_emm_information_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &emm_info);
std::string str = emm_info_str(&emm_info); std::string str = emm_info_str(&emm_info);
nas_log->info("Received EMM Information: %s\n", str.c_str()); nas_log->info("Received EMM Information: %s\n", str.c_str());
nas_log->console("%s\n", str.c_str()); nas_log->console("%s\n", str.c_str());
ctxt.rx_count++; ctxt.rx_count++;
pool->deallocate(pdu);
} }
void nas::parse_detach_request(uint32_t lcid, byte_buffer_t *pdu) void nas::parse_detach_request(uint32_t lcid, unique_byte_buffer pdu)
{ {
LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_request; LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_request;
liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &detach_request); liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &detach_request);
ctxt.rx_count++; ctxt.rx_count++;
pool->deallocate(pdu);
if (state == EMM_STATE_REGISTERED) { if (state == EMM_STATE_REGISTERED) {
nas_log->info("Received Detach request (type=%d)\n", detach_request.detach_type.type_of_detach); nas_log->info("Received Detach request (type=%d)\n", detach_request.detach_type.type_of_detach);
@ -1139,12 +1124,11 @@ void nas::parse_detach_request(uint32_t lcid, byte_buffer_t *pdu)
} }
} }
void nas::parse_emm_status(uint32_t lcid, byte_buffer_t *pdu) void nas::parse_emm_status(uint32_t lcid, unique_byte_buffer pdu)
{ {
LIBLTE_MME_EMM_STATUS_MSG_STRUCT emm_status; LIBLTE_MME_EMM_STATUS_MSG_STRUCT emm_status;
liblte_mme_unpack_emm_status_msg((LIBLTE_BYTE_MSG_STRUCT *)pdu, &emm_status); liblte_mme_unpack_emm_status_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &emm_status);
ctxt.rx_count++; ctxt.rx_count++;
pool->deallocate(pdu);
switch (emm_status.emm_cause) { switch (emm_status.emm_cause) {
case LIBLTE_MME_ESM_CAUSE_INVALID_EPS_BEARER_IDENTITY: case LIBLTE_MME_ESM_CAUSE_INVALID_EPS_BEARER_IDENTITY:
@ -1169,7 +1153,8 @@ void nas::parse_emm_status(uint32_t lcid, byte_buffer_t *pdu)
* Senders * Senders
******************************************************************************/ ******************************************************************************/
void nas::gen_attach_request(byte_buffer_t *msg) { void nas::gen_attach_request(unique_byte_buffer& msg)
{
if (!msg) { if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in gen_attach_request().\n"); nas_log->error("Fatal Error: Couldn't allocate PDU in gen_attach_request().\n");
return; return;
@ -1224,10 +1209,8 @@ void nas::gen_attach_request(byte_buffer_t *msg) {
nas_log->info("Requesting GUTI attach. " nas_log->info("Requesting GUTI attach. "
"m_tmsi: %x, mcc: %x, mnc: %x, mme_group_id: %x, mme_code: %x\n", "m_tmsi: %x, mcc: %x, mnc: %x, mme_group_id: %x, mme_code: %x\n",
ctxt.guti.m_tmsi, ctxt.guti.mcc, ctxt.guti.mnc, ctxt.guti.mme_group_id, ctxt.guti.mme_code); ctxt.guti.m_tmsi, ctxt.guti.mcc, ctxt.guti.mnc, ctxt.guti.mme_group_id, ctxt.guti.mme_code);
liblte_mme_pack_attach_request_msg(&attach_req, liblte_mme_pack_attach_request_msg(
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, &attach_req, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)msg.get());
ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *) msg);
// Add MAC // Add MAC
if (msg->N_bytes > 5) { if (msg->N_bytes > 5) {
@ -1246,7 +1229,7 @@ void nas::gen_attach_request(byte_buffer_t *msg) {
attach_req.nas_ksi.nas_ksi = 0; attach_req.nas_ksi.nas_ksi = 0;
usim->get_imsi_vec(attach_req.eps_mobile_id.imsi, 15); usim->get_imsi_vec(attach_req.eps_mobile_id.imsi, 15);
nas_log->info("Requesting IMSI attach (IMSI=%s)\n", usim->get_imsi_str().c_str()); nas_log->info("Requesting IMSI attach (IMSI=%s)\n", usim->get_imsi_str().c_str());
liblte_mme_pack_attach_request_msg(&attach_req, (LIBLTE_BYTE_MSG_STRUCT *) msg); liblte_mme_pack_attach_request_msg(&attach_req, (LIBLTE_BYTE_MSG_STRUCT*)msg.get());
} }
if(pcap != NULL) { if(pcap != NULL) {
@ -1259,8 +1242,8 @@ void nas::gen_attach_request(byte_buffer_t *msg) {
} }
} }
void nas::gen_service_request(unique_byte_buffer& msg)
void nas::gen_service_request(byte_buffer_t *msg) { {
if (!msg) { if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in gen_service_request().\n"); nas_log->error("Fatal Error: Couldn't allocate PDU in gen_service_request().\n");
return; return;
@ -1340,7 +1323,7 @@ void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) {
} }
void nas::send_security_mode_reject(uint8_t cause) { void nas::send_security_mode_reject(uint8_t cause) {
byte_buffer_t *msg = pool_allocate_blocking; unique_byte_buffer msg = srslte::allocate_unique_buffer(*pool, true);
if (!msg) { if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_security_mode_reject().\n"); nas_log->error("Fatal Error: Couldn't allocate PDU in send_security_mode_reject().\n");
return; return;
@ -1348,17 +1331,17 @@ void nas::send_security_mode_reject(uint8_t cause) {
LIBLTE_MME_SECURITY_MODE_REJECT_MSG_STRUCT sec_mode_rej = {0}; LIBLTE_MME_SECURITY_MODE_REJECT_MSG_STRUCT sec_mode_rej = {0};
sec_mode_rej.emm_cause = cause; sec_mode_rej.emm_cause = cause;
liblte_mme_pack_security_mode_reject_msg(&sec_mode_rej, (LIBLTE_BYTE_MSG_STRUCT *) msg); liblte_mme_pack_security_mode_reject_msg(&sec_mode_rej, (LIBLTE_BYTE_MSG_STRUCT*)msg.get());
if(pcap != NULL) { if(pcap != NULL) {
pcap->write_nas(msg->msg, msg->N_bytes); pcap->write_nas(msg->msg, msg->N_bytes);
} }
nas_log->info("Sending security mode reject\n"); nas_log->info("Sending security mode reject\n");
rrc->write_sdu(msg); rrc->write_sdu(std::move(msg));
} }
void nas::send_detach_request(bool switch_off) void nas::send_detach_request(bool switch_off)
{ {
byte_buffer_t *pdu = pool_allocate_blocking; unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu) { if (!pdu) {
nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__); nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__);
return; return;
@ -1384,7 +1367,8 @@ void nas::send_detach_request(bool switch_off)
liblte_mme_pack_detach_request_msg(&detach_request, liblte_mme_pack_detach_request_msg(&detach_request,
rrc->is_connected() ? LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED rrc->is_connected() ? LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED
: LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, : LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY,
ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu); ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT*)pdu.get());
if(pcap != NULL) { if(pcap != NULL) {
pcap->write_nas(pdu->msg, pdu->N_bytes); pcap->write_nas(pdu->msg, pdu->N_bytes);
@ -1411,7 +1395,8 @@ void nas::send_detach_request(bool switch_off)
detach_request.nas_ksi.nas_ksi = 0; detach_request.nas_ksi.nas_ksi = 0;
usim->get_imsi_vec(detach_request.eps_mobile_id.imsi, 15); usim->get_imsi_vec(detach_request.eps_mobile_id.imsi, 15);
nas_log->info("Requesting IMSI detach (IMSI=%s)\n", usim->get_imsi_str().c_str()); nas_log->info("Requesting IMSI detach (IMSI=%s)\n", usim->get_imsi_str().c_str());
liblte_mme_pack_detach_request_msg(&detach_request, LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT *) pdu); liblte_mme_pack_detach_request_msg(
&detach_request, LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get());
if(pcap != NULL) { if(pcap != NULL) {
pcap->write_nas(pdu->msg, pdu->N_bytes); pcap->write_nas(pdu->msg, pdu->N_bytes);
@ -1420,15 +1405,15 @@ void nas::send_detach_request(bool switch_off)
nas_log->info("Sending detach request\n"); nas_log->info("Sending detach request\n");
if (rrc->is_connected()) { if (rrc->is_connected()) {
rrc->write_sdu(pdu); rrc->write_sdu(std::move(pdu));
} else { } else {
rrc->connection_request(establishment_cause_e::mo_sig, pdu); rrc->connection_request(establishment_cause_e::mo_sig, std::move(pdu));
} }
} }
void nas::send_detach_accept() void nas::send_detach_accept()
{ {
byte_buffer_t *pdu = pool_allocate_blocking; unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu) { if (!pdu) {
nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__); nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__);
return; return;
@ -1439,7 +1424,7 @@ void nas::send_detach_accept()
liblte_mme_pack_detach_accept_msg(&detach_accept, liblte_mme_pack_detach_accept_msg(&detach_accept,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED,
ctxt.tx_count, ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *) pdu); (LIBLTE_BYTE_MSG_STRUCT*)pdu.get());
if(pcap != NULL) { if(pcap != NULL) {
pcap->write_nas(pdu->msg, pdu->N_bytes); pcap->write_nas(pdu->msg, pdu->N_bytes);
@ -1459,12 +1444,12 @@ void nas::send_detach_accept()
} }
nas_log->info("Sending detach accept\n"); nas_log->info("Sending detach accept\n");
rrc->write_sdu(pdu); rrc->write_sdu(std::move(pdu));
} }
void nas::send_authentication_response(const uint8_t* res, const size_t res_len, const uint8_t sec_hdr_type) { void nas::send_authentication_response(const uint8_t* res, const size_t res_len, const uint8_t sec_hdr_type) {
byte_buffer_t *pdu = pool_allocate_blocking; unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu) { if (!pdu) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_response().\n"); nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_response().\n");
return; return;
@ -1477,7 +1462,8 @@ void nas::send_authentication_response(const uint8_t* res, const size_t res_len,
auth_res.res[i] = res[i]; auth_res.res[i] = res[i];
} }
auth_res.res_len = res_len; auth_res.res_len = res_len;
liblte_mme_pack_authentication_response_msg(&auth_res, sec_hdr_type, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT *)pdu); liblte_mme_pack_authentication_response_msg(
&auth_res, sec_hdr_type, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get());
if(pcap != NULL) { if(pcap != NULL) {
pcap->write_nas(pdu->msg, pdu->N_bytes); pcap->write_nas(pdu->msg, pdu->N_bytes);
@ -1494,12 +1480,12 @@ void nas::send_authentication_response(const uint8_t* res, const size_t res_len,
} }
nas_log->info("Sending Authentication Response\n"); nas_log->info("Sending Authentication Response\n");
rrc->write_sdu(pdu); rrc->write_sdu(std::move(pdu));
} }
void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_fail_param) { void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_fail_param) {
byte_buffer_t *msg = pool_allocate_blocking; unique_byte_buffer msg = srslte::allocate_unique_buffer(*pool, true);
if (!msg) { if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_failure().\n"); nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_failure().\n");
return; return;
@ -1515,12 +1501,12 @@ void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_f
auth_failure.auth_fail_param_present = false; auth_failure.auth_fail_param_present = false;
} }
liblte_mme_pack_authentication_failure_msg(&auth_failure, (LIBLTE_BYTE_MSG_STRUCT *)msg); liblte_mme_pack_authentication_failure_msg(&auth_failure, (LIBLTE_BYTE_MSG_STRUCT*)msg.get());
if(pcap != NULL) { if(pcap != NULL) {
pcap->write_nas(msg->msg, msg->N_bytes); pcap->write_nas(msg->msg, msg->N_bytes);
} }
nas_log->info("Sending authentication failure.\n"); nas_log->info("Sending authentication failure.\n");
rrc->write_sdu(msg); rrc->write_sdu(std::move(msg));
} }
@ -1543,24 +1529,24 @@ void nas::send_identity_response(uint32_t lcid, uint8 id_type)
return; return;
} }
byte_buffer_t *pdu = pool_allocate_blocking; unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu) { if (!pdu) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_identity_response().\n"); nas_log->error("Fatal Error: Couldn't allocate PDU in send_identity_response().\n");
return; return;
} }
liblte_mme_pack_identity_response_msg(&id_resp, (LIBLTE_BYTE_MSG_STRUCT *) pdu); liblte_mme_pack_identity_response_msg(&id_resp, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get());
if(pcap != NULL) { if(pcap != NULL) {
pcap->write_nas(pdu->msg, pdu->N_bytes); pcap->write_nas(pdu->msg, pdu->N_bytes);
} }
rrc->write_sdu(pdu); rrc->write_sdu(std::move(pdu));
ctxt.tx_count++; ctxt.tx_count++;
} }
void nas::send_service_request() { void nas::send_service_request() {
byte_buffer_t *msg = pool_allocate_blocking; unique_byte_buffer msg = srslte::allocate_unique_buffer(*pool, true);
if (!msg) { if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_service_request().\n"); nas_log->error("Fatal Error: Couldn't allocate PDU in send_service_request().\n");
return; return;
@ -1591,7 +1577,7 @@ void nas::send_service_request() {
} }
nas_log->info("Sending service request\n"); nas_log->info("Sending service request\n");
rrc->write_sdu(msg); rrc->write_sdu(std::move(msg));
ctxt.tx_count++; ctxt.tx_count++;
} }
@ -1685,7 +1671,7 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) {
esm_info_resp.protocol_cnfg_opts_present = false; esm_info_resp.protocol_cnfg_opts_present = false;
} }
byte_buffer_t *pdu = pool_allocate_blocking; unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu) { if (!pdu) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_attach_request().\n"); nas_log->error("Fatal Error: Couldn't allocate PDU in send_attach_request().\n");
return; return;
@ -1694,7 +1680,7 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) {
if (liblte_mme_pack_esm_information_response_msg(&esm_info_resp, if (liblte_mme_pack_esm_information_response_msg(&esm_info_resp,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED,
ctxt.tx_count, ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *)pdu)) { (LIBLTE_BYTE_MSG_STRUCT*)pdu.get())) {
nas_log->error("Error packing ESM information response.\n"); nas_log->error("Error packing ESM information response.\n");
return; return;
} }
@ -1717,7 +1703,7 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) {
} }
nas_log->info_hex(pdu->msg, pdu->N_bytes, "Sending ESM information response\n"); nas_log->info_hex(pdu->msg, pdu->N_bytes, "Sending ESM information response\n");
rrc->write_sdu(pdu); rrc->write_sdu(std::move(pdu));
ctxt.tx_count++; ctxt.tx_count++;
chap_id++; chap_id++;

View File

@ -51,8 +51,7 @@ rrc::rrc() :
last_state(RRC_STATE_CONNECTED), last_state(RRC_STATE_CONNECTED),
drb_up(false), drb_up(false),
rlc_flush_timeout(2000), rlc_flush_timeout(2000),
rlc_flush_counter(0), rlc_flush_counter(0)
dedicated_info_nas(NULL)
{ {
n310_cnt = 0; n310_cnt = 0;
n311_cnt = 0; n311_cnt = 0;
@ -97,7 +96,7 @@ void rrc::srslte_rrc_log(const char* str)
} }
template <class T> template <class T>
void rrc::log_rrc_message(const std::string source, const direction_t dir, const unique_pool_buffer& pdu, const T& msg) void rrc::log_rrc_message(const std::string source, const direction_t dir, const byte_buffer_t* pdu, const T& msg)
{ {
if (rrc_log->get_level() == srslte::LOG_LEVEL_INFO) { if (rrc_log->get_level() == srslte::LOG_LEVEL_INFO) {
rrc_log->info("%s - %s %s (%d B)\n", source.c_str(), (dir == Rx) ? "Rx" : "Tx", rrc_log->info("%s - %s %s (%d B)\n", source.c_str(), (dir == Rx) ? "Rx" : "Tx",
@ -158,7 +157,6 @@ void rrc::init(phy_interface_rrc* phy_,
t311 = mac_timers->timer_get_unique_id(); t311 = mac_timers->timer_get_unique_id();
t304 = mac_timers->timer_get_unique_id(); t304 = mac_timers->timer_get_unique_id();
dedicated_info_nas.set_pool(pool);
ue_identity_configured = false; ue_identity_configured = false;
transaction_id = 0; transaction_id = 0;
@ -191,7 +189,7 @@ void rrc::stop() {
stop_timers(); stop_timers();
cmd_msg_t msg; cmd_msg_t msg;
msg.command = cmd_msg_t::STOP; msg.command = cmd_msg_t::STOP;
cmd_q.push(msg); cmd_q.push(std::move(msg));
wait_thread_finish(); wait_thread_finish();
} }
@ -425,7 +423,7 @@ void rrc::plmn_select(asn1::rrc::plmn_id_s plmn_id)
* it. Sends connectionRequest message and returns if message transmitted successfully. * it. Sends connectionRequest message and returns if message transmitted successfully.
* It does not wait until completition of Connection Establishment procedure * It does not wait until completition of Connection Establishment procedure
*/ */
bool rrc::connection_request(asn1::rrc::establishment_cause_e cause, srslte::unique_pool_buffer dedicated_info_nas) bool rrc::connection_request(asn1::rrc::establishment_cause_e cause, srslte::unique_byte_buffer dedicated_info_nas)
{ {
if (!plmn_is_selected) { if (!plmn_is_selected) {
@ -519,7 +517,7 @@ bool rrc::connection_request(asn1::rrc::establishment_cause_e cause, srslte::uni
if (!ret) { if (!ret) {
rrc_log->warning("Could not establish connection. Deallocating dedicatedInfoNAS PDU\n"); rrc_log->warning("Could not establish connection. Deallocating dedicatedInfoNAS PDU\n");
this->dedicated_info_nas.deallocate(); this->dedicated_info_nas.reset();
} }
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
@ -1432,7 +1430,7 @@ void rrc::send_con_restablish_complete() {
send_ul_dcch_msg(RB_ID_SRB1, ul_dcch_msg); send_ul_dcch_msg(RB_ID_SRB1, ul_dcch_msg);
} }
void rrc::send_con_setup_complete(srslte::unique_pool_buffer nas_msg) void rrc::send_con_setup_complete(srslte::unique_byte_buffer nas_msg)
{ {
rrc_log->debug("Preparing RRC Connection Setup Complete\n"); rrc_log->debug("Preparing RRC Connection Setup Complete\n");
@ -1450,7 +1448,7 @@ void rrc::send_con_setup_complete(srslte::unique_pool_buffer nas_msg)
send_ul_dcch_msg(RB_ID_SRB1, ul_dcch_msg); send_ul_dcch_msg(RB_ID_SRB1, ul_dcch_msg);
} }
void rrc::send_ul_info_transfer(unique_pool_buffer nas_msg) void rrc::send_ul_info_transfer(unique_byte_buffer nas_msg)
{ {
uint32_t lcid = rlc->has_bearer(RB_ID_SRB2) ? RB_ID_SRB2 : RB_ID_SRB1; uint32_t lcid = rlc->has_bearer(RB_ID_SRB2) ? RB_ID_SRB2 : RB_ID_SRB1;
@ -1659,9 +1657,9 @@ bool rrc::con_reconfig(asn1::rrc::rrc_conn_recfg_s* reconfig)
send_rrc_con_reconfig_complete(); send_rrc_con_reconfig_complete();
unique_pool_buffer nas_sdu(pool); unique_byte_buffer nas_sdu;
for (uint32_t i = 0; i < reconfig_r8->ded_info_nas_list.size(); i++) { for (uint32_t i = 0; i < reconfig_r8->ded_info_nas_list.size(); i++) {
nas_sdu.allocate(); nas_sdu = srslte::allocate_unique_buffer(*pool);
if (nas_sdu.get()) { if (nas_sdu.get()) {
memcpy(nas_sdu->msg, reconfig_r8->ded_info_nas_list[i].data(), reconfig_r8->ded_info_nas_list[i].size()); memcpy(nas_sdu->msg, reconfig_r8->ded_info_nas_list[i].data(), reconfig_r8->ded_info_nas_list[i].size());
nas_sdu->N_bytes = reconfig_r8->ded_info_nas_list[i].size(); nas_sdu->N_bytes = reconfig_r8->ded_info_nas_list[i].size();
@ -1767,13 +1765,13 @@ void rrc::stop_timers()
* *
* *
*******************************************************************************/ *******************************************************************************/
void rrc::write_pdu_bcch_bch(unique_pool_buffer pdu) void rrc::write_pdu_bcch_bch(unique_byte_buffer pdu)
{ {
// Do we need to do something with BCH? // Do we need to do something with BCH?
rrc_log->info_hex(pdu->msg, pdu->N_bytes, "BCCH BCH message received."); rrc_log->info_hex(pdu->msg, pdu->N_bytes, "BCCH BCH message received.");
} }
void rrc::write_pdu_bcch_dlsch(unique_pool_buffer pdu) void rrc::write_pdu_bcch_dlsch(unique_byte_buffer pdu)
{ {
// Stop BCCH search after successful reception of 1 BCCH block // Stop BCCH search after successful reception of 1 BCCH block
mac->bcch_stop_rx(); mac->bcch_stop_rx();
@ -1786,7 +1784,7 @@ void rrc::write_pdu_bcch_dlsch(unique_pool_buffer pdu)
return; return;
} }
log_rrc_message("BCCH", Rx, pdu, dlsch_msg); log_rrc_message("BCCH", Rx, pdu.get(), dlsch_msg);
if (dlsch_msg.msg.c1().type() == bcch_dl_sch_msg_type_c::c1_c_::types::sib_type1) { if (dlsch_msg.msg.c1().type() == bcch_dl_sch_msg_type_c::c1_c_::types::sib_type1) {
rrc_log->info("Processing SIB1 (1/1)\n"); rrc_log->info("Processing SIB1 (1/1)\n");
@ -1926,15 +1924,15 @@ void rrc::handle_sib13()
* *
* *
*******************************************************************************/ *******************************************************************************/
void rrc::write_pdu_pcch(unique_pool_buffer pdu) void rrc::write_pdu_pcch(unique_byte_buffer pdu)
{ {
cmd_msg_t msg; cmd_msg_t msg;
msg.pdu = std::move(pdu); msg.pdu = std::move(pdu);
msg.command = cmd_msg_t::PCCH; msg.command = cmd_msg_t::PCCH;
cmd_q.push(msg); cmd_q.push(std::move(msg));
} }
void rrc::process_pcch(unique_pool_buffer pdu) void rrc::process_pcch(unique_byte_buffer pdu)
{ {
if (pdu->N_bytes > 0 && pdu->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BITS) { if (pdu->N_bytes > 0 && pdu->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BITS) {
pcch_msg_s pcch_msg; pcch_msg_s pcch_msg;
@ -1944,7 +1942,7 @@ void rrc::process_pcch(unique_pool_buffer pdu)
return; return;
} }
log_rrc_message("PCCH", Rx, pdu, pcch_msg); log_rrc_message("PCCH", Rx, pdu.get(), pcch_msg);
paging_s* paging = &pcch_msg.msg.c1().paging(); paging_s* paging = &pcch_msg.msg.c1().paging();
if (paging->paging_record_list.size() > ASN1_RRC_MAX_PAGE_REC) { if (paging->paging_record_list.size() > ASN1_RRC_MAX_PAGE_REC) {
@ -1990,7 +1988,7 @@ void rrc::process_pcch(unique_pool_buffer pdu)
} }
} }
void rrc::write_pdu_mch(uint32_t lcid, srslte::unique_pool_buffer pdu) void rrc::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer pdu)
{ {
if (pdu->N_bytes > 0 && pdu->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BITS) { if (pdu->N_bytes > 0 && pdu->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BITS) {
//TODO: handle MCCH notifications and update MCCH //TODO: handle MCCH notifications and update MCCH
@ -2003,7 +2001,7 @@ void rrc::write_pdu_mch(uint32_t lcid, srslte::unique_pool_buffer pdu)
} }
serving_cell->has_mcch = true; serving_cell->has_mcch = true;
phy->set_config_mbsfn_mcch(&serving_cell->mcch); phy->set_config_mbsfn_mcch(&serving_cell->mcch);
log_rrc_message("MCH", Rx, pdu, serving_cell->mcch); log_rrc_message("MCH", Rx, pdu.get(), serving_cell->mcch);
} }
} }
} }
@ -2024,7 +2022,7 @@ void rrc::write_pdu_mch(uint32_t lcid, srslte::unique_pool_buffer pdu)
void rrc::send_ul_ccch_msg(const asn1::rrc::ul_ccch_msg_s& msg) void rrc::send_ul_ccch_msg(const asn1::rrc::ul_ccch_msg_s& msg)
{ {
// Reset and reuse sdu buffer if provided // Reset and reuse sdu buffer if provided
unique_pool_buffer pdcp_buf(pool_allocate_blocking, pool); unique_byte_buffer pdcp_buf = srslte::allocate_unique_buffer(*pool, true);
if (not pdcp_buf.get()) { if (not pdcp_buf.get()) {
rrc_log->error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack().\n"); rrc_log->error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack().\n");
return; return;
@ -2048,7 +2046,7 @@ void rrc::send_ul_ccch_msg(const asn1::rrc::ul_ccch_msg_s& msg)
mac->set_contention_id(uecri); mac->set_contention_id(uecri);
uint32_t lcid = RB_ID_SRB0; uint32_t lcid = RB_ID_SRB0;
log_rrc_message(get_rb_name(lcid).c_str(), Tx, pdcp_buf, msg); log_rrc_message(get_rb_name(lcid).c_str(), Tx, pdcp_buf.get(), msg);
pdcp->write_sdu(lcid, std::move(pdcp_buf)); pdcp->write_sdu(lcid, std::move(pdcp_buf));
} }
@ -2056,7 +2054,7 @@ void rrc::send_ul_ccch_msg(const asn1::rrc::ul_ccch_msg_s& msg)
void rrc::send_ul_dcch_msg(uint32_t lcid, const asn1::rrc::ul_dcch_msg_s& msg) void rrc::send_ul_dcch_msg(uint32_t lcid, const asn1::rrc::ul_dcch_msg_s& msg)
{ {
// Reset and reuse sdu buffer if provided // Reset and reuse sdu buffer if provided
unique_pool_buffer pdcp_buf(pool_allocate_blocking, pool); unique_byte_buffer pdcp_buf = srslte::allocate_unique_buffer(*pool, true);
if (not pdcp_buf.get()) { if (not pdcp_buf.get()) {
rrc_log->error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack().\n"); rrc_log->error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack().\n");
return; return;
@ -2068,12 +2066,12 @@ void rrc::send_ul_dcch_msg(uint32_t lcid, const asn1::rrc::ul_dcch_msg_s& msg)
pdcp_buf->N_bytes = (uint32_t)bref.distance_bytes(pdcp_buf->msg); pdcp_buf->N_bytes = (uint32_t)bref.distance_bytes(pdcp_buf->msg);
pdcp_buf->set_timestamp(); pdcp_buf->set_timestamp();
log_rrc_message(get_rb_name(lcid).c_str(), Tx, pdcp_buf, msg); log_rrc_message(get_rb_name(lcid).c_str(), Tx, pdcp_buf.get(), msg);
pdcp->write_sdu(lcid, std::move(pdcp_buf)); pdcp->write_sdu(lcid, std::move(pdcp_buf));
} }
void rrc::write_sdu(srslte::unique_pool_buffer sdu) void rrc::write_sdu(srslte::unique_byte_buffer sdu)
{ {
if (state == RRC_STATE_IDLE) { if (state == RRC_STATE_IDLE) {
@ -2083,7 +2081,7 @@ void rrc::write_sdu(srslte::unique_pool_buffer sdu)
send_ul_info_transfer(std::move(sdu)); send_ul_info_transfer(std::move(sdu));
} }
void rrc::write_pdu(uint32_t lcid, unique_pool_buffer pdu) void rrc::write_pdu(uint32_t lcid, unique_byte_buffer pdu)
{ {
// If the message contains a ConnectionSetup, acknowledge the transmission to avoid blocking of paging procedure // If the message contains a ConnectionSetup, acknowledge the transmission to avoid blocking of paging procedure
if (lcid == 0) { if (lcid == 0) {
@ -2110,10 +2108,10 @@ void rrc::write_pdu(uint32_t lcid, unique_pool_buffer pdu)
msg.pdu = std::move(pdu); msg.pdu = std::move(pdu);
msg.command = cmd_msg_t::PDU; msg.command = cmd_msg_t::PDU;
msg.lcid = (uint16_t)lcid; msg.lcid = (uint16_t)lcid;
cmd_q.push(msg); cmd_q.push(std::move(msg));
} }
void rrc::process_pdu(uint32_t lcid, srslte::unique_pool_buffer pdu) void rrc::process_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu)
{ {
switch (lcid) { switch (lcid) {
case RB_ID_SRB0: case RB_ID_SRB0:
@ -2129,7 +2127,7 @@ void rrc::process_pdu(uint32_t lcid, srslte::unique_pool_buffer pdu)
} }
} }
void rrc::parse_dl_ccch(unique_pool_buffer pdu) void rrc::parse_dl_ccch(unique_byte_buffer pdu)
{ {
asn1::bit_ref bref(pdu->msg, pdu->N_bytes); asn1::bit_ref bref(pdu->msg, pdu->N_bytes);
asn1::rrc::dl_ccch_msg_s dl_ccch_msg; asn1::rrc::dl_ccch_msg_s dl_ccch_msg;
@ -2138,7 +2136,7 @@ void rrc::parse_dl_ccch(unique_pool_buffer pdu)
rrc_log->error("Failed to unpack DL-CCCH message\n"); rrc_log->error("Failed to unpack DL-CCCH message\n");
return; return;
} }
log_rrc_message(get_rb_name(RB_ID_SRB0).c_str(), Rx, pdu, dl_ccch_msg); log_rrc_message(get_rb_name(RB_ID_SRB0).c_str(), Rx, pdu.get(), dl_ccch_msg);
dl_ccch_msg_type_c::c1_c_* c1 = &dl_ccch_msg.msg.c1(); dl_ccch_msg_type_c::c1_c_* c1 = &dl_ccch_msg.msg.c1();
switch (dl_ccch_msg.msg.c1().type().value) { switch (dl_ccch_msg.msg.c1().type().value) {
@ -2180,7 +2178,7 @@ void rrc::parse_dl_ccch(unique_pool_buffer pdu)
} }
} }
void rrc::parse_dl_dcch(uint32_t lcid, unique_pool_buffer pdu) void rrc::parse_dl_dcch(uint32_t lcid, unique_byte_buffer pdu)
{ {
asn1::bit_ref bref(pdu->msg, pdu->N_bytes); asn1::bit_ref bref(pdu->msg, pdu->N_bytes);
asn1::rrc::dl_dcch_msg_s dl_dcch_msg; asn1::rrc::dl_dcch_msg_s dl_dcch_msg;
@ -2189,12 +2187,12 @@ void rrc::parse_dl_dcch(uint32_t lcid, unique_pool_buffer pdu)
rrc_log->error("Failed to unpack DL-DCCH message\n"); rrc_log->error("Failed to unpack DL-DCCH message\n");
return; return;
} }
log_rrc_message(get_rb_name(lcid).c_str(), Rx, pdu, dl_dcch_msg); log_rrc_message(get_rb_name(lcid).c_str(), Rx, pdu.get(), dl_dcch_msg);
dl_dcch_msg_type_c::c1_c_* c1 = &dl_dcch_msg.msg.c1(); dl_dcch_msg_type_c::c1_c_* c1 = &dl_dcch_msg.msg.c1();
switch (dl_dcch_msg.msg.c1().type().value) { switch (dl_dcch_msg.msg.c1().type().value) {
case dl_dcch_msg_type_c::c1_c_::types::dl_info_transfer: case dl_dcch_msg_type_c::c1_c_::types::dl_info_transfer:
pdu = unique_pool_buffer(pool_allocate_blocking, pool); pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu.get()) { if (!pdu.get()) {
rrc_log->error("Fatal error: out of buffers in pool\n"); rrc_log->error("Fatal error: out of buffers in pool\n");
return; return;

View File

@ -70,13 +70,13 @@ namespace srslte {
class pdcp_dummy : public rrc_interface_pdcp, public pdcp_interface_gw class pdcp_dummy : public rrc_interface_pdcp, public pdcp_interface_gw
{ {
public: public:
void write_pdu(uint32_t lcid, byte_buffer_t *pdu) {} void write_pdu(uint32_t lcid, unique_byte_buffer pdu) {}
void write_pdu_bcch_bch(byte_buffer_t *pdu) {} void write_pdu_bcch_bch(unique_byte_buffer pdu) {}
void write_pdu_bcch_dlsch(byte_buffer_t *pdu) {} void write_pdu_bcch_dlsch(unique_byte_buffer pdu) {}
void write_pdu_pcch(byte_buffer_t *pdu) {} void write_pdu_pcch(unique_byte_buffer pdu) {}
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) {}
std::string get_rb_name(uint32_t lcid) { return std::string("lcid"); } std::string get_rb_name(uint32_t lcid) { return std::string("lcid"); }
void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu, bool blocking) {} void write_sdu(uint32_t lcid, srslte::unique_byte_buffer sdu, bool blocking) {}
bool is_lcid_enabled(uint32_t lcid) { return false; } bool is_lcid_enabled(uint32_t lcid) { return false; }
}; };
@ -89,12 +89,11 @@ public:
mnc_to_bytes(mnc, plmns.plmn_id.mnc); mnc_to_bytes(mnc, plmns.plmn_id.mnc);
plmns.tac = 0xffff; plmns.tac = 0xffff;
} }
void write_sdu(byte_buffer_t *sdu) void write_sdu(unique_byte_buffer sdu)
{ {
last_sdu_len = sdu->N_bytes; last_sdu_len = sdu->N_bytes;
//printf("NAS generated SDU (len=%d):\n", sdu->N_bytes); //printf("NAS generated SDU (len=%d):\n", sdu->N_bytes);
//srslte_vec_fprint_byte(stdout, sdu->msg, sdu->N_bytes); //srslte_vec_fprint_byte(stdout, sdu->msg, sdu->N_bytes);
byte_buffer_pool::get_instance()->deallocate(sdu);
} }
std::string get_rb_name(uint32_t lcid) { return std::string("lcid"); } std::string get_rb_name(uint32_t lcid) { return std::string("lcid"); }
uint32_t get_last_sdu_len() { return last_sdu_len; } uint32_t get_last_sdu_len() { return last_sdu_len; }
@ -106,12 +105,11 @@ public:
}; };
void plmn_select(plmn_id_s plmn_id){}; void plmn_select(plmn_id_s plmn_id){};
void set_ue_idenity(s_tmsi_s s_tmsi) {} void set_ue_idenity(s_tmsi_s s_tmsi) {}
bool connection_request(establishment_cause_e cause, srslte::byte_buffer_t* sdu) bool connection_request(establishment_cause_e cause, srslte::unique_byte_buffer sdu)
{ {
printf("NAS generated SDU (len=%d):\n", sdu->N_bytes); printf("NAS generated SDU (len=%d):\n", sdu->N_bytes);
last_sdu_len = sdu->N_bytes; last_sdu_len = sdu->N_bytes;
srslte_vec_fprint_byte(stdout, sdu->msg, sdu->N_bytes); srslte_vec_fprint_byte(stdout, sdu->msg, sdu->N_bytes);
byte_buffer_pool::get_instance()->deallocate(sdu);
return true; return true;
} }
bool is_connected() {return false;} bool is_connected() {return false;}
@ -128,8 +126,8 @@ private:
class gw_dummy : public gw_interface_nas, public gw_interface_pdcp class gw_dummy : public gw_interface_nas, public gw_interface_pdcp
{ {
error_t setup_if_addr(uint8_t pdn_type, uint32_t ip_addr, uint8_t *ipv6_if_id, char *err_str) { return ERROR_NONE; } error_t setup_if_addr(uint8_t pdn_type, uint32_t ip_addr, uint8_t *ipv6_if_id, char *err_str) { return ERROR_NONE; }
void write_pdu(uint32_t lcid, byte_buffer_t *pdu) {} void write_pdu(uint32_t lcid, unique_byte_buffer pdu) {}
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) {}
}; };
} }
@ -164,6 +162,7 @@ int security_command_test()
uint8_t res[16]; uint8_t res[16];
usim.init(&args, &usim_log); usim.init(&args, &usim_log);
{
srsue::nas nas; srsue::nas nas;
nas_args_t cfg; nas_args_t cfg;
cfg.eia = "1,2"; cfg.eia = "1,2";
@ -171,30 +170,32 @@ int security_command_test()
nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg); nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg);
// push auth request PDU to NAS to generate security context // push auth request PDU to NAS to generate security context
byte_buffer_t* tmp = byte_buffer_pool::get_instance()->allocate(); byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer tmp = srslte::allocate_unique_buffer(*pool, true);
memcpy(tmp->msg, auth_request_pdu, sizeof(auth_request_pdu)); memcpy(tmp->msg, auth_request_pdu, sizeof(auth_request_pdu));
tmp->N_bytes = sizeof(auth_request_pdu); tmp->N_bytes = sizeof(auth_request_pdu);
nas.write_pdu(LCID, tmp); nas.write_pdu(LCID, std::move(tmp));
// TODO: add check for authentication response // TODO: add check for authentication response
rrc_dummy.reset(); rrc_dummy.reset();
// reuse buffer for security mode command // reuse buffer for security mode command
tmp = srslte::allocate_unique_buffer(*pool, true);
memcpy(tmp->msg, sec_mode_command_pdu, sizeof(sec_mode_command_pdu)); memcpy(tmp->msg, sec_mode_command_pdu, sizeof(sec_mode_command_pdu));
tmp->N_bytes = sizeof(sec_mode_command_pdu); tmp->N_bytes = sizeof(sec_mode_command_pdu);
nas.write_pdu(LCID, tmp); nas.write_pdu(LCID, std::move(tmp));
// check length of generated NAS SDU // check length of generated NAS SDU
if (rrc_dummy.get_last_sdu_len() > 3) { if (rrc_dummy.get_last_sdu_len() > 3) {
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} }
}
byte_buffer_pool::get_instance()->cleanup(); byte_buffer_pool::get_instance()->cleanup();
return ret; return ret;
} }
int mme_attach_request_test() int mme_attach_request_test()
{ {
int ret = SRSLTE_ERROR; int ret = SRSLTE_ERROR;
@ -226,6 +227,7 @@ int mme_attach_request_test()
args.op = "63BFA50EE6523365FF14C1F45F88737D"; args.op = "63BFA50EE6523365FF14C1F45F88737D";
usim.init(&args, &usim_log); usim.init(&args, &usim_log);
{
nas_args_t nas_cfg; nas_args_t nas_cfg;
nas_cfg.force_imsi_attach = true; nas_cfg.force_imsi_attach = true;
nas_cfg.apn_name = "test123"; nas_cfg.apn_name = "test123";
@ -247,15 +249,18 @@ int mme_attach_request_test()
rrc_dummy.reset(); rrc_dummy.reset();
// finally push attach accept // finally push attach accept
byte_buffer_t* tmp = byte_buffer_pool::get_instance()->allocate(); byte_buffer_pool* pool = byte_buffer_pool::get_instance();
unique_byte_buffer tmp = srslte::allocate_unique_buffer(*pool, true);
memcpy(tmp->msg, attach_accept_pdu, sizeof(attach_accept_pdu)); memcpy(tmp->msg, attach_accept_pdu, sizeof(attach_accept_pdu));
tmp->N_bytes = sizeof(attach_accept_pdu); tmp->N_bytes = sizeof(attach_accept_pdu);
nas.write_pdu(LCID, tmp); nas.write_pdu(LCID, std::move(tmp));
// check length of generated NAS SDU (attach complete) // check length of generated NAS SDU (attach complete)
if (rrc_dummy.get_last_sdu_len() > 3) { if (rrc_dummy.get_last_sdu_len() > 3) {
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} }
// ensure buffers are deleted before pool cleanup
}
byte_buffer_pool::get_instance()->cleanup(); byte_buffer_pool::get_instance()->cleanup();
@ -296,6 +301,7 @@ int esm_info_request_test()
srslte::byte_buffer_pool *pool; srslte::byte_buffer_pool *pool;
pool = byte_buffer_pool::get_instance(); pool = byte_buffer_pool::get_instance();
{
srsue::nas nas; srsue::nas nas;
nas_args_t cfg; nas_args_t cfg;
cfg.apn_name = "srslte"; cfg.apn_name = "srslte";
@ -305,15 +311,16 @@ int esm_info_request_test()
nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg); nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg);
// push ESM info request PDU to NAS to generate response // push ESM info request PDU to NAS to generate response
byte_buffer_t* tmp = pool->allocate(); unique_byte_buffer tmp = srslte::allocate_unique_buffer(*pool, true);
memcpy(tmp->msg, esm_info_req_pdu, sizeof(esm_info_req_pdu)); memcpy(tmp->msg, esm_info_req_pdu, sizeof(esm_info_req_pdu));
tmp->N_bytes = sizeof(esm_info_req_pdu); tmp->N_bytes = sizeof(esm_info_req_pdu);
nas.write_pdu(LCID, tmp); nas.write_pdu(LCID, std::move(tmp));
// check length of generated NAS SDU // check length of generated NAS SDU
if (rrc_dummy.get_last_sdu_len() > 3) { if (rrc_dummy.get_last_sdu_len() > 3) {
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} }
}
pool->cleanup(); pool->cleanup();