Merge branch 'next' into raa

master
Paul Sutton 7 years ago
commit f7375b5da0

@ -1,7 +1,7 @@
srsLTE srsLTE
======== ========
[![Coverity Scan Build Status](https://scan.coverity.com/projects/10045/badge.svg)](https://scan.coverity.com/projects/10045) [![Coverity Scan Build Status](https://scan.coverity.com/projects/4721/badge.svg)](https://scan.coverity.com/projects/4721)
srsLTE is a free and open-source LTE software suite developed by SRS (www.softwareradiosystems.com). srsLTE is a free and open-source LTE software suite developed by SRS (www.softwareradiosystems.com).

@ -54,7 +54,7 @@ void logger_file::init(std::string file, int max_length_) {
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&not_empty, NULL); pthread_cond_init(&not_empty, NULL);
pthread_cond_init(&not_full, NULL); pthread_cond_init(&not_full, NULL);
max_length = max_length_*1024; max_length = (int64_t)max_length_*1024;
name_idx = 0; name_idx = 0;
filename = file; filename = file;
logfile = fopen(filename.c_str(), "w"); logfile = fopen(filename.c_str(), "w");

@ -54,6 +54,7 @@ int srslte_ringbuffer_write(srslte_ringbuffer_t *q, void *p, int nof_bytes)
int w_bytes = nof_bytes; int w_bytes = nof_bytes;
pthread_mutex_lock(&q->mutex); pthread_mutex_lock(&q->mutex);
if (!q->active) { if (!q->active) {
pthread_mutex_unlock(&q->mutex);
return 0; return 0;
} }
if (q->count + w_bytes > q->capacity) { if (q->count + w_bytes > q->capacity) {
@ -85,6 +86,7 @@ int srslte_ringbuffer_read(srslte_ringbuffer_t *q, void *p, int nof_bytes)
pthread_cond_wait(&q->cvar, &q->mutex); pthread_cond_wait(&q->cvar, &q->mutex);
} }
if (!q->active) { if (!q->active) {
pthread_mutex_unlock(&q->mutex);
return 0; return 0;
} }
if (nof_bytes + q->rpm > q->capacity) { if (nof_bytes + q->rpm > q->capacity) {

@ -587,7 +587,8 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r
rrc->get_rb_name(lcid).c_str(), nof_bytes, head_len); rrc->get_rb_name(lcid).c_str(), nof_bytes, head_len);
return 0; return 0;
} }
pdu_space = nof_bytes-head_len-2;
pdu_space = nof_bytes-head_len;
if(pdu_space < (retx.so_end-retx.so_start)) if(pdu_space < (retx.so_end-retx.so_start))
retx.so_end = retx.so_start+pdu_space; retx.so_end = retx.so_start+pdu_space;
@ -603,10 +604,13 @@ int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t r
if(lower >= retx.so_end) if(lower >= retx.so_end)
break; break;
if(pdu_space <= 2)
break;
upper += old_header.li[i]; upper += old_header.li[i];
head_len = rlc_am_packed_length(&new_header); head_len = rlc_am_packed_length(&new_header);
pdu_space = nof_bytes-head_len-2; pdu_space = nof_bytes-head_len;
if(pdu_space < (retx.so_end-retx.so_start)) if(pdu_space < (retx.so_end-retx.so_start))
retx.so_end = retx.so_start+pdu_space; retx.so_end = retx.so_start+pdu_space;
@ -1085,11 +1089,11 @@ void rlc_am::handle_control_pdu(uint8_t *payload, uint32_t nof_bytes)
it = tx_window.find(i); it = tx_window.find(i);
if (it != tx_window.end()) { if (it != tx_window.end()) {
if(update_vt_a) { if(update_vt_a) {
tx_window.erase(it);
if(it->second.buf) { if(it->second.buf) {
pool->deallocate(it->second.buf); pool->deallocate(it->second.buf);
it->second.buf = 0; it->second.buf = 0;
} }
tx_window.erase(it);
vt_a = (vt_a + 1)%MOD; vt_a = (vt_a + 1)%MOD;
vt_ms = (vt_ms + 1)%MOD; vt_ms = (vt_ms + 1)%MOD;
} }
@ -1217,15 +1221,33 @@ void rlc_am::print_rx_segments()
bool rlc_am::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pdu_t *segment) bool rlc_am::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pdu_t *segment)
{ {
// Ordered insert // Check for first segment
std::list<rlc_amd_rx_pdu_t>::iterator tmpit; if(0 == segment->header.so) {
std::list<rlc_amd_rx_pdu_t>::iterator it = pdu->segments.begin(); std::list<rlc_amd_rx_pdu_t>::iterator it;
while(it != pdu->segments.end() && it->header.so < segment->header.so) for(it = pdu->segments.begin(); it != pdu->segments.end(); it++) {
it++; pool->deallocate(it->buf);
pdu->segments.insert(it, *segment); }
pdu->segments.clear();
pdu->segments.push_back(*segment);
return false;
}
// Check segment offset
uint32_t n = 0;
if(!pdu->segments.empty()) {
rlc_amd_rx_pdu_t &back = pdu->segments.back();
n = back.header.so + back.buf->N_bytes;
}
if(segment->header.so != n) {
pool->deallocate(segment->buf);
return false;
} else {
pdu->segments.push_back(*segment);
}
// Check for complete // Check for complete
uint32_t so = 0; uint32_t so = 0;
std::list<rlc_amd_rx_pdu_t>::iterator it, tmpit;
for(it = pdu->segments.begin(); it != pdu->segments.end(); it++) { for(it = pdu->segments.begin(); it != pdu->segments.end(); it++) {
if(so != it->header.so) if(so != it->header.so)
return false; return false;

@ -47,6 +47,7 @@ public:
rlc2 = rlc2_; rlc2 = rlc2_;
fail_rate = fail_rate_; fail_rate = fail_rate_;
run_enable = true; run_enable = true;
running = false;
} }
void stop() void stop()
@ -81,7 +82,7 @@ private:
if(((float)rand()/RAND_MAX > fail_rate) && read>0) { if(((float)rand()/RAND_MAX > fail_rate) && read>0) {
rlc2->write_pdu(1, pdu->msg, opp_size); rlc2->write_pdu(1, pdu->msg, opp_size);
} }
usleep(1000); usleep(100);
} }
running = false; running = false;
} }
@ -138,10 +139,12 @@ class rlc_am_tester
,public thread ,public thread
{ {
public: public:
rlc_am_tester(rlc_interface_pdcp *rlc_){ rlc_am_tester(rlc_interface_pdcp *rlc_, std::string name_=""){
rlc = rlc_; rlc = rlc_;
run_enable = true; run_enable = true;
running = false; running = false;
rx_pdus = 0;
name = name_;
} }
void stop() void stop()
@ -163,6 +166,7 @@ public:
{ {
assert(lcid == 1); assert(lcid == 1);
byte_buffer_pool::get_instance()->deallocate(sdu); byte_buffer_pool::get_instance()->deallocate(sdu);
std::cout << "rlc_am_tester " << name << " received " << rx_pdus++ << " PDUs" << std::endl;
} }
void write_pdu_bcch_bch(byte_buffer_t *sdu) {} void write_pdu_bcch_bch(byte_buffer_t *sdu) {}
void write_pdu_bcch_dlsch(byte_buffer_t *sdu) {} void write_pdu_bcch_dlsch(byte_buffer_t *sdu) {}
@ -186,13 +190,16 @@ private:
pdu->N_bytes = 1500; pdu->N_bytes = 1500;
pdu->msg[0] = sn++; pdu->msg[0] = sn++;
rlc->write_sdu(1, pdu); rlc->write_sdu(1, pdu);
usleep(1000); usleep(100);
} }
running = false; running = false;
} }
bool run_enable; bool run_enable;
bool running; bool running;
long rx_pdus;
std::string name;
rlc_interface_pdcp *rlc; rlc_interface_pdcp *rlc;
}; };
@ -206,13 +213,13 @@ void stress_test()
log1.set_hex_limit(-1); log1.set_hex_limit(-1);
log2.set_hex_limit(-1); log2.set_hex_limit(-1);
float fail_rate = 0.1; float fail_rate = 0.01;
rlc rlc1; rlc rlc1;
rlc rlc2; rlc rlc2;
rlc_am_tester tester1(&rlc1); rlc_am_tester tester1(&rlc1, "tester1");
rlc_am_tester tester2(&rlc2); rlc_am_tester tester2(&rlc2, "tester2");
mac_dummy mac(&rlc1, &rlc2, fail_rate); mac_dummy mac(&rlc1, &rlc2, fail_rate);
ue_interface ue; ue_interface ue;

