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

master
Francisco Paisana 6 years ago committed by Andre Puschmann
parent 0976ea6f27
commit f469e2178b

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

@ -183,6 +183,8 @@ public:
log = NULL;
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() {
delete pool;
}
@ -222,24 +224,21 @@ private:
buffer_pool<byte_buffer_t> *pool;
};
inline bool byte_buffer_guard::allocate()
inline void byte_buffer_deleter::operator()(byte_buffer_t* buf) const
{
deallocate();
buf = pool->allocate();
if (buf == nullptr) {
// allocation failed
pool = nullptr;
return false;
if (buf) {
pool->deallocate(buf);
}
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) {
pool->deallocate(buf);
buf = nullptr;
}
return std::move(unique_byte_buffer(pool.allocate(nullptr, blocking), byte_buffer_deleter(&pool)));
}
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

@ -26,6 +26,7 @@
INCLUDES
*******************************************************************************/
#include <memory>
#include <stdint.h>
#include <string.h>
@ -266,79 +267,17 @@ private:
#endif
};
// Create a Managed Life-Time Byte Buffer
class byte_buffer_pool;
class byte_buffer_guard
class byte_buffer_deleter
{
public:
byte_buffer_guard(byte_buffer_pool* pool_) : pool(pool_) {}
byte_buffer_guard(byte_buffer_t* buf_, byte_buffer_pool* pool_) : buf(buf_), pool(pool_) {}
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;
explicit byte_buffer_deleter(byte_buffer_pool* pool_ = nullptr) : pool(pool_) {}
void operator()(byte_buffer_t* buf) const;
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

@ -179,7 +179,7 @@ class rlc_interface_pdcp
public:
/* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls
* 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;
};
@ -199,7 +199,7 @@ public:
class pdcp_interface_gtpu
{
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
@ -208,8 +208,8 @@ class pdcp_interface_rrc
public:
virtual void reset(uint16_t rnti) = 0;
virtual void add_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 rem_user(uint16_t rnti) = 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 config_security(uint16_t rnti,
uint32_t lcid,
@ -227,7 +227,7 @@ class pdcp_interface_rlc
{
public:
/* 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
@ -255,14 +255,14 @@ public:
class rrc_interface_pdcp
{
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
class rrc_interface_s1ap
{
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 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;
@ -274,7 +274,7 @@ public:
class gtpu_interface_pdcp
{
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
@ -290,9 +290,14 @@ public:
class s1ap_interface_rrc
{
public:
virtual void initial_ue(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM cause, srslte::byte_buffer_t *pdu) = 0;
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;
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) = 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_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;

@ -114,8 +114,8 @@ public:
class gw_interface_pdcp
{
public:
virtual void write_pdu(uint32_t lcid, srslte::unique_pool_buffer pdu) = 0;
virtual void write_pdu_mch(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_byte_buffer pdu) = 0;
};
// NAS interface for RRC
@ -132,7 +132,7 @@ public:
virtual void set_barring(barring_t barring) = 0;
virtual void paging(asn1::rrc::s_tmsi_s* ue_identiy) = 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 bool get_k_asme(uint8_t *k_asme_, uint32_t n) = 0;
virtual uint32_t get_ipv4_addr() = 0;
@ -189,13 +189,14 @@ public:
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_mnc() = 0;
virtual void enable_capabilities() = 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 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 bool is_connected() = 0;
virtual std::string get_rb_name(uint32_t lcid) = 0;
@ -205,11 +206,11 @@ public:
class rrc_interface_pdcp
{
public:
virtual void write_pdu(uint32_t lcid, srslte::unique_pool_buffer pdu) = 0;
virtual void write_pdu_bcch_bch(srslte::unique_pool_buffer pdu) = 0;
virtual void write_pdu_bcch_dlsch(srslte::unique_pool_buffer pdu) = 0;
virtual void write_pdu_pcch(srslte::unique_pool_buffer pdu) = 0;
virtual void write_pdu_mch(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_byte_buffer pdu) = 0;
virtual void write_pdu_bcch_dlsch(srslte::unique_byte_buffer pdu) = 0;
virtual void write_pdu_pcch(srslte::unique_byte_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;
};
@ -225,7 +226,7 @@ public:
class pdcp_interface_gw
{
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;
};
@ -235,7 +236,7 @@ class pdcp_interface_rrc
public:
virtual void reestablish() = 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 change_lcid(uint32_t old_lcid, uint32_t new_lcid) = 0;
virtual void config_security(uint32_t lcid,
@ -260,11 +261,11 @@ class pdcp_interface_rlc
{
public:
/* 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_bcch_bch(srslte::unique_pool_buffer sdu) = 0;
virtual void write_pdu_bcch_dlsch(srslte::unique_pool_buffer sdu) = 0;
virtual void write_pdu_pcch(srslte::unique_pool_buffer sdu) = 0;
virtual void write_pdu_mch(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_byte_buffer sdu) = 0;
virtual void write_pdu_bcch_dlsch(srslte::unique_byte_buffer sdu) = 0;
virtual void write_pdu_pcch(srslte::unique_byte_buffer sdu) = 0;
virtual void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) = 0;
};
// RLC interface for RRC
@ -289,7 +290,7 @@ class rlc_interface_pdcp
public:
/* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls
* 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;
};

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

@ -72,7 +72,7 @@ public:
bool is_active();
// 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_,
uint8_t *k_rrc_int_,
uint8_t *k_up_enc_,
@ -84,7 +84,7 @@ public:
uint32_t get_ul_count();
// RLC interface
void write_pdu(unique_pool_buffer pdu);
void write_pdu(unique_byte_buffer pdu);
private:
byte_buffer_pool *pool;

@ -50,7 +50,7 @@ public:
virtual bool is_active() = 0;
// 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_,
uint8_t *k_rrc_int_,
uint8_t *k_up_enc_,
@ -62,7 +62,7 @@ public:
virtual uint32_t get_ul_count() = 0;
// RLC interface
virtual void write_pdu(unique_pool_buffer pdu) = 0;
virtual void write_pdu(unique_byte_buffer pdu) = 0;
};
} // namespace srslte

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

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

@ -161,7 +161,7 @@ public:
virtual void reset_metrics() = 0;
// 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
virtual bool has_data() = 0;

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

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

@ -36,7 +36,7 @@ namespace srslte {
struct rlc_umd_pdu_t{
rlc_umd_pdu_header_t header;
byte_buffer_t *buf;
unique_byte_buffer buf;
};
class rlc_um
@ -60,7 +60,7 @@ public:
uint32_t get_bearer();
// PDCP interface
void write_sdu(byte_buffer_t *sdu, bool blocking = true);
void write_sdu(unique_byte_buffer sdu, bool blocking = true);
// MAC interface
bool has_data();
@ -87,8 +87,8 @@ private:
void stop();
void reestablish();
void empty_queue();
void write_sdu(byte_buffer_t *sdu);
void try_write_sdu(byte_buffer_t *sdu);
void write_sdu(unique_byte_buffer sdu);
void try_write_sdu(unique_byte_buffer sdu);
uint32_t get_num_tx_bytes();
void reset_metrics();
bool has_data();
@ -107,7 +107,7 @@ private:
// TX SDU buffers
rlc_tx_queue tx_sdu_queue;
byte_buffer_t *tx_sdu;
unique_byte_buffer tx_sdu;
/****************************************************************************
* State variables and counters
@ -168,7 +168,7 @@ private:
std::map<uint32_t, rlc_umd_pdu_t> rx_window;
// RX SDU buffers
byte_buffer_t *rx_sdu;
unique_byte_buffer rx_sdu;
uint32_t vr_ur_in_rx_sdu;
// Rx state variables and counter
@ -220,9 +220,9 @@ private:
* Header pack/unpack helper functions
* 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_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);
bool rlc_um_start_aligned(uint8_t fi);

@ -117,7 +117,7 @@ bool pdcp::is_lcid_enabled(uint32_t lcid)
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);
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);
}
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);
if (valid_mch_lcid(lcid)){
@ -276,7 +276,7 @@ uint32_t pdcp::get_ul_count(uint32_t lcid)
/*******************************************************************************
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);
if (valid_lcid(lcid)) {
@ -287,22 +287,22 @@ void pdcp::write_pdu(uint32_t lcid, unique_pool_buffer pdu)
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));
}
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));
}
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));
}
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) {
rrc->write_pdu_mch(lcid, std::move(sdu));

@ -112,7 +112,7 @@ bool pdcp_entity::is_active()
}
// 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,
"TX %s SDU, SN: %d, do_integrity = %s, do_encryption = %s",
@ -178,7 +178,7 @@ void pdcp_entity::enable_encryption()
}
// 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",
rrc->get_rb_name(lcid).c_str(), (do_integrity) ? "true" : "false", (do_encryption) ? "true" : "false");

@ -199,7 +199,7 @@ void rlc::empty_queue()
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)
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);
if (valid_lcid(lcid)) {
rlc_array.at(lcid)->write_sdu(sdu, blocking);
rlc_array.at(lcid)->write_sdu(std::move(sdu), blocking);
} else {
rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid);
}
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);
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 {
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)
{
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) {
memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes;
buf->set_timestamp();
pdcp->write_pdu_bcch_bch(buf);
pdcp->write_pdu_bcch_bch(std::move(buf));
} else {
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)
{
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) {
memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes;
buf->set_timestamp();
pdcp->write_pdu_bcch_dlsch(buf);
pdcp->write_pdu_bcch_dlsch(std::move(buf));
} else {
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)
{
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) {
memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes;
buf->set_timestamp();
pdcp->write_pdu_pcch(buf);
pdcp->write_pdu_pcch(std::move(buf));
} else {
rlc_log->error("Fatal error: Out of buffers from the pool in write_pdu_pcch()\n");
}

@ -128,9 +128,9 @@ void rlc_am::reset_metrics()
* 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),
pdu_without_poll(0),
byte_without_poll(0),
tx_sdu(NULL),
log(NULL),
cfg(),
tx_status(),
@ -258,10 +257,6 @@ void rlc_am::rlc_am_tx::stop()
byte_without_poll = 0;
// 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();
// Drop all messages in RETX queue
@ -275,16 +270,12 @@ void rlc_am::rlc_am_tx::empty_queue()
// deallocate all SDUs in transmit queue
while(tx_sdu_queue.size() > 0) {
byte_buffer_t *buf;
unique_byte_buffer buf;
tx_sdu_queue.read(&buf);
pool->deallocate(buf);
}
// deallocate SDU that is currently processed
if (tx_sdu != NULL) {
pool->deallocate(tx_sdu);
tx_sdu = NULL;
}
tx_sdu.reset();
pthread_mutex_unlock(&mutex);
}
@ -362,7 +353,7 @@ uint32_t rlc_am::rlc_am_tx::get_buffer_state()
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) {
return;
@ -371,15 +362,20 @@ void rlc_am::rlc_am_tx::write_sdu(unique_pool_buffer sdu, bool blocking)
if (sdu.get() != NULL) {
if (blocking) {
// 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());
tx_sdu_queue.write(std::move(sdu));
} else {
// 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))) {
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 {
log->info_hex(sdu->msg, sdu->N_bytes, "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", RB_NAME,
sdu->N_bytes, tx_sdu_queue.size());
#warning Find a more elegant solution - the msg was already deallocated at this point
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 {
@ -783,7 +779,7 @@ int rlc_am::rlc_am_tx::build_data_pdu(uint8_t *payload, uint32_t nof_bytes)
return 0;
}
byte_buffer_t *pdu = pool_allocate_blocking;
unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (pdu == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG
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",
RB_NAME, nof_bytes, head_len);
pool->deallocate(pdu);
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",
RB_NAME, tx_sdu->get_latency_us());
pool->deallocate(tx_sdu);
tx_sdu = NULL;
tx_sdu.reset();
}
if (pdu_space > to_move) {
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) {
log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
RB_NAME, tx_sdu->get_latency_us());
pool->deallocate(tx_sdu);
tx_sdu = NULL;
tx_sdu.reset();
}
if(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;
// 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].is_acked = false;
tx_window[header.sn].retx_count = 0;
const byte_buffer_t* buffer_ptr = tx_window[header.sn].buf.get();
uint8_t *ptr = payload;
rlc_am_write_data_pdu_header(&header, &ptr);
memcpy(ptr, pdu->msg, pdu->N_bytes);
int total_len = (ptr-payload) + pdu->N_bytes;
memcpy(ptr, buffer_ptr->msg, buffer_ptr->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->debug("%s\n", rlc_amd_pdu_header_to_string(header).c_str());
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);
if (it != tx_window.end()) {
if(update_vt_a) {
if (it->second.buf != NULL) {
pool->deallocate(it->second.buf);
it->second.buf = 0;
}
tx_window.erase(it);
vt_a = (vt_a + 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)
,poll_received(false)
,do_status(false)
,rx_sdu(NULL)
{
pthread_mutex_init(&mutex, NULL);
}
@ -1205,10 +1194,7 @@ void rlc_am::rlc_am_rx::stop()
reordering_timer = NULL;
}
if (rx_sdu != NULL) {
pool->deallocate(rx_sdu);
rx_sdu = NULL;
}
rx_sdu.reset();
vr_r = 0;
vr_mr = RLC_AM_WINDOW_SIZE;
@ -1220,22 +1206,9 @@ void rlc_am::rlc_am_rx::stop()
do_status = false;
// 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();
// 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();
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
rlc_amd_rx_pdu_t pdu;
pdu.buf = pool_allocate_blocking;
pdu.buf = srslte::allocate_unique_buffer(*pool, true);
if (pdu.buf == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG
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()) {
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());
pool->deallocate(pdu.buf);
return;
}
memcpy(pdu.buf->msg, payload, nof_bytes);
pdu.buf->N_bytes = nof_bytes;
pdu.header = header;
rx_window[header.sn] = pdu;
rx_window[header.sn] = std::move(pdu);
// Update 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;
segment.buf = pool_allocate_blocking;
segment.buf = srslte::allocate_unique_buffer(*pool, true);
if (segment.buf == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG
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
// 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)) {
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);
}
@ -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
rlc_amd_rx_pdu_segments_t pdu;
pdu.segments.push_back(segment);
rx_segments[header.sn] = pdu;
pdu.segments.push_back(std::move(segment));
rx_segments[header.sn] = std::move(pdu);
// Update 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;
if (rx_sdu == NULL) {
rx_sdu = pool_allocate_blocking;
rx_sdu = allocate_unique_buffer(*pool, true);
if (rx_sdu == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG
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;
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();
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) {
#ifdef RLC_AM_BUFFER_DEBUG
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 {
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;
}
} else {
log->error("Cannot fit RLC PDU in SDU buffer, dropping both.\n");
pool->deallocate(rx_sdu);
rx_sdu.reset();
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;
} else {
log->error("Cannot fit RLC PDU in SDU buffer, dropping both. Erasing SN=%d.\n", vr_r);
pool->deallocate(rx_sdu);
pool->deallocate(rx_window[vr_r].buf);
rx_sdu.reset();
rx_window.erase(vr_r);
}
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);
rx_sdu->set_timestamp();
parent->pdcp->write_pdu(parent->lcid, rx_sdu);
rx_sdu = pool_allocate_blocking;
parent->pdcp->write_pdu(parent->lcid, std::move(rx_sdu));
rx_sdu = allocate_unique_buffer(*pool, true);
if (rx_sdu == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG
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;
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);
pool->deallocate(segit->buf);
}
it->second.segments.clear();
}
pool->deallocate(rx_window[vr_r].buf);
rx_window.erase(vr_r);
vr_r = (vr_r + 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());
}
// 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)
{
// Check for first segment
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.push_back(*segment);
pdu->segments.push_back(std::move(*segment));
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) {
log->warning("Received PDU with SO=%d, expected %d. Discarding PDU.\n", segment->header.so, n);
pool->deallocate(segment->buf);
return false;
} else {
pdu->segments.push_back(*segment);
pdu->segments.push_back(std::move(*segment));
}
// 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());
// 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) {
#ifdef RLC_AM_BUFFER_DEBUG
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);
pool->deallocate(full_pdu);
return true;
}

@ -63,9 +63,8 @@ bool rlc_tm::configure(srslte_rlc_config_t cnfg)
void rlc_tm::empty_queue()
{
// Drop all messages in TX queue
byte_buffer_t *buf;
unique_byte_buffer buf;
while (ul_queue.try_read(&buf)) {
pool->deallocate(buf);
}
ul_queue.reset();
}
@ -92,25 +91,34 @@ uint32_t rlc_tm::get_bearer()
}
// 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) {
byte_buffer_pool::get_instance()->deallocate(sdu);
return;
}
if (sdu) {
if (blocking) {
ul_queue.write(sdu);
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());
ul_queue.write(std::move(sdu));
} else {
if (ul_queue.try_write(sdu)) {
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());
uint8_t* msg_ptr = sdu->msg;
uint32_t nof_bytes = sdu->N_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 {
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());
pool->deallocate(sdu);
#warning Find a more elegant solution - the msg was already deallocated at this point
log->info("[Dropped SDU] %s Tx SDU, queue size=%d, bytes=%d",
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 {
@ -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);
return -1;
}
byte_buffer_t *buf;
unique_byte_buffer buf;
if (ul_queue.try_read(&buf)) {
pdu_size = buf->N_bytes;
memcpy(payload, buf->msg, buf->N_bytes);
log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n",
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",
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)
{
byte_buffer_t *buf = pool_allocate;
unique_byte_buffer buf = allocate_unique_buffer(*pool);
if (buf) {
memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes;
buf->set_timestamp();
num_rx_bytes += nof_bytes;
pdcp->write_pdu(lcid, buf);
pdcp->write_pdu(lcid, std::move(buf));
} else {
log->error("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu().\n");
}

@ -140,12 +140,12 @@ uint32_t rlc_um::get_bearer()
/****************************************************************************
* 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) {
tx.write_sdu(sdu);
tx.write_sdu(std::move(sdu));
} 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() :
pool(byte_buffer_pool::get_instance()),
log(NULL),
tx_sdu(NULL),
vt_us(0),
tx_enabled(false),
num_tx_bytes(0)
@ -272,16 +271,12 @@ void rlc_um::rlc_um_tx::empty_queue()
// deallocate all SDUs in transmit queue
while(tx_sdu_queue.size() > 0) {
byte_buffer_t *buf;
unique_byte_buffer buf;
tx_sdu_queue.read(&buf);
pool->deallocate(buf);
}
// deallocate SDU that is currently processed
if(tx_sdu) {
pool->deallocate(tx_sdu);
tx_sdu = NULL;
}
tx_sdu.reset();
pthread_mutex_unlock(&mutex);
}
@ -329,36 +324,38 @@ uint32_t rlc_um::rlc_um_tx::get_buffer_state()
return n_bytes;
}
void rlc_um::rlc_um_tx::write_sdu(byte_buffer_t *sdu)
void rlc_um::rlc_um_tx::write_sdu(unique_byte_buffer sdu)
{
if (!tx_enabled) {
byte_buffer_pool::get_instance()->deallocate(sdu);
return;
}
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());
tx_sdu_queue.write(std::move(sdu));
} else {
log->warning("NULL SDU pointer in write_sdu()\n");
}
}
void rlc_um::rlc_um_tx::try_write_sdu(byte_buffer_t *sdu)
void rlc_um::rlc_um_tx::try_write_sdu(unique_byte_buffer sdu)
{
if (!tx_enabled) {
byte_buffer_pool::get_instance()->deallocate(sdu);
sdu.reset();
return;
}
if (sdu) {
if (tx_sdu_queue.try_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());
uint8_t* msg_ptr = sdu->msg;
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 {
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());
pool->deallocate(sdu);
#warning Find a more elegant solution - the msg was already deallocated at this point
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 {
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;
}
byte_buffer_t *pdu = pool_allocate;
unique_byte_buffer pdu = allocate_unique_buffer(*pool);
if(!pdu || pdu->N_bytes != 0) {
log->error("Failed to allocate PDU buffer\n");
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;
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)
{
pool->deallocate(pdu);
log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n",
get_rb_name(), nof_bytes, head_len);
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",
get_rb_name(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu);
tx_sdu = NULL;
tx_sdu.reset();
}
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
@ -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",
get_rb_name(), tx_sdu->get_latency_us());
pool->deallocate(tx_sdu);
tx_sdu = NULL;
tx_sdu.reset();
}
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;
// 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);
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);
pool->deallocate(pdu);
debug_state();
@ -509,7 +502,6 @@ rlc_um::rlc_um_rx::rlc_um_rx()
,log(NULL)
,pdcp(NULL)
,rrc(NULL)
,rx_sdu(NULL)
,vr_ur(0)
,vr_ux (0)
,vr_uh(0)
@ -582,16 +574,9 @@ void rlc_um::rlc_um_rx::reset()
pdu_lost = false;
rx_enabled = false;
if (rx_sdu) {
pool->deallocate(rx_sdu);
rx_sdu = NULL;
}
rx_sdu.reset();
// 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();
}
@ -630,7 +615,7 @@ void rlc_um::rlc_um_rx::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
}
// Write to rx window
pdu.buf = pool_allocate;
pdu.buf = allocate_unique_buffer(*pool);
if (!pdu.buf) {
log->error("Discarting packet: no space in buffer pool\n");
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->N_bytes -= header_len;
pdu.header = header;
rx_window[header.sn] = pdu;
rx_window[header.sn] = std::move(pdu);
// Update vr_uh
if(!inside_reordering_window(header.sn)) {
@ -681,7 +666,7 @@ unlock_and_exit:
void rlc_um::rlc_um_rx::reassemble_rx_sdus()
{
if(!rx_sdu) {
rx_sdu = pool_allocate;
rx_sdu = allocate_unique_buffer(*pool);
if (!rx_sdu) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
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);
rx_sdu->set_timestamp();
if(cfg.is_mrb){
pdcp->write_pdu_mch(lcid, rx_sdu);
pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} 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) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
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);
rx_sdu->set_timestamp();
if(cfg.is_mrb){
pdcp->write_pdu_mch(lcid, rx_sdu);
pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} 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) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return;
@ -769,7 +754,6 @@ void rlc_um::rlc_um_rx::reassemble_rx_sdus()
}
// Clean up rx_window
pool->deallocate(rx_window[vr_ur].buf);
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);
rx_sdu->set_timestamp();
if(cfg.is_mrb){
pdcp->write_pdu_mch(lcid, rx_sdu);
pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} 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) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
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);
rx_sdu->set_timestamp();
if(cfg.is_mrb){
pdcp->write_pdu_mch(lcid, rx_sdu);
pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} 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) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return;
@ -896,7 +880,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);
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
***************************************************************************/
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);
}
@ -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;
uint8_t ext = (header->N_li > 0) ? 1 : 0;

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

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

