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
This commit is contained in:
parent
14e26cbca3
commit
be314d9a54
|
@ -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();
|
||||
|
|
109
src/tbf_dl.cpp
109
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;
|
||||
|
||||
/* get data and header from current block */
|
||||
block_data = m_rlc.block(index)->block;
|
||||
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;
|
||||
|
||||
gprs_rlc_data_info_init_dl(&rlc, cs, false);
|
||||
if (index2 >= 0) {
|
||||
bsns[num_bsns] = index2;
|
||||
num_bsns += 1;
|
||||
}
|
||||
|
||||
if (num_bsns == 1)
|
||||
cs.decToSingleBlock(&need_padding);
|
||||
|
||||
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 */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue