Fix issues in uplink QoS (#636)

Fix bugs in Long BSR and Truncated BSR and added unit tests
This commit is contained in:
Ismael Gomez 2019-09-02 22:48:41 +02:00 committed by GitHub
parent ef61f0408c
commit 69edee4e6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 97 additions and 10 deletions

View File

@ -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;
if (((sch_pdu*)parent)->has_space_ce(ce_size)) {
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[1] = (buff_size_table(buff_size[1]) & 0xf) << 4 | (buff_size_table(buff_size[2]) & 0xf0) >> 4;
w_payload_ce[2] = (buff_size_table(buff_size[2]) & 0x3) << 6 | (buff_size_table(buff_size[3]) & 0x3f);
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]) & 0x3c) >> 2);
w_payload_ce[2] = ((buff_size_table(buff_size[2]) & 0x3) << 6) | ((buff_size_table(buff_size[3]) & 0x3f));
} else {
w_payload_ce[0] = (nonzero_lcg & 0x3) << 6 | (buff_size_table(buff_size[nonzero_lcg]) & 0x3f);
}

View File

@ -456,6 +456,47 @@ int mac_sch_pdu_pack_test5()
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
int mac_sch_pdu_pack_error_test()
{
@ -645,6 +686,11 @@ int main(int argc, char** argv)
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()) {
fprintf(stderr, "mac_sch_pdu_pack_error_test failed.\n");
return SRSLTE_ERROR;

View File

@ -74,7 +74,7 @@ private:
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;
triggered_bsr_type_t triggered_bsr_type;

View File

@ -223,7 +223,7 @@ bool bsr_proc::generate_bsr(bsr_t* bsr, uint32_t nof_padding_bytes)
// If space only for short
if (nof_lcg > 1) {
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++) {
if (max_prio_lcg != i) {
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);
ret = true;
}
pthread_mutex_unlock(&mutex);
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;
uint32_t max_idx = 0;
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) {
if (iter->second.priority < max_prio) {
if (iter->second.priority < max_prio && iter->second.old_buffer > 0) {
max_prio = iter->second.priority;
max_idx = i;
}

View File

@ -54,6 +54,9 @@ public:
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)
{
if (!read_enable) {
return 0;
}
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
@ -77,7 +80,10 @@ public:
void write_pdu_mch(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes){};
uint32_t get_received_bytes() { return received_bytes; }
void disable_read() { read_enable = false; }
private:
bool read_enable = true;
uint32_t received_bytes;
srslte::log_filter* log;
// 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
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");
mac_log.set_level(srslte::LOG_LEVEL_DEBUG);
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
{
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::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);
}
// 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
sleep(1);
mac.run_tti(0);