@ -146,7 +146,8 @@ public:
private:
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) {
printf("Fatal Error: Could not allocate PDU in mac_reader::run_thread\n");
exit(-1);
@ -175,7 +176,6 @@ private:
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()
@ -229,7 +229,7 @@ public:
}
// 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);
if (sdu->N_bytes != args.sdu_size) {
@ -237,14 +237,13 @@ public:
exit(-1);
}
byte_buffer_pool::get_instance()->deallocate(sdu);
rx_pdus++;
}
void write_pdu_bcch_bch(byte_buffer_t *sdu) {}
void write_pdu_bcch_dlsch(byte_buffer_t *sdu) {}
void write_pdu_pcch(byte_buffer_t *sdu) {}
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu) {}
void write_pdu_bcch_bch(unique_byte_buffer sdu) {}
void write_pdu_bcch_dlsch(unique_byte_buffer sdu) {}
void write_pdu_pcch(unique_byte_buffer sdu) {}
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) {}
// RRC interface
void max_retx_attempted(){}
std::string get_rb_name(uint32_t rx_lcid) { return std::string("DRB1"); }
@ -254,8 +253,9 @@ public:
private:
void run_thread() {
uint8_t sn = 0;
byte_buffer_pool* pool = byte_buffer_pool::get_instance();
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) {
printf("Error: Could not allocate PDU in rlc_tester::run_thread\n\n\n");
// backoff for a bit
@ -267,7 +267,7 @@ private:
}
sn++;
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) {
usleep(args.sdu_gen_delay_usec);
}

@ -67,29 +67,21 @@ public:
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
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) {
printf("Received PDU with size %d, expected %d. Exiting.\n", sdu->N_bytes, expected_sdu_len);
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_dlsch(byte_buffer_t *sdu) {}
void write_pdu_pcch(byte_buffer_t *sdu) {}
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu)
void write_pdu_bcch_bch(unique_byte_buffer sdu) {}
void write_pdu_bcch_dlsch(unique_byte_buffer sdu) {}
void write_pdu_pcch(unique_byte_buffer 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
@ -97,7 +89,7 @@ public:
std::string get_rb_name(uint32_t lcid) { return std::string(""); }
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;
uint32_t expected_sdu_len;
};
@ -136,12 +128,14 @@ int basic_test()
tester.set_expected_sdu_len(1);
// 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++)
{
*sdu_bufs[i].msg = i; // Write the index into the buffer
sdu_bufs[i].N_bytes = 1; // Give each buffer a size of 1 byte
rlc1.write_sdu(&sdu_bufs[i]);
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
*sdu_bufs[i]->msg = i; // Write the index into the buffer
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());
@ -208,12 +202,14 @@ int loss_test()
tester.set_expected_sdu_len(1);
// 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++)
{
*sdu_bufs[i].msg = i; // Write the index into the buffer
sdu_bufs[i].N_bytes = 1; // Give each buffer a size of 1 byte
rlc1.write_sdu(&sdu_bufs[i]);
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
sdu_bufs[i]->msg[0] = i; // Write the index into the buffer
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());
@ -272,12 +268,14 @@ int basic_mbsfn_test()
tester.set_expected_sdu_len(1);
// 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++)
{
*sdu_bufs[i].msg = i; // Write the index into the buffer
sdu_bufs[i].N_bytes = 1; // Give each buffer a size of 1 byte
rlc1.write_sdu(&sdu_bufs[i]);
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
sdu_bufs[i]->msg[0] = i; // Write the index into the buffer
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());
@ -358,16 +356,18 @@ int reassmble_test()
tester.set_expected_sdu_len(sdu_len);
byte_buffer_t sdu_bufs[n_sdus];
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++) {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
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
rlc1.write_sdu(&sdu_bufs[i]);
sdu_bufs[i]->N_bytes = sdu_len; // Give each buffer a size of 1 byte
rlc1.write_sdu(std::move(sdu_bufs[i]));
}
// 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
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) {
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
rlc1.write_sdu(&sdu_bufs[i]);
sdu_bufs[i]->N_bytes = sdu_len; // Give each buffer a size of 1 byte
rlc1.write_sdu(std::move(sdu_bufs[i]));
}
// Read second batch of PDUs (use large grants)
@ -475,15 +476,16 @@ int reassmble_test2()
tester.set_expected_sdu_len(sdu_len);
byte_buffer_t sdu_bufs[n_sdus];
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++) {
sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true);
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;
rlc1.write_sdu(&sdu_bufs[i]);
sdu_bufs[i]->N_bytes = sdu_len;
rlc1.write_sdu(std::move(sdu_bufs[i]));
}
const int max_n_pdus = 100;
@ -506,11 +508,12 @@ int reassmble_test2()
// push second batch of SDUs
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) {
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
rlc1.write_sdu(&sdu_bufs[i]);
sdu_bufs[i]->N_bytes = sdu_len; // Give each buffer a size of 1 byte
rlc1.write_sdu(std::move(sdu_bufs[i]));
}
// Read second batch of PDUs

@ -53,7 +53,7 @@ public:
void rem_user(uint16_t rnti);
// 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:
static const int THREAD_PRIO = 65;

@ -39,14 +39,14 @@ public:
void stop();
// pdcp_interface_rlc
void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu);
void write_pdu_mch(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::unique_byte_buffer sdu) {}
// pdcp_interface_rrc
void reset(uint16_t rnti);
void add_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 config_security(uint16_t rnti,
uint32_t lcid,
@ -65,7 +65,7 @@ private:
uint16_t rnti;
srsenb::rlc_interface_pdcp *rlc;
// 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);
};
@ -75,8 +75,8 @@ private:
uint16_t rnti;
srsenb::gtpu_interface_pdcp *gtpu;
// gw_interface_pdcp
void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu);
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu){}
void write_pdu(uint32_t lcid, srslte::unique_byte_buffer pdu);
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) {}
};
class user_interface_rrc : public srsue::rrc_interface_pdcp
@ -85,11 +85,11 @@ private:
uint16_t rnti;
srsenb::rrc_interface_pdcp *rrc;
// rrc_interface_pdcp
void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu);
void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu);
void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu);
void write_pdu_pcch(srslte::byte_buffer_t *pdu);
void write_pdu_mch(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::unique_byte_buffer pdu);
void write_pdu_bcch_dlsch(srslte::unique_byte_buffer pdu);
void write_pdu_pcch(srslte::unique_byte_buffer pdu);
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer pdu) {}
std::string get_rb_name(uint32_t lcid);
};

@ -55,7 +55,7 @@ public:
void add_bearer_mrb(uint16_t rnti, uint32_t lcid);
// 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);
std::string get_rb_name(uint32_t lcid);
@ -71,12 +71,12 @@ private:
public srsue::rrc_interface_rlc,
public srsue::ue_interface
{
public:
void write_pdu(uint32_t lcid, srslte::byte_buffer_t *sdu);
void write_pdu_bcch_bch(srslte::byte_buffer_t *sdu);
void write_pdu_bcch_dlsch(srslte::byte_buffer_t *sdu);
void write_pdu_pcch(srslte::byte_buffer_t *sdu);
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu){}
public:
void write_pdu(uint32_t lcid, srslte::unique_byte_buffer sdu);
void write_pdu_bcch_bch(srslte::unique_byte_buffer sdu);
void write_pdu_bcch_dlsch(srslte::unique_byte_buffer sdu);
void write_pdu_pcch(srslte::unique_byte_buffer sdu);
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) {}
void max_retx_attempted();
std::string get_rb_name(uint32_t lcid);
uint16_t rnti;

@ -153,7 +153,7 @@ public:
void max_retx_attempted(uint16_t rnti);
// 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);
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);
@ -161,7 +161,7 @@ public:
void add_paging_id(uint32_t ueid, LIBLTE_S1AP_UEPAGINGID_STRUCT UEPagingID);
// 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();
uint32_t get_nof_users();
@ -207,17 +207,17 @@ public:
void send_connection_reject();
void send_connection_release();
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_upd(srslte::byte_buffer_t *pdu);
void send_connection_reconf_upd(srslte::unique_byte_buffer pdu);
void send_security_mode_command();
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_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_reconf_complete(asn1::rrc::rrc_conn_recfg_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::unique_byte_buffer pdu);
void handle_security_mode_complete(asn1::rrc::security_mode_complete_s* msg);
void handle_security_mode_failure(asn1::rrc::security_mode_fail_s* msg);
bool handle_ue_cap_info(asn1::rrc::ue_cap_info_s* msg);
@ -246,7 +246,8 @@ public:
bool select_security_algorithms();
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;
rrc* parent;
@ -315,7 +316,7 @@ private:
activity_monitor act_monitor;
std::vector<srslte::byte_buffer_t*> sib_buffer;
std::vector<srslte::unique_byte_buffer> sib_buffer;
// user connect notifier
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 config_mac();
void parse_ul_dcch(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *pdu);
void parse_ul_ccch(uint16_t rnti, 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::unique_byte_buffer pdu);
void configure_security(uint16_t rnti,
uint32_t lcid,
uint8_t *k_rrc_enc,
@ -351,9 +352,9 @@ private:
srslte::log* rrc_log;
typedef struct{
uint16_t rnti;
uint32_t lcid;
srslte::byte_buffer_t* pdu;
uint16_t rnti;
uint32_t lcid;
srslte::unique_byte_buffer pdu;
}rrc_pdu;
const static uint32_t LCID_EXIT = 0xffff0000;

@ -68,9 +68,13 @@ public:
void run_thread();
// 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::byte_buffer_t *pdu, uint32_t m_tmsi, uint8_t mmec);
void write_pdu(uint16_t rnti, 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::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_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio);
void ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *res);
@ -112,7 +116,7 @@ private:
bool connect_mme();
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_successfuloutcome(LIBLTE_S1AP_SUCCESSFULOUTCOME_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_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_ulnastransport(uint16_t rnti, srslte::byte_buffer_t *pdu);
bool send_initialuemessage(uint16_t rnti,
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_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_);

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

@ -111,7 +111,7 @@ void gtpu::stop()
}
// 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_header_t header;
@ -191,8 +191,7 @@ void gtpu::rem_user(uint16_t rnti)
void gtpu::run_thread()
{
unique_pool_buffer pdu(pool);
pdu.allocate();
unique_byte_buffer pdu = allocate_unique_buffer(*pool);
if (!pdu.get()) {
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));
do {
pdu.allocate();
pdu = allocate_unique_buffer(*pool);
if (!pdu.get()) {
gtpu_log->console("GTPU Buffer pool empty. Trying again...\n");
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_header_t header;
unique_pool_buffer pdu(pool);
pdu.allocate();
unique_byte_buffer pdu = allocate_unique_buffer(*pool);
//header
header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL | GTPU_FLAGS_SEQUENCE;
@ -371,7 +369,7 @@ void gtpu::mch_thread::run_thread()
return;
}
unique_pool_buffer pdu(pool);
unique_byte_buffer pdu = allocate_unique_buffer(*pool);
int n;
socklen_t addrlen;
sockaddr_in src_addr;
@ -385,8 +383,6 @@ void gtpu::mch_thread::run_thread()
run_enable = true;
running=true;
pdu.allocate();
// Warning: Use mutex here if creating multiple services each with a different thread
uint16_t lcid = lcid_counter;
lcid_counter++;
@ -405,7 +401,7 @@ void gtpu::mch_thread::run_thread()
gtpu_read_header(pdu.get(), &header, gtpu_log);
pdcp->write_sdu(SRSLTE_MRNTI, lcid, std::move(pdu));
do {
pdu.allocate();
pdu = allocate_unique_buffer(*pool);
if (!pdu.get()) {
gtpu_log->console("GTPU Buffer pool empty. Trying again...\n");
usleep(10000);

@ -130,60 +130,58 @@ void pdcp::enable_encryption(uint16_t rnti, uint32_t lcid)
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);
if (users.count(rnti)) {
users[rnti].pdcp->write_pdu(lcid, sdu);
} else {
pool->deallocate(sdu);
users[rnti].pdcp->write_pdu(lcid, std::move(sdu));
}
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);
if (users.count(rnti)) {
if(rnti != SRSLTE_MRNTI){
users[rnti].pdcp->write_sdu(lcid, sdu);
users[rnti].pdcp->write_sdu(lcid, std::move(sdu));
}else {
users[rnti].pdcp->write_sdu_mch(lcid, sdu);
users[rnti].pdcp->write_sdu_mch(lcid, std::move(sdu));
}
}
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) {
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);
}
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);
}
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);
}