@ -482,17 +482,17 @@ void resegment_test_1()
// Read the retx PDU from RLC1 and force resegmentation // Read the retx PDU from RLC1 and force resegmentation
byte_buffer_t retx1; byte_buffer_t retx1;
len = rlc1.read_pdu(retx1.msg, 11); // 4 byte header + 5 data len = rlc1.read_pdu(retx1.msg, 9); // 4 byte header + 5 data
retx1.N_bytes = len; retx1.N_bytes = len;
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2
rlc2.write_pdu(retx1.msg, retx1.N_bytes); rlc2.write_pdu(retx1.msg, retx1.N_bytes);
assert(9 == rlc1.get_buffer_state()); // 4 byte header + 5 data assert(9 == rlc1.get_buffer_state());
// Read the remaining segment // Read the remaining segment
byte_buffer_t retx2; byte_buffer_t retx2;
len = rlc1.read_pdu(retx2.msg, 11); // 4 byte header + 5 data len = rlc1.read_pdu(retx2.msg, 9); // 4 byte header + 5 data
retx2.N_bytes = len; retx2.N_bytes = len;
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2
@ -591,16 +591,16 @@ void resegment_test_2()
// Read the retx PDU from RLC1 and force resegmentation // Read the retx PDU from RLC1 and force resegmentation
byte_buffer_t retx1; byte_buffer_t retx1;
retx1.N_bytes = rlc1.read_pdu(retx1.msg, 18); // 6 byte header + 10 data retx1.N_bytes = rlc1.read_pdu(retx1.msg, 16); // 6 byte header + 10 data
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2
rlc2.write_pdu(retx1.msg, retx1.N_bytes); rlc2.write_pdu(retx1.msg, retx1.N_bytes);
assert(16 == rlc1.get_buffer_state()); // 6 byte header + 10 data assert(16 == rlc1.get_buffer_state());
// Read the remaining segment // Read the remaining segment
byte_buffer_t retx2; byte_buffer_t retx2;
retx2.N_bytes = rlc1.read_pdu(retx2.msg, 18); // 6 byte header + 10 data retx2.N_bytes = rlc1.read_pdu(retx2.msg, 16); // 6 byte header + 10 data
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2
rlc2.write_pdu(retx2.msg, retx2.N_bytes); rlc2.write_pdu(retx2.msg, retx2.N_bytes);
@ -696,14 +696,14 @@ void resegment_test_3()
// Read the retx PDU from RLC1 and force resegmentation // Read the retx PDU from RLC1 and force resegmentation
byte_buffer_t retx1; byte_buffer_t retx1;
retx1.N_bytes = rlc1.read_pdu(retx1.msg, 16); // 4 byte header + 10 data retx1.N_bytes = rlc1.read_pdu(retx1.msg, 14); // 4 byte header + 10 data
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2
rlc2.write_pdu(retx1.msg, retx1.N_bytes); rlc2.write_pdu(retx1.msg, retx1.N_bytes);
// Read the remaining segment // Read the remaining segment
byte_buffer_t retx2; byte_buffer_t retx2;
retx2.N_bytes = rlc1.read_pdu(retx2.msg, 16); // 4 byte header + 10 data retx2.N_bytes = rlc1.read_pdu(retx2.msg, 14); // 4 byte header + 10 data
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2
rlc2.write_pdu(retx2.msg, retx2.N_bytes); rlc2.write_pdu(retx2.msg, retx2.N_bytes);
@ -799,14 +799,14 @@ void resegment_test_4()
// Read the retx PDU from RLC1 and force resegmentation // Read the retx PDU from RLC1 and force resegmentation
byte_buffer_t retx1; byte_buffer_t retx1;
retx1.N_bytes = rlc1.read_pdu(retx1.msg, 23); // 6 byte header + 15 data retx1.N_bytes = rlc1.read_pdu(retx1.msg, 21); // 6 byte header + 15 data
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2
rlc2.write_pdu(retx1.msg, retx1.N_bytes); rlc2.write_pdu(retx1.msg, retx1.N_bytes);
// Read the remaining segment // Read the remaining segment
byte_buffer_t retx2; byte_buffer_t retx2;
retx2.N_bytes = rlc1.read_pdu(retx2.msg, 23); // 6 byte header + 15 data retx2.N_bytes = rlc1.read_pdu(retx2.msg, 21); // 6 byte header + 15 data
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2
rlc2.write_pdu(retx2.msg, retx2.N_bytes); rlc2.write_pdu(retx2.msg, retx2.N_bytes);
@ -902,14 +902,14 @@ void resegment_test_5()
// Read the retx PDU from RLC1 and force resegmentation // Read the retx PDU from RLC1 and force resegmentation
byte_buffer_t retx1; byte_buffer_t retx1;
retx1.N_bytes = rlc1.read_pdu(retx1.msg, 29); // 7 byte header + 20 data retx1.N_bytes = rlc1.read_pdu(retx1.msg, 27); // 7 byte header + 20 data
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2
rlc2.write_pdu(retx1.msg, retx1.N_bytes); rlc2.write_pdu(retx1.msg, retx1.N_bytes);
// Read the remaining segment // Read the remaining segment
byte_buffer_t retx2; byte_buffer_t retx2;
retx2.N_bytes = rlc1.read_pdu(retx2.msg, 29); // 7 byte header + 20 data retx2.N_bytes = rlc1.read_pdu(retx2.msg, 27); // 7 byte header + 20 data
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2
rlc2.write_pdu(retx2.msg, retx2.N_bytes); rlc2.write_pdu(retx2.msg, retx2.N_bytes);
@ -1023,11 +1023,11 @@ void resegment_test_6()
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2
rlc2.write_pdu(retx1.msg, retx1.N_bytes); rlc2.write_pdu(retx1.msg, retx1.N_bytes);
assert(157 == rlc1.get_buffer_state()); assert(155 == rlc1.get_buffer_state());
// Read the remaining segment // Read the remaining segment
byte_buffer_t retx2; byte_buffer_t retx2;
len = rlc1.read_pdu(retx2.msg, 159); len = rlc1.read_pdu(retx2.msg, 157);
retx2.N_bytes = len; retx2.N_bytes = len;
// Write the retx PDU to RLC2 // Write the retx PDU to RLC2

