From be314d9a54578d1eb31ab84f5de9bc16f8e892e9 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 2 Feb 2016 15:32:10 +0100 Subject: edge: Refactor create_dl_acked_block for multi-block support Currently the method is hard-coded to support a single BSN only. MCS-7 to MCS-9 encode 2 data blocks into a single RLC data message. This commit refactors create_dl_acked_block to process any number of blocks internally. Note that this does not extend the parameter list accordingly and just duplicates the BSN if these MCS are being used. Sponsored-by: On-Waves ehf --- src/tbf.h | 2 +- src/tbf_dl.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 86 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/tbf.h b/src/tbf.h index 443f85fc..2eefbeea 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -408,7 +408,7 @@ protected: struct msgb *create_new_bsn(const uint32_t fn, const uint8_t ts); struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts, - const int index); + int index, int index2 = -1); int update_window(const uint8_t ssn, const uint8_t *rbb); int update_window(unsigned first_bsn, const struct bitvec *rbb); int maybe_start_new_window(); diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 6208b601..21b2ba13 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -519,9 +519,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( const uint32_t fn, const uint8_t ts, - const int index) + int index, int index2) { - uint8_t *block_data, *msg_data; + uint8_t *msg_data; struct msgb *dl_msg; unsigned msg_len; bool need_poll; @@ -530,26 +530,96 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( unsigned int rrbp; uint32_t new_poll_fn; int rc; - + bool is_final = false; gprs_rlc_data_info rlc; GprsCodingScheme cs; - gprs_rlc_data_block_info *rdbi; + int bsns[ARRAY_SIZE(rlc.block_info)]; + unsigned num_bsns; + int punct[ARRAY_SIZE(rlc.block_info)]; + bool need_padding = false; + + /* + * TODO: This is an experimental work-around to put 2 BSN into + * MSC-7 to MCS-9 encoded messages. It just sends the same BSN + * twice in the block. The cs should be derived from the TBF's + * current CS such that both BSNs (that must be compatible) can + * be put into the data area, even if the resulting CS is higher than + * the current limit. + */ + cs = m_rlc.block(index)->cs; + bsns[0] = index; + num_bsns = 1; - /* get data and header from current block */ - block_data = m_rlc.block(index)->block; + if (index2 >= 0) { + bsns[num_bsns] = index2; + num_bsns += 1; + } - cs = m_rlc.block(index)->cs; + if (num_bsns == 1) + cs.decToSingleBlock(&need_padding); - gprs_rlc_data_info_init_dl(&rlc, cs, false); + gprs_rlc_data_info_init_dl(&rlc, cs, need_padding); rlc.usf = 7; /* will be set at scheduler */ rlc.pr = 0; /* FIXME: power reduction */ rlc.tfi = m_tfi; /* TFI */ - /* TODO: Use real puncturing values */ - rlc.cps = gprs_rlc_mcs_cps(cs, 0, 0, 0); - rlc.block_info[data_block_idx] = m_rlc.block(index)->block_info; - rdbi = &rlc.block_info[data_block_idx]; + /* return data block(s) as message */ + msg_len = cs.sizeDL(); + dl_msg = msgb_alloc(msg_len, "rlcmac_dl_data"); + if (!dl_msg) + return NULL; + + msg_data = msgb_put(dl_msg, msg_len); + + /* Copy block(s) to RLC message */ + for (data_block_idx = 0; data_block_idx < rlc.num_data_blocks; + data_block_idx++) + { + int bsn; + GprsCodingScheme cs_enc; + uint8_t *block_data; + gprs_rlc_data_block_info *rdbi, *block_info; + + /* Check if there are more blocks than BSNs */ + if (data_block_idx < num_bsns) + bsn = bsns[data_block_idx]; + else + bsn = bsns[0]; + + cs_enc = m_rlc.block(bsn)->cs; + + /* get data and header from current block */ + block_data = m_rlc.block(bsn)->block; + + /* TODO: Use real puncturing values */ + punct[data_block_idx] = data_block_idx; + + rdbi = &rlc.block_info[data_block_idx]; + block_info = &m_rlc.block(bsn)->block_info; + + if(rdbi->data_len != m_rlc.block(bsn)->len) { + LOGP(DRLCMACDL, LOGL_ERROR, + "ERROR: Expected len = %d for %s instead of " + "%d in data unit %d (BSN %d, %s)\n", + rdbi->data_len, cs.name(), m_rlc.block(bsn)->len, + data_block_idx, bsn, cs_enc.name()); + OSMO_ASSERT(rdbi->data_len == m_rlc.block(bsn)->len); + } + rdbi->e = block_info->e; + rdbi->cv = block_info->cv; + rdbi->bsn = bsn; + is_final = is_final || rdbi->cv == 0; + + LOGP(DRLCMACDL, LOGL_DEBUG, "- Copying data unit %d (BSN %d)\n", + data_block_idx, bsn); + + Encoding::rlc_copy_from_aligned_buffer(&rlc, data_block_idx, + msg_data, block_data); + } + + OSMO_ASSERT(ARRAY_SIZE(punct) >= 2); + rlc.cps = gprs_rlc_mcs_cps(cs, punct[0], punct[1], need_padding); /* If the TBF has just started, relate frames_since_last_poll to the * current fn */ @@ -583,7 +653,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( "TS %d\n", ts); m_tx_counter = 0; /* start timer whenever we send the final block */ - if (rdbi->cv == 0) + if (is_final) tbf_timer_start(this, 3191, bts_data()->t3191, 0); /* Clear poll timeout flag */ @@ -604,20 +674,11 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( } } - msg_len = cs.sizeDL(); - - /* return data block as message */ - dl_msg = msgb_alloc(msg_len, "rlcmac_dl_data"); - if (!dl_msg) - return NULL; - - msg_data = msgb_put(dl_msg, msg_len); Encoding::rlc_write_dl_data_header(&rlc, msg_data); - Encoding::rlc_copy_from_aligned_buffer(&rlc, data_block_idx, msg_data, - block_data); - LOGP(DRLCMACDL, LOGL_DEBUG, "msg block (BSN %d, %s): %s\n", + LOGP(DRLCMACDL, LOGL_DEBUG, "msg block (BSN %d, %s%s): %s\n", index, cs.name(), + need_padding ? ", padded" : "", msgb_hexdump(dl_msg)); /* Increment TX-counter */ -- cgit v1.2.3