@ -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);
}
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;
pthread_rwlock_rdlock(&rwlock);
if (users.count(rnti)) {
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);
}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);
}
// 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;
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);
} else {
pool->deallocate(sdu);
}
pthread_rwlock_unlock(&rwlock);
}
@ -218,22 +215,22 @@ void rlc::user_interface::max_retx_attempted()
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);
}
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);
}
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);
}

@ -86,7 +86,7 @@ void rrc::stop()
if(running) {
running = false;
rrc_pdu p = {0, LCID_EXIT, NULL};
rx_pdu_queue.push(p);
rx_pdu_queue.push(std::move(p));
wait_thread_finish();
}
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)
{
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)
{
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)
{
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() {
@ -223,7 +223,7 @@ void rrc::upd_user(uint16_t new_rnti, uint16_t old_rnti)
pthread_mutex_lock(&user_mutex);
if (users.count(old_rnti) == 1) {
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 {
users[old_rnti].send_connection_release();
}
@ -236,16 +236,16 @@ void rrc::upd_user(uint16_t new_rnti, uint16_t old_rnti)
/*******************************************************************************
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};
rx_pdu_queue.push(p);
rrc_pdu p = {rnti, lcid, std::move(pdu)};
rx_pdu_queue.push(std::move(p));
}
/*******************************************************************************
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.msg.set_c1();
@ -264,8 +264,8 @@ void rrc::write_dl_info(uint16_t rnti, byte_buffer_t* sdu)
sdu->msg, sdu->N_bytes);
sdu->reset();
users[rnti].send_dl_dcch(&dl_dcch_msg, sdu);
users[rnti].send_dl_dcch(&dl_dcch_msg, std::move(sdu));
} else {
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) {
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)
@ -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
*******************************************************************************/
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;
@ -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
ul_ccch_msg.msg.type().value != ul_ccch_msg_type_c::types_opts::c1) {
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()) {
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");
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 (users.count(rnti)) {
users[rnti].parse_ul_dcch(lcid, pdu);
users[rnti].parse_ul_dcch(lcid, std::move(pdu));
} else {
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
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 bref0 = bref;
msg[msg_index].pack(bref);
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_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;
@ -829,11 +826,11 @@ void rrc::run_thread()
switch(p.lcid)
{
case RB_ID_SRB0:
parse_ul_ccch(p.rnti, p.pdu);
parse_ul_ccch(p.rnti, std::move(p.pdu));
break;
case RB_ID_SRB1:
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;
case LCID_REM_USER:
rem_user(p.rnti);
@ -1035,7 +1032,7 @@ bool rrc::ue::is_timeout()
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();
@ -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
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");
pool->deallocate(pdu);
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;
switch (ul_dcch_msg.msg.c1().type()) {
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;
case ul_dcch_msg_type_c::c1_c_::types::ul_info_transfer:
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()
.data(),
pdu->N_bytes);
parent->s1ap->write_pdu(rnti, pdu);
parent->s1ap->write_pdu(rnti, std::move(pdu));
break;
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);
state = RRC_STATE_REGISTERED;
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
// state = RRC_STATE_WAIT_FOR_UE_CAP_INFO;
notify_s1ap_ue_ctxt_setup_complete();
send_connection_reconf(pdu);
send_connection_reconf(std::move(pdu));
state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE;
break;
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;
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())) {
send_connection_reconf(pdu);
send_connection_reconf(std::move(pdu));
state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE;
} else {
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);
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);
if(has_tmsi) {
parent->s1ap->initial_ue(rnti, (LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM)establishment_cause.value, pdu, m_tmsi,
mmec);
parent->s1ap->initial_ue(
rnti, (LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM)establishment_cause.value, std::move(pdu), m_tmsi, mmec);
} 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;
}
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);
@ -1602,7 +1599,7 @@ int rrc::ue::get_drbid_config(drb_to_add_mod_s* drb, int drb_id)
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;
rrc_conn_recfg_s* rrc_conn_recfg = &dl_dcch_msg.msg.set_c1().set_rrc_conn_recfg();
@ -1646,14 +1643,14 @@ void rrc::ue::send_connection_reconf_upd(srslte::byte_buffer_t *pdu)
sr_get(&phy_cfg->sched_request_cfg.setup().sr_cfg_idx, &phy_cfg->sched_request_cfg.setup().sr_pucch_res_idx);
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;
}
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.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
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;
}
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.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->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()
@ -1975,7 +1972,7 @@ bool rrc::ue::select_security_algorithms()
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
byte_buffer_t* pdu = pool_allocate_blocking;
srslte::unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool);
if (pdu) {
asn1::bit_ref bref(pdu->msg, pdu->get_tailroom());
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];
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 {
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) {
pdu = pool_allocate_blocking;
pdu = srslte::allocate_unique_buffer(*pool);
}
if (pdu) {
asn1::bit_ref bref(pdu->msg, pdu->get_tailroom());
@ -2003,10 +2000,10 @@ void rrc::ue::send_dl_dcch(dl_dcch_msg_s* dl_dcch_msg, byte_buffer_t* pdu)
char buf[32];
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, std::move(pdu));
parent->pdcp->write_sdu(rnti, RB_ID_SRB1, pdu);
} else {
parent->rrc_log->error("Allocating pdu\n");
}