@ -24,6 +24,7 @@
* *
*/ */
#include <iostream>
#include "mme/s1ap.h" #include "mme/s1ap.h"
#include "mme/s1ap_nas_transport.h" #include "mme/s1ap_nas_transport.h"
#include "srslte/common/security.h" #include "srslte/common/security.h"

@ -76,17 +76,22 @@ class cell_t
return false; return false;
} }
cell_t() { cell_t() {
this->has_valid_sib1 = false; srslte_cell_t tmp = {};
this->has_valid_sib2 = false; cell_t(tmp, 0, 0);
this->has_valid_sib3 = false;
} }
cell_t(srslte_cell_t phy_cell, uint32_t earfcn, float rsrp) { cell_t(srslte_cell_t phy_cell, uint32_t earfcn, float rsrp) {
this->has_valid_sib1 = false; this->has_valid_sib1 = false;
this->has_valid_sib2 = false; this->has_valid_sib2 = false;
this->has_valid_sib3 = false; this->has_valid_sib3 = false;
this->has_valid_sib13 = false;
this->phy_cell = phy_cell; this->phy_cell = phy_cell;
this->rsrp = rsrp; this->rsrp = rsrp;
this->earfcn = earfcn; this->earfcn = earfcn;
in_sync = false;
bzero(&sib1, sizeof(sib1));
bzero(&sib2, sizeof(sib2));
bzero(&sib3, sizeof(sib3));
bzero(&sib13, sizeof(sib13));
} }
uint32_t earfcn; uint32_t earfcn;
@ -114,6 +119,7 @@ class rrc
{ {
public: public:
rrc(); rrc();
~rrc();
void init(phy_interface_rrc *phy_, void init(phy_interface_rrc *phy_,
mac_interface_rrc *mac_, mac_interface_rrc *mac_,

@ -49,12 +49,20 @@ rrc::rrc()
:state(RRC_STATE_IDLE) :state(RRC_STATE_IDLE)
,drb_up(false) ,drb_up(false)
,sysinfo_index(0) ,sysinfo_index(0)
,serving_cell(NULL)
{ {
n310_cnt = 0; n310_cnt = 0;
n311_cnt = 0; n311_cnt = 0;
serving_cell = new cell_t(); serving_cell = new cell_t();
} }
rrc::~rrc()
{
if (serving_cell) {
delete(serving_cell);
}
}
static void liblte_rrc_handler(void *ctx, char *str) { static void liblte_rrc_handler(void *ctx, char *str) {
rrc *r = (rrc *) ctx; rrc *r = (rrc *) ctx;
r->liblte_rrc_log(str); r->liblte_rrc_log(str);

Loading…
Cancel
Save