mirror of https://github.com/PentHertz/srsLTE.git
Fix issues in uplink QoS (#636)
Fix bugs in Long BSR and Truncated BSR and added unit tests
This commit is contained in:
parent
ef61f0408c
commit
69edee4e6c
|
@ -556,9 +556,9 @@ bool sch_subh::set_bsr(uint32_t buff_size[4], sch_subh::cetype format)
|
||||||
uint32_t ce_size = format == LONG_BSR ? 3 : 1;
|
uint32_t ce_size = format == LONG_BSR ? 3 : 1;
|
||||||
if (((sch_pdu*)parent)->has_space_ce(ce_size)) {
|
if (((sch_pdu*)parent)->has_space_ce(ce_size)) {
|
||||||
if (format == LONG_BSR) {
|
if (format == LONG_BSR) {
|
||||||
w_payload_ce[0] = (buff_size_table(buff_size[0]) & 0x3f) << 2 | (buff_size_table(buff_size[1]) & 0xc0) >> 6;
|
w_payload_ce[0] = ((buff_size_table(buff_size[0]) & 0x3f) << 2) | ((buff_size_table(buff_size[1]) & 0x30) >> 4);
|
||||||
w_payload_ce[1] = (buff_size_table(buff_size[1]) & 0xf) << 4 | (buff_size_table(buff_size[2]) & 0xf0) >> 4;
|
w_payload_ce[1] = ((buff_size_table(buff_size[1]) & 0xf) << 4) | ((buff_size_table(buff_size[2]) & 0x3c) >> 2);
|
||||||
w_payload_ce[2] = (buff_size_table(buff_size[2]) & 0x3) << 6 | (buff_size_table(buff_size[3]) & 0x3f);
|
w_payload_ce[2] = ((buff_size_table(buff_size[2]) & 0x3) << 6) | ((buff_size_table(buff_size[3]) & 0x3f));
|
||||||
} else {
|
} else {
|
||||||
w_payload_ce[0] = (nonzero_lcg & 0x3) << 6 | (buff_size_table(buff_size[nonzero_lcg]) & 0x3f);
|
w_payload_ce[0] = (nonzero_lcg & 0x3) << 6 | (buff_size_table(buff_size[nonzero_lcg]) & 0x3f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -456,6 +456,47 @@ int mac_sch_pdu_pack_test5()
|
||||||
return SRSLTE_SUCCESS;
|
return SRSLTE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test for BSR CE
|
||||||
|
int mac_sch_pdu_pack_test6()
|
||||||
|
{
|
||||||
|
srslte::log_filter mac_log("MAC");
|
||||||
|
mac_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
|
mac_log.set_hex_limit(32);
|
||||||
|
|
||||||
|
const uint32_t pdu_size = 8;
|
||||||
|
srslte::sch_pdu pdu(10, &mac_log);
|
||||||
|
|
||||||
|
uint8_t tv[pdu_size] = {0x3e, 0x1f, 0x01, 0xfa, 0x7f, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
|
byte_buffer_t buffer;
|
||||||
|
pdu.init_tx(&buffer, pdu_size, true);
|
||||||
|
|
||||||
|
TESTASSERT(pdu.rem_size() == pdu_size);
|
||||||
|
TESTASSERT(pdu.get_pdu_len() == pdu_size);
|
||||||
|
TESTASSERT(pdu.get_sdu_space() == pdu_size - 1);
|
||||||
|
TESTASSERT(pdu.get_current_sdu_ptr() == buffer.msg);
|
||||||
|
|
||||||
|
// Try to Long BSR CE
|
||||||
|
uint32_t buff_size[4] = {0, 1000, 5000, 19200000};
|
||||||
|
TESTASSERT(pdu.new_subh());
|
||||||
|
TESTASSERT(pdu.get()->set_bsr(buff_size, srslte::sch_subh::LONG_BSR));
|
||||||
|
|
||||||
|
// write PDU
|
||||||
|
pdu.write_packet(&mac_log);
|
||||||
|
|
||||||
|
// compare with tv
|
||||||
|
TESTASSERT(memcmp(buffer.msg, tv, sizeof(buffer.N_bytes)) == 0);
|
||||||
|
|
||||||
|
// log
|
||||||
|
mac_log.info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes);
|
||||||
|
|
||||||
|
#if HAVE_PCAP
|
||||||
|
pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
// Test for checking error cases
|
// Test for checking error cases
|
||||||
int mac_sch_pdu_pack_error_test()
|
int mac_sch_pdu_pack_error_test()
|
||||||
{
|
{
|
||||||
|
@ -645,6 +686,11 @@ int main(int argc, char** argv)
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mac_sch_pdu_pack_test6()) {
|
||||||
|
fprintf(stderr, "mac_sch_pdu_pack_test6 failed.\n");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (mac_sch_pdu_pack_error_test()) {
|
if (mac_sch_pdu_pack_error_test()) {
|
||||||
fprintf(stderr, "mac_sch_pdu_pack_error_test failed.\n");
|
fprintf(stderr, "mac_sch_pdu_pack_error_test failed.\n");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
|
|
|
@ -74,7 +74,7 @@ private:
|
||||||
|
|
||||||
std::map<uint32_t, lcid_t> lcgs[NOF_LCG]; // groups LCID in LCG
|
std::map<uint32_t, lcid_t> lcgs[NOF_LCG]; // groups LCID in LCG
|
||||||
|
|
||||||
uint32_t find_max_priority_lcg();
|
uint32_t find_max_priority_lcg_with_data();
|
||||||
typedef enum {NONE, REGULAR, PADDING, PERIODIC} triggered_bsr_type_t;
|
typedef enum {NONE, REGULAR, PADDING, PERIODIC} triggered_bsr_type_t;
|
||||||
triggered_bsr_type_t triggered_bsr_type;
|
triggered_bsr_type_t triggered_bsr_type;
|
||||||
|
|
||||||
|
|
|
@ -223,7 +223,7 @@ bool bsr_proc::generate_bsr(bsr_t* bsr, uint32_t nof_padding_bytes)
|
||||||
// If space only for short
|
// If space only for short
|
||||||
if (nof_lcg > 1) {
|
if (nof_lcg > 1) {
|
||||||
bsr->format = TRUNC_BSR;
|
bsr->format = TRUNC_BSR;
|
||||||
uint32_t max_prio_lcg = find_max_priority_lcg();
|
uint32_t max_prio_lcg = find_max_priority_lcg_with_data();
|
||||||
for (uint32_t i = 0; i < NOF_LCG; i++) {
|
for (uint32_t i = 0; i < NOF_LCG; i++) {
|
||||||
if (max_prio_lcg != i) {
|
if (max_prio_lcg != i) {
|
||||||
bsr->buff_size[i] = 0;
|
bsr->buff_size[i] = 0;
|
||||||
|
@ -383,7 +383,6 @@ bool bsr_proc::generate_padding_bsr(uint32_t nof_padding_bytes, bsr_t* bsr)
|
||||||
set_trigger(NONE);
|
set_trigger(NONE);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -434,13 +433,13 @@ void bsr_proc::setup_lcid(uint32_t lcid, uint32_t new_lcg, uint32_t priority)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t bsr_proc::find_max_priority_lcg()
|
uint32_t bsr_proc::find_max_priority_lcg_with_data()
|
||||||
{
|
{
|
||||||
int32_t max_prio = 99;
|
int32_t max_prio = 99;
|
||||||
uint32_t max_idx = 0;
|
uint32_t max_idx = 0;
|
||||||
for (int i = 0; i < NOF_LCG; i++) {
|
for (int i = 0; i < NOF_LCG; i++) {
|
||||||
for (std::map<uint32_t, lcid_t>::iterator iter = lcgs[i].begin(); iter != lcgs[i].end(); ++iter) {
|
for (std::map<uint32_t, lcid_t>::iterator iter = lcgs[i].begin(); iter != lcgs[i].end(); ++iter) {
|
||||||
if (iter->second.priority < max_prio) {
|
if (iter->second.priority < max_prio && iter->second.old_buffer > 0) {
|
||||||
max_prio = iter->second.priority;
|
max_prio = iter->second.priority;
|
||||||
max_idx = i;
|
max_idx = i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,9 @@ public:
|
||||||
uint32_t get_buffer_state(const uint32_t lcid) { return ul_queues[lcid]; }
|
uint32_t get_buffer_state(const uint32_t lcid) { return ul_queues[lcid]; }
|
||||||
int read_pdu(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes)
|
int read_pdu(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes)
|
||||||
{
|
{
|
||||||
|
if (!read_enable) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
uint32_t len = SRSLTE_MIN(ul_queues[lcid], nof_bytes);
|
uint32_t len = SRSLTE_MIN(ul_queues[lcid], nof_bytes);
|
||||||
|
|
||||||
// set payload bytes to LCID so we can check later if the scheduling was correct
|
// set payload bytes to LCID so we can check later if the scheduling was correct
|
||||||
|
@ -77,7 +80,10 @@ public:
|
||||||
void write_pdu_mch(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes){};
|
void write_pdu_mch(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes){};
|
||||||
uint32_t get_received_bytes() { return received_bytes; }
|
uint32_t get_received_bytes() { return received_bytes; }
|
||||||
|
|
||||||
|
void disable_read() { read_enable = false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool read_enable = true;
|
||||||
uint32_t received_bytes;
|
uint32_t received_bytes;
|
||||||
srslte::log_filter* log;
|
srslte::log_filter* log;
|
||||||
// UL queues where key is LCID and value the queue length
|
// UL queues where key is LCID and value the queue length
|
||||||
|
@ -840,8 +846,6 @@ int mac_ul_sch_pdu_with_short_bsr_test()
|
||||||
// PDU with only padding BSR (long BSR) and the rest padding
|
// PDU with only padding BSR (long BSR) and the rest padding
|
||||||
int mac_ul_sch_pdu_with_padding_bsr_test()
|
int mac_ul_sch_pdu_with_padding_bsr_test()
|
||||||
{
|
{
|
||||||
const uint8_t tv[] = {0x3e, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
|
|
||||||
srslte::log_filter mac_log("MAC");
|
srslte::log_filter mac_log("MAC");
|
||||||
mac_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
mac_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||||
mac_log.set_hex_limit(100000);
|
mac_log.set_hex_limit(100000);
|
||||||
|
@ -863,6 +867,9 @@ int mac_ul_sch_pdu_with_padding_bsr_test()
|
||||||
|
|
||||||
// create UL action and grant and push MAC PDU
|
// create UL action and grant and push MAC PDU
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const uint8_t tv[] = {0x3e, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
mac_interface_phy_lte::tb_action_ul_t ul_action = {};
|
mac_interface_phy_lte::tb_action_ul_t ul_action = {};
|
||||||
mac_interface_phy_lte::mac_grant_ul_t mac_grant = {};
|
mac_interface_phy_lte::mac_grant_ul_t mac_grant = {};
|
||||||
|
|
||||||
|
@ -884,6 +891,41 @@ int mac_ul_sch_pdu_with_padding_bsr_test()
|
||||||
TESTASSERT(memcmp(ul_action.tb.payload, tv, sizeof(tv)) == 0);
|
TESTASSERT(memcmp(ul_action.tb.payload, tv, sizeof(tv)) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create UL action and grant and push MAC PDU
|
||||||
|
{
|
||||||
|
|
||||||
|
const uint8_t tv[] = {0x1c, 0x42};
|
||||||
|
|
||||||
|
mac_interface_phy_lte::tb_action_ul_t ul_action = {};
|
||||||
|
mac_interface_phy_lte::mac_grant_ul_t mac_grant = {};
|
||||||
|
|
||||||
|
mac_grant.rnti = crnti; // make sure MAC picks it up as valid UL grant
|
||||||
|
mac_grant.tb.ndi_present = true;
|
||||||
|
mac_grant.tb.ndi = true;
|
||||||
|
mac_grant.pid = 2;
|
||||||
|
mac_grant.tb.tbs = 2; // give enough room for Padding BSR
|
||||||
|
int cc_idx = 0;
|
||||||
|
|
||||||
|
// Add data to multiple LCID
|
||||||
|
mac.setup_lcid(1, 1, 1, -1, 0);
|
||||||
|
mac.setup_lcid(2, 2, 2, -1, 0);
|
||||||
|
rlc.disable_read();
|
||||||
|
rlc.write_sdu(1, 10);
|
||||||
|
rlc.write_sdu(2, 100);
|
||||||
|
mac.run_tti(1);
|
||||||
|
|
||||||
|
// Send grant to MAC and get action for this TB, then call tb_decoded to unlock MAC
|
||||||
|
mac.new_grant_ul(cc_idx, mac_grant, &ul_action);
|
||||||
|
|
||||||
|
// print generated PDU
|
||||||
|
mac_log.info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs);
|
||||||
|
#if HAVE_PCAP
|
||||||
|
pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TESTASSERT(memcmp(ul_action.tb.payload, tv, sizeof(tv)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
// make sure MAC PDU thread picks up before stopping
|
// make sure MAC PDU thread picks up before stopping
|
||||||
sleep(1);
|
sleep(1);
|
||||||
mac.run_tti(0);
|
mac.run_tti(0);
|
||||||
|
|
Loading…
Reference in New Issue