@ -87,7 +87,7 @@ void s1ap::get_metrics(s1ap_metrics_t &m)
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) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n");
return;
@ -131,7 +131,7 @@ void s1ap::run_thread()
}
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
********************************************************************************/
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].stream_id = 1;
ue_ctxt_map[rnti].release_requested = false;
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].stream_id = 1;
ue_ctxt_map[rnti].release_requested = false;
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");
@ -201,7 +205,7 @@ void s1ap::write_pdu(uint16_t rnti, srslte::byte_buffer_t *pdu)
return;
}
send_ulnastransport(rnti, pdu);
send_ulnastransport(rnti, std::move(pdu));
}
bool s1ap::user_release(uint16_t rnti, LIBLTE_S1AP_CAUSERADIONETWORK_ENUM cause_radio)
@ -382,7 +386,7 @@ bool s1ap::setup_s1()
/* 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;
@ -394,13 +398,10 @@ bool s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t *pdu)
switch(rx_pdu.choice_type) {
case LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE:
return handle_initiatingmessage(&rx_pdu.choice.initiatingMessage);
break;
case LIBLTE_S1AP_S1AP_PDU_CHOICE_SUCCESSFULOUTCOME:
return handle_successfuloutcome(&rx_pdu.choice.successfulOutcome);
break;
case LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME:
return handle_unsuccessfuloutcome(&rx_pdu.choice.unsuccessfulOutcome);
break;
default:
s1ap_log->error("Unhandled PDU type %d\n", rx_pdu.choice_type);
return false;
@ -478,11 +479,11 @@ bool s1ap::handle_dlnastransport(LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT
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) {
memcpy(pdu->msg, msg->NAS_PDU.buffer, 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;
} else {
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
********************************************************************************/
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) {
return false;
@ -686,7 +692,7 @@ bool s1ap::send_initialuemessage(uint16_t rnti, LIBLTE_S1AP_RRC_ESTABLISHMENT_CA
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) {
return false;
@ -819,7 +825,7 @@ bool s1ap::send_initial_ctxt_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_I
if(!mme_connected) {
return false;
}
srslte::byte_buffer_t *buf = pool_allocate;
srslte::unique_byte_buffer buf = srslte::allocate_unique_buffer(*pool);
if (!buf) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_response().\n");
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->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);
ssize_t n_sent = sctp_sendmsg(socket_fd, buf->msg, buf->N_bytes,
(struct sockaddr*)&mme_addr, sizeof(struct sockaddr_in),
htonl(PPID), 0, ue_ctxt_map[rnti].stream_id, 0, 0);
pool->deallocate(buf);
if(n_sent == -1) {
s1ap_log->error("Failed to send InitialContextSetupResponse for RNTI:0x%x\n", rnti);
return false;
@ -873,7 +877,7 @@ bool s1ap::send_erab_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETU
if(!mme_connected) {
return false;
}
srslte::byte_buffer_t *buf = pool_allocate;
srslte::unique_byte_buffer buf = srslte::allocate_unique_buffer(*pool);
if (!buf) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_erab_setup_response().\n");
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->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);
ssize_t n_sent = sctp_sendmsg(socket_fd, buf->msg, buf->N_bytes,
(struct sockaddr*)&mme_addr, sizeof(struct sockaddr_in),
htonl(PPID), 0, ue_ctxt_map[rnti].stream_id, 0, 0);
pool->deallocate(buf);
if(n_sent == -1) {
s1ap_log->error("Failed to send E_RABSetupResponse for RNTI:0x%x\n", rnti);
return false;
@ -927,7 +929,7 @@ bool s1ap::send_initial_ctxt_setup_failure(uint16_t rnti)
if(!mme_connected) {
return false;
}
srslte::byte_buffer_t *buf = pool_allocate;
srslte::unique_byte_buffer buf = srslte::allocate_unique_buffer(*pool);
if (!buf) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_failure().\n");
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.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);
ssize_t n_sent = sctp_sendmsg(socket_fd, buf->msg, buf->N_bytes,
(struct sockaddr*)&mme_addr, sizeof(struct sockaddr_in),
htonl(PPID), 0, ue_ctxt_map[rnti].stream_id, 0, 0);
pool->deallocate(buf);
if(n_sent == -1) {
s1ap_log->error("Failed to send UplinkNASTransport for RNTI:0x%x\n", rnti);
return false;

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

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

@ -307,20 +307,19 @@ public:
typedef enum { Rx = 0, Tx } direction_t;
template <class T>
void
log_rrc_message(const std::string source, const direction_t dir, const srslte::unique_pool_buffer& pdu, const T& msg);
void log_rrc_message(const std::string source, const direction_t dir, const srslte::byte_buffer_t* pdu, const T& msg);
void print_mbms();
bool mbms_service_start(uint32_t serv, uint32_t port);
// NAS interface
void write_sdu(srslte::unique_pool_buffer sdu);
void write_sdu(srslte::unique_byte_buffer sdu);
void enable_capabilities();
uint16_t get_mcc();
uint16_t get_mnc();
int plmn_search(found_plmn_t found_plmns[MAX_FOUND_PLMNS]);
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);
// PHY interface
@ -339,11 +338,11 @@ public:
bool have_drb();
// PDCP interface
void write_pdu(uint32_t lcid, srslte::unique_pool_buffer pdu);
void write_pdu_bcch_bch(srslte::unique_pool_buffer pdu);
void write_pdu_bcch_dlsch(srslte::unique_pool_buffer pdu);
void write_pdu_pcch(srslte::unique_pool_buffer pdu);
void write_pdu_mch(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_byte_buffer pdu);
void write_pdu_bcch_dlsch(srslte::unique_byte_buffer pdu);
void write_pdu_pcch(srslte::unique_byte_buffer pdu);
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer pdu);
private:
@ -353,7 +352,7 @@ private:
PCCH,
STOP
} command;
srslte::unique_pool_buffer pdu;
srslte::unique_byte_buffer pdu;
uint16_t lcid;
} cmd_msg_t;
@ -361,7 +360,7 @@ private:
srslte::block_queue<cmd_msg_t> cmd_q;
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::log *rrc_log;
@ -373,7 +372,7 @@ private:
usim_interface_rrc *usim;
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_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_restablish_request(asn1::rrc::reest_cause_e cause);
void send_con_restablish_complete();
void send_con_setup_complete(srslte::unique_pool_buffer nas_msg);
void send_ul_info_transfer(srslte::unique_pool_buffer nas_msg);
void send_con_setup_complete(srslte::unique_byte_buffer nas_msg);
void send_ul_info_transfer(srslte::unique_byte_buffer nas_msg);
void send_security_mode_complete();
void send_rrc_con_reconfig_complete();
void send_rrc_ue_cap_info();
// Parsers
void process_pdu(uint32_t lcid, srslte::unique_pool_buffer pdu);
void parse_dl_ccch(srslte::unique_pool_buffer pdu);
void parse_dl_dcch(uint32_t lcid, srslte::unique_pool_buffer pdu);
void parse_dl_info_transfer(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_byte_buffer pdu);
void parse_dl_dcch(uint32_t lcid, srslte::unique_byte_buffer pdu);
void parse_dl_info_transfer(uint32_t lcid, srslte::unique_byte_buffer pdu);
// Helpers
bool con_reconfig(asn1::rrc::rrc_conn_recfg_s* reconfig);

@ -162,7 +162,7 @@ void gw::set_tundevname(const std::string & devname)
/*******************************************************************************
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());
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);
}
}
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)
{
@ -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;
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) {
gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n");
return;
@ -315,9 +313,9 @@ void gw::run_thread()
if (pdcp->is_lcid_enabled(cfg.lcid)) {
pdu->set_timestamp();
ul_tput_bytes += pdu->N_bytes;
pdcp->write_sdu(cfg.lcid, pdu, false);
pdcp->write_sdu(cfg.lcid, std::move(pdu), false);
do {
pdu = pool_allocate;
pdu = srslte::allocate_unique_buffer(*pool);
if (!pdu) {
gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n");
usleep(100000);

@ -257,7 +257,7 @@ bool nas::rrc_connect() {
}
// 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) {
nas_log->error("Fatal Error: Couldn't allocate PDU in rrc_connect().\n");
return false;
@ -280,8 +280,7 @@ bool nas::rrc_connect() {
// Set establishment cause
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");
// 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, byte_buffer_t *pdu) {
void nas::write_pdu(uint32_t lcid, unique_byte_buffer pdu)
{
uint8 pd = 0;
uint8 msg_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());
// 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)
{
case LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS:
@ -360,14 +359,12 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
break;
} else {
nas_log->error("Not handling NAS message with integrity check error\n");
pool->deallocate(pdu);
return;
}
case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT:
break;
default:
nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type);
pool->deallocate(pdu);
return;
}
@ -377,47 +374,46 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) {
}
// 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());
// TODO: Check if message type requieres specical security header type and if it isvalid
switch (msg_type) {
case LIBLTE_MME_MSG_TYPE_ATTACH_ACCEPT:
parse_attach_accept(lcid, pdu);
parse_attach_accept(lcid, std::move(pdu));
break;
case LIBLTE_MME_MSG_TYPE_ATTACH_REJECT:
parse_attach_reject(lcid, pdu);
parse_attach_reject(lcid, std::move(pdu));
break;
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;
case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REJECT:
parse_authentication_reject(lcid, pdu);
parse_authentication_reject(lcid, std::move(pdu));
break;
case LIBLTE_MME_MSG_TYPE_IDENTITY_REQUEST:
parse_identity_request(lcid, pdu);
parse_identity_request(lcid, std::move(pdu));
break;
case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMMAND:
parse_security_mode_command(lcid, pdu);
parse_security_mode_command(lcid, std::move(pdu));
break;
case LIBLTE_MME_MSG_TYPE_SERVICE_REJECT:
parse_service_reject(lcid, pdu);
parse_service_reject(lcid, std::move(pdu));
break;
case LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_REQUEST:
parse_esm_information_request(lcid, pdu);
parse_esm_information_request(lcid, std::move(pdu));
break;
case LIBLTE_MME_MSG_TYPE_EMM_INFORMATION:
parse_emm_information(lcid, pdu);
parse_emm_information(lcid, std::move(pdu));
break;
case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST:
parse_detach_request(lcid, pdu);
parse_detach_request(lcid, std::move(pdu));
break;
case LIBLTE_MME_MSG_TYPE_EMM_STATUS:
parse_emm_status(lcid, pdu);
parse_emm_status(lcid, std::move(pdu));
break;
default:
nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type);
pool->deallocate(pdu);
return;
}
}
@ -510,7 +506,7 @@ void nas::integrity_generate(uint8_t *key_128,
// This function depends to a valid k_nas_int.
// 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) {
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;
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;
switch(ctxt.cipher_algo)
@ -629,7 +625,8 @@ bool nas::check_cap_replay(LIBLTE_MME_UE_SECURITY_CAPABILITIES_STRUCT *caps)
* 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) {
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) {
nas_log->error("Invalid attach accept PDU size (%d)\n", pdu->N_bytes);
pool->deallocate(pdu);
return;
}
@ -653,7 +649,7 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
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) {
//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) ||
(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");
pool->deallocate(pdu);
return;
}
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 {
nas_log->error("PDN type not IPv4, IPv6 nor IPv4v6\n");
pool->deallocate(pdu);
return;
}
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_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED,
ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *) pdu);
(LIBLTE_BYTE_MSG_STRUCT*)pdu.get());
// Write NAS pcap
if (pcap != NULL) {
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();
nas_log->info("Sending Attach Complete\n");
rrc->write_sdu(pdu);
rrc->write_sdu(std::move(pdu));
ctxt.tx_count++;
} else {
nas_log->info("Not handling attach type %u\n", attach_accept.eps_attach_result);
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;
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->console("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause);
state = EMM_STATE_DEREGISTERED;
pool->deallocate(pdu);
// 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;
bzero(&auth_req, sizeof(LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT));
nas_log->info("Received Authentication Request\n");
liblte_mme_unpack_authentication_request_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &auth_req);
// Deallocate PDU after parsing
pool->deallocate(pdu);
liblte_mme_unpack_authentication_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &auth_req);
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");
pool->deallocate(pdu);
state = EMM_STATE_DEREGISTERED;
// 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;
ZERO_OBJECT(id_req);
LIBLTE_MME_ID_RESPONSE_MSG_STRUCT 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
pool->deallocate(pdu);
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);
}
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) {
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;
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",
sec_mode_cmd.nas_ksi.nas_ksi,
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) {
nas_log->error("Mapped security context not supported\n");
pool->deallocate(pdu);
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) {
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);
pool->deallocate(pdu);
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)) {
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);
pool->deallocate(pdu);
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]) {
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);
pool->deallocate(pdu);
return;
}
@ -1038,7 +1025,6 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
if (integrity_check(pdu) != true) {
nas_log->warning("Sending Security Mode Reject due to integrity check failure\n");
send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_MAC_FAILURE);
pool->deallocate(pdu);
return;
}
@ -1059,10 +1045,11 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
// Send response
pdu->reset();
liblte_mme_pack_security_mode_complete_msg(&sec_mode_comp,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT,
ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *) pdu);
liblte_mme_pack_security_mode_complete_msg(
&sec_mode_comp,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT,
ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT*)pdu.get());
if(pcap != NULL) {
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",
ctxt.tx_count,
rrc->get_rb_name(lcid).c_str());
rrc->write_sdu(pdu);
rrc->write_sdu(std::move(pdu));
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;
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");
goto exit;
}
@ -1098,36 +1085,34 @@ void nas::parse_service_reject(uint32_t lcid, byte_buffer_t* pdu)
exit:
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_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);
ctxt.rx_count++;
pool->deallocate(pdu);
// send response
send_esm_information_response(esm_info_req.proc_transaction_id);
}
void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) {
liblte_mme_unpack_emm_information_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &emm_info);
void nas::parse_emm_information(uint32_t lcid, unique_byte_buffer pdu)
{
liblte_mme_unpack_emm_information_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &emm_info);
std::string str = emm_info_str(&emm_info);
nas_log->info("Received EMM Information: %s\n", str.c_str());
nas_log->console("%s\n", str.c_str());
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_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++;
pool->deallocate(pdu);
if (state == EMM_STATE_REGISTERED) {
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_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++;
pool->deallocate(pdu);
switch (emm_status.emm_cause) {
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
******************************************************************************/
void nas::gen_attach_request(byte_buffer_t *msg) {
void nas::gen_attach_request(unique_byte_buffer& msg)
{
if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in gen_attach_request().\n");
return;
@ -1224,10 +1209,8 @@ void nas::gen_attach_request(byte_buffer_t *msg) {
nas_log->info("Requesting GUTI attach. "
"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);
liblte_mme_pack_attach_request_msg(&attach_req,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY,
ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *) msg);
liblte_mme_pack_attach_request_msg(
&attach_req, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)msg.get());
// Add MAC
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;
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());
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) {
@ -1259,8 +1242,8 @@ void nas::gen_attach_request(byte_buffer_t *msg) {
}
}
void nas::gen_service_request(byte_buffer_t *msg) {
void nas::gen_service_request(unique_byte_buffer& msg)
{
if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in gen_service_request().\n");
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) {
byte_buffer_t *msg = pool_allocate_blocking;
unique_byte_buffer msg = srslte::allocate_unique_buffer(*pool, true);
if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_security_mode_reject().\n");
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};
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) {
pcap->write_nas(msg->msg, msg->N_bytes);
}
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)
{
byte_buffer_t *pdu = pool_allocate_blocking;
unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu) {
nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__);
return;
@ -1384,7 +1367,8 @@ void nas::send_detach_request(bool switch_off)
liblte_mme_pack_detach_request_msg(&detach_request,
rrc->is_connected() ? LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED
: 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) {
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;
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());
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) {
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");
if (rrc->is_connected()) {
rrc->write_sdu(pdu);
rrc->write_sdu(std::move(pdu));
} 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()
{
byte_buffer_t *pdu = pool_allocate_blocking;
unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu) {
nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__);
return;
@ -1439,7 +1424,7 @@ void nas::send_detach_accept()
liblte_mme_pack_detach_accept_msg(&detach_accept,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED,
ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *) pdu);
(LIBLTE_BYTE_MSG_STRUCT*)pdu.get());
if(pcap != NULL) {
pcap->write_nas(pdu->msg, pdu->N_bytes);
@ -1459,12 +1444,12 @@ void nas::send_detach_accept()
}
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) {
byte_buffer_t *pdu = pool_allocate_blocking;
unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_response().\n");
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_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) {
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");
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) {
byte_buffer_t *msg = pool_allocate_blocking;
unique_byte_buffer msg = srslte::allocate_unique_buffer(*pool, true);
if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_failure().\n");
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;
}
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) {
pcap->write_nas(msg->msg, msg->N_bytes);
}
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;
}
byte_buffer_t *pdu = pool_allocate_blocking;
unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_identity_response().\n");
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) {
pcap->write_nas(pdu->msg, pdu->N_bytes);
}
rrc->write_sdu(pdu);
rrc->write_sdu(std::move(pdu));
ctxt.tx_count++;
}
void nas::send_service_request() {
byte_buffer_t *msg = pool_allocate_blocking;
unique_byte_buffer msg = srslte::allocate_unique_buffer(*pool, true);
if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_service_request().\n");
return;
@ -1591,7 +1577,7 @@ void nas::send_service_request() {
}
nas_log->info("Sending service request\n");
rrc->write_sdu(msg);
rrc->write_sdu(std::move(msg));
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;
}
byte_buffer_t *pdu = pool_allocate_blocking;
unique_byte_buffer pdu = srslte::allocate_unique_buffer(*pool, true);
if (!pdu) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_attach_request().\n");
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,
LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED,
ctxt.tx_count,
(LIBLTE_BYTE_MSG_STRUCT *)pdu)) {
(LIBLTE_BYTE_MSG_STRUCT*)pdu.get())) {
nas_log->error("Error packing ESM information response.\n");
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");
rrc->write_sdu(pdu);
rrc->write_sdu(std::move(pdu));
ctxt.tx_count++;
chap_id++;

@ -51,8 +51,7 @@ rrc::rrc() :
last_state(RRC_STATE_CONNECTED),
drb_up(false),
rlc_flush_timeout(2000),
rlc_flush_counter(0),
dedicated_info_nas(NULL)
rlc_flush_counter(0)
{
n310_cnt = 0;
n311_cnt = 0;
@ -97,7 +96,7 @@ void rrc::srslte_rrc_log(const char* str)
}
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) {
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();
t304 = mac_timers->timer_get_unique_id();
dedicated_info_nas.set_pool(pool);
ue_identity_configured = false;
transaction_id = 0;
@ -191,7 +189,7 @@ void rrc::stop() {
stop_timers();
cmd_msg_t msg;
msg.command = cmd_msg_t::STOP;
cmd_q.push(msg);
cmd_q.push(std::move(msg));
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 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) {
@ -519,7 +517,7 @@ bool rrc::connection_request(asn1::rrc::establishment_cause_e cause, srslte::uni
if (!ret) {
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);
@ -1432,7 +1430,7 @@ void rrc::send_con_restablish_complete() {
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");
@ -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);
}
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;
@ -1659,9 +1657,9 @@ bool rrc::con_reconfig(asn1::rrc::rrc_conn_recfg_s* reconfig)
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++) {
nas_sdu.allocate();
nas_sdu = srslte::allocate_unique_buffer(*pool);
if (nas_sdu.get()) {
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();
@ -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?
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
mac->bcch_stop_rx();
@ -1786,7 +1784,7 @@ void rrc::write_pdu_bcch_dlsch(unique_pool_buffer pdu)
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) {
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;
msg.pdu = std::move(pdu);
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) {
pcch_msg_s pcch_msg;
@ -1944,7 +1942,7 @@ void rrc::process_pcch(unique_pool_buffer pdu)
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();
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) {
//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;
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)
{
// 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()) {
rrc_log->error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack().\n");
return;
@ -2048,7 +2046,7 @@ void rrc::send_ul_ccch_msg(const asn1::rrc::ul_ccch_msg_s& msg)
mac->set_contention_id(uecri);
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));
}
@ -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)
{
// 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()) {
rrc_log->error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack().\n");
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->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));
}
void rrc::write_sdu(srslte::unique_pool_buffer sdu)
void rrc::write_sdu(srslte::unique_byte_buffer sdu)
{
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));
}
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 (lcid == 0) {
@ -2110,10 +2108,10 @@ void rrc::write_pdu(uint32_t lcid, unique_pool_buffer pdu)
msg.pdu = std::move(pdu);
msg.command = cmd_msg_t::PDU;
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) {
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::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");
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();
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::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");
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();
switch (dl_dcch_msg.msg.c1().type().value) {
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()) {
rrc_log->error("Fatal error: out of buffers in pool\n");
return;

@ -70,13 +70,13 @@ namespace srslte {
class pdcp_dummy : public rrc_interface_pdcp, public pdcp_interface_gw
{
public:
void write_pdu(uint32_t lcid, byte_buffer_t *pdu) {}
void write_pdu_bcch_bch(byte_buffer_t *pdu) {}
void write_pdu_bcch_dlsch(byte_buffer_t *pdu) {}
void write_pdu_pcch(byte_buffer_t *pdu) {}
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu) {}
void write_pdu(uint32_t lcid, unique_byte_buffer pdu) {}
void write_pdu_bcch_bch(unique_byte_buffer pdu) {}
void write_pdu_bcch_dlsch(unique_byte_buffer pdu) {}
void write_pdu_pcch(unique_byte_buffer pdu) {}
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) {}
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; }
};
@ -89,12 +89,11 @@ public:
mnc_to_bytes(mnc, plmns.plmn_id.mnc);
plmns.tac = 0xffff;
}
void write_sdu(byte_buffer_t *sdu)
void write_sdu(unique_byte_buffer sdu)
{
last_sdu_len = sdu->N_bytes;
//printf("NAS generated SDU (len=%d):\n", 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"); }
uint32_t get_last_sdu_len() { return last_sdu_len; }
@ -106,12 +105,11 @@ public:
};
void plmn_select(plmn_id_s plmn_id){};
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);
last_sdu_len = sdu->N_bytes;
srslte_vec_fprint_byte(stdout, sdu->msg, sdu->N_bytes);
byte_buffer_pool::get_instance()->deallocate(sdu);
return true;
}
bool is_connected() {return false;}
@ -128,8 +126,8 @@ private:
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; }
void write_pdu(uint32_t lcid, byte_buffer_t *pdu) {}
void write_pdu_mch(uint32_t lcid, srslte::byte_buffer_t *sdu) {}
void write_pdu(uint32_t lcid, unique_byte_buffer pdu) {}
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer sdu) {}
};
}
@ -164,29 +162,33 @@ int security_command_test()
uint8_t res[16];
usim.init(&args, &usim_log);
srsue::nas nas;
nas_args_t cfg;
cfg.eia = "1,2";
cfg.eea = "0,1,2";
nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg);
// push auth request PDU to NAS to generate security context
byte_buffer_t* tmp = byte_buffer_pool::get_instance()->allocate();
memcpy(tmp->msg, auth_request_pdu, sizeof(auth_request_pdu));
tmp->N_bytes = sizeof(auth_request_pdu);
nas.write_pdu(LCID, tmp);
// TODO: add check for authentication response
rrc_dummy.reset();
// reuse buffer for security mode command
memcpy(tmp->msg, sec_mode_command_pdu, sizeof(sec_mode_command_pdu));
tmp->N_bytes = sizeof(sec_mode_command_pdu);
nas.write_pdu(LCID, tmp);
// check length of generated NAS SDU
if (rrc_dummy.get_last_sdu_len() > 3) {
ret = SRSLTE_SUCCESS;
{
srsue::nas nas;
nas_args_t cfg;
cfg.eia = "1,2";
cfg.eea = "0,1,2";
nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg);
// push auth request PDU to NAS to generate security context
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));
tmp->N_bytes = sizeof(auth_request_pdu);
nas.write_pdu(LCID, std::move(tmp));
// TODO: add check for authentication response
rrc_dummy.reset();
// 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));
tmp->N_bytes = sizeof(sec_mode_command_pdu);
nas.write_pdu(LCID, std::move(tmp));
// check length of generated NAS SDU
if (rrc_dummy.get_last_sdu_len() > 3) {
ret = SRSLTE_SUCCESS;
}
}
byte_buffer_pool::get_instance()->cleanup();
@ -194,7 +196,6 @@ int security_command_test()
return ret;
}
int mme_attach_request_test()
{
int ret = SRSLTE_ERROR;
@ -226,35 +227,39 @@ int mme_attach_request_test()
args.op = "63BFA50EE6523365FF14C1F45F88737D";
usim.init(&args, &usim_log);
nas_args_t nas_cfg;
nas_cfg.force_imsi_attach = true;
nas_cfg.apn_name = "test123";
srsue::nas nas;
srsue::gw gw;
nas.init(&usim, &rrc_dummy, &gw, &nas_log, nas_cfg);
srslte_gw_config_t gw_config(3);
gw.init(&pdcp_dummy, &nas, &gw_log, gw_config);
gw.set_tundevname("tun0");
// trigger test
nas.attach_request();
// this will time out in the first place
// reset length of last received NAS PDU
rrc_dummy.reset();
// finally push attach accept
byte_buffer_t* tmp = byte_buffer_pool::get_instance()->allocate();
memcpy(tmp->msg, attach_accept_pdu, sizeof(attach_accept_pdu));
tmp->N_bytes = sizeof(attach_accept_pdu);
nas.write_pdu(LCID, tmp);
// check length of generated NAS SDU (attach complete)
if (rrc_dummy.get_last_sdu_len() > 3) {
ret = SRSLTE_SUCCESS;
{
nas_args_t nas_cfg;
nas_cfg.force_imsi_attach = true;
nas_cfg.apn_name = "test123";
srsue::nas nas;
srsue::gw gw;
nas.init(&usim, &rrc_dummy, &gw, &nas_log, nas_cfg);
srslte_gw_config_t gw_config(3);
gw.init(&pdcp_dummy, &nas, &gw_log, gw_config);
gw.set_tundevname("tun0");
// trigger test
nas.attach_request();
// this will time out in the first place
// reset length of last received NAS PDU
rrc_dummy.reset();
// finally push attach accept
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));
tmp->N_bytes = sizeof(attach_accept_pdu);
nas.write_pdu(LCID, std::move(tmp));
// check length of generated NAS SDU (attach complete)
if (rrc_dummy.get_last_sdu_len() > 3) {
ret = SRSLTE_SUCCESS;
}
// ensure buffers are deleted before pool cleanup
}
byte_buffer_pool::get_instance()->cleanup();
@ -296,23 +301,25 @@ int esm_info_request_test()
srslte::byte_buffer_pool *pool;
pool = byte_buffer_pool::get_instance();
srsue::nas nas;
nas_args_t cfg;
cfg.apn_name = "srslte";
cfg.apn_user = "srsuser";
cfg.apn_pass = "srspass";
cfg.force_imsi_attach = true;
nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg);
// push ESM info request PDU to NAS to generate response
byte_buffer_t* tmp = pool->allocate();
memcpy(tmp->msg, esm_info_req_pdu, sizeof(esm_info_req_pdu));
tmp->N_bytes = sizeof(esm_info_req_pdu);
nas.write_pdu(LCID, tmp);
// check length of generated NAS SDU
if (rrc_dummy.get_last_sdu_len() > 3) {
ret = SRSLTE_SUCCESS;
{
srsue::nas nas;
nas_args_t cfg;
cfg.apn_name = "srslte";
cfg.apn_user = "srsuser";
cfg.apn_pass = "srspass";
cfg.force_imsi_attach = true;
nas.init(&usim, &rrc_dummy, &gw, &nas_log, cfg);
// push ESM info request PDU to NAS to generate response
unique_byte_buffer tmp = srslte::allocate_unique_buffer(*pool, true);
memcpy(tmp->msg, esm_info_req_pdu, sizeof(esm_info_req_pdu));
tmp->N_bytes = sizeof(esm_info_req_pdu);
nas.write_pdu(LCID, std::move(tmp));
// check length of generated NAS SDU
if (rrc_dummy.get_last_sdu_len() > 3) {
ret = SRSLTE_SUCCESS;
}
}
pool->cleanup();

Loading…
Cancel
Save