forked from cellular-infrastructure/osmo-pcu
tbf, ...: Make the fields in the dl/ul struct member variables
There is no need for the union/struct anymore. Make the variable members of the UL/DL class. As a result gprs_rlc_dl_window gets a reset() method because memset(&dir.dl, 0, sizeof(dir.dl)) doesn't work anymore in reuse_tbf(). Ticket: SYS#389 Sponsored by: On-Waves ehf
This commit is contained in:
parent
6a8a1dcda2
commit
7e994e392d
|
@ -408,7 +408,7 @@ int BTS::rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn)
|
|||
|
||||
LOGP(DRLCMAC, LOGL_DEBUG, "Got IMM.ASS confirm for TLLI=%08x\n", tlli);
|
||||
|
||||
if (dl_tbf->dir.dl.wait_confirm)
|
||||
if (dl_tbf->m_wait_confirm)
|
||||
tbf_timer_start(dl_tbf, 0, Tassign_agch);
|
||||
|
||||
return 0;
|
||||
|
@ -490,7 +490,7 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta)
|
|||
else
|
||||
plen = Encoding::write_immediate_assignment(&m_bts, immediate_assignment, 0, ra,
|
||||
Fn, tbf->ta, tbf->trx->arfcn, tbf->first_ts, tbf->tsc(),
|
||||
tbf->tfi(), tbf->dir.ul.usf[tbf->first_ts], 0, 0, 0, 0,
|
||||
tbf->tfi(), tbf->m_usf[tbf->first_ts], 0, 0, 0, 0,
|
||||
m_bts.alpha, m_bts.gamma, -1);
|
||||
pcu_l1if_tx_agch(immediate_assignment, plen);
|
||||
bitvec_free(immediate_assignment);
|
||||
|
@ -532,7 +532,7 @@ void BTS::trigger_dl_ass(
|
|||
dl_tbf->assign_imsi(imsi);
|
||||
/* send immediate assignment */
|
||||
dl_tbf->bts->snd_dl_ass(dl_tbf, 0, imsi);
|
||||
dl_tbf->dir.dl.wait_confirm = 1;
|
||||
dl_tbf->m_wait_confirm = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ void Encoding::write_packet_uplink_assignment(
|
|||
for (ts = 0; ts < 8; ts++) {
|
||||
if (tbf->pdch[ts]) {
|
||||
bitvec_write_field(dest, wp,0x1,1); // USF_TN(i): on
|
||||
bitvec_write_field(dest, wp,tbf->dir.ul.usf[ts],3); // USF_TN(i)
|
||||
bitvec_write_field(dest, wp,tbf->m_usf[ts],3); // USF_TN(i)
|
||||
if (alpha || gamma)
|
||||
bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter
|
||||
} else
|
||||
|
@ -382,7 +382,7 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts,
|
|||
|
||||
char rbb[65];
|
||||
|
||||
tbf->dir.ul.window.update_rbb(rbb);
|
||||
tbf->m_window.update_rbb(rbb);
|
||||
|
||||
LOGP(DRLCMACUL, LOGL_DEBUG, "Encoding Ack/Nack for %s "
|
||||
"(final=%d)\n", tbf_name(tbf), final);
|
||||
|
@ -399,7 +399,7 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts,
|
|||
block->u.Packet_Uplink_Ack_Nack.UnionType = 0x0; // PU_AckNack_GPRS = on
|
||||
block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.CHANNEL_CODING_COMMAND = bts->initial_cs_ul - 1; // CS1
|
||||
block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.FINAL_ACK_INDICATION = final; // FINAL ACK INDICATION
|
||||
block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.STARTING_SEQUENCE_NUMBER = tbf->dir.ul.window.ssn(); // STARTING_SEQUENCE_NUMBER
|
||||
block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.STARTING_SEQUENCE_NUMBER = tbf->m_window.ssn(); // STARTING_SEQUENCE_NUMBER
|
||||
|
||||
encode_rbb(rbb, block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.RECEIVED_BLOCK_BITMAP);
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ static uint8_t sched_select_uplink(uint8_t trx, uint8_t ts, uint32_t fn,
|
|||
continue;
|
||||
|
||||
/* use this USF */
|
||||
usf = tbf->dir.ul.usf[ts];
|
||||
usf = tbf->m_usf[ts];
|
||||
LOGP(DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: TRX=%d "
|
||||
"TS=%d FN=%d block_nr=%d scheduling USF=%d for "
|
||||
"required uplink resource of UL TFI=%d\n", trx, ts, fn,
|
||||
|
@ -186,7 +186,7 @@ static struct msgb *sched_select_downlink(struct gprs_rlcmac_bts *bts,
|
|||
continue;
|
||||
|
||||
/* waiting for CCCH IMM.ASS confirm */
|
||||
if (tbf->dir.dl.wait_confirm)
|
||||
if (tbf->m_wait_confirm)
|
||||
continue;
|
||||
|
||||
LOGP(DRLCMACSCHED, LOGL_DEBUG, "Scheduling data message at "
|
||||
|
|
|
@ -86,7 +86,7 @@ static inline int8_t find_free_usf(struct gprs_rlcmac_pdch *pdch)
|
|||
tbf = pdch->ul_tbf_by_tfi(tfi);
|
||||
if (!tbf)
|
||||
continue;
|
||||
usf_map |= (1 << tbf->dir.ul.usf[pdch->ts_no]);
|
||||
usf_map |= (1 << tbf->m_usf[pdch->ts_no]);
|
||||
}
|
||||
|
||||
/* look for USF, don't use USF=7 */
|
||||
|
@ -122,7 +122,7 @@ static void assign_uplink_tbf_usf(
|
|||
{
|
||||
tbf->trx->ul_tbf[tbf->tfi()] = tbf;
|
||||
tbf->pdch[pdch->ts_no] = pdch;
|
||||
tbf->dir.ul.usf[pdch->ts_no] = usf;
|
||||
tbf->m_usf[pdch->ts_no] = usf;
|
||||
}
|
||||
|
||||
static void assign_dlink_tbf(
|
||||
|
|
|
@ -46,6 +46,13 @@ void gprs_rlc_v_b::reset()
|
|||
mark_invalid(i);
|
||||
}
|
||||
|
||||
void gprs_rlc_dl_window::reset()
|
||||
{
|
||||
m_v_s = 0;
|
||||
m_v_a = 0;
|
||||
m_v_b.reset();
|
||||
}
|
||||
|
||||
int gprs_rlc_dl_window::resend_needed()
|
||||
{
|
||||
for (uint16_t bsn = v_a(); bsn != v_s(); bsn = (bsn + 1) & mod_sns()) {
|
||||
|
|
|
@ -109,6 +109,7 @@ private:
|
|||
* most simple form of inheritance is not a POD anymore.
|
||||
*/
|
||||
struct gprs_rlc_dl_window {
|
||||
void reset();
|
||||
const uint16_t mod_sns() const;
|
||||
const uint16_t sns() const;
|
||||
const uint16_t ws() const;
|
||||
|
|
113
src/tbf.cpp
113
src/tbf.cpp
|
@ -132,8 +132,8 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts,
|
|||
#warning "Do the same look up for IMSI, TLLI and OLD_TLLI"
|
||||
#warning "Refactor the below lines... into a new method"
|
||||
ul_tbf = bts->bts->ul_tbf_by_tlli(tlli);
|
||||
if (ul_tbf && ul_tbf->dir.ul.contention_resolution_done
|
||||
&& !ul_tbf->dir.ul.final_ack_sent) {
|
||||
if (ul_tbf && ul_tbf->m_contention_resolution_done
|
||||
&& !ul_tbf->m_final_ack_sent) {
|
||||
use_trx = ul_tbf->trx->trx_no;
|
||||
ta = ul_tbf->ta;
|
||||
ss = 0;
|
||||
|
@ -240,7 +240,7 @@ gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
|
|||
}
|
||||
tbf->m_tlli = tlli;
|
||||
tbf->m_tlli_valid = 1; /* no contention resolution */
|
||||
tbf->dir.ul.contention_resolution_done = 1;
|
||||
tbf->m_contention_resolution_done = 1;
|
||||
tbf->ta = ta; /* use current TA */
|
||||
tbf_new_state(tbf, GPRS_RLCMAC_ASSIGN);
|
||||
tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH);
|
||||
|
@ -405,8 +405,8 @@ void gprs_rlcmac_tbf::poll_timeout()
|
|||
ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE;
|
||||
if (state_is(GPRS_RLCMAC_FINISHED)) {
|
||||
gprs_rlcmac_ul_tbf *ul_tbf = static_cast<gprs_rlcmac_ul_tbf *>(this);
|
||||
ul_tbf->dir.ul.n3103++;
|
||||
if (ul_tbf->dir.ul.n3103 == ul_tbf->bts->bts_data()->n3103) {
|
||||
ul_tbf->m_n3103++;
|
||||
if (ul_tbf->m_n3103 == ul_tbf->bts->bts_data()->n3103) {
|
||||
LOGP(DRLCMAC, LOGL_NOTICE,
|
||||
"- N3103 exceeded\n");
|
||||
tbf_new_state(ul_tbf, GPRS_RLCMAC_RELEASING);
|
||||
|
@ -477,7 +477,7 @@ void gprs_rlcmac_tbf::poll_timeout()
|
|||
m_imsi);
|
||||
/* send immediate assignment */
|
||||
dl_tbf->bts->snd_dl_ass(dl_tbf, 0, m_imsi);
|
||||
dl_tbf->dir.dl.wait_confirm = 1;
|
||||
dl_tbf->m_wait_confirm = 1;
|
||||
}
|
||||
} else
|
||||
LOGP(DRLCMAC, LOGL_ERROR, "- Poll Timeout, but no event!\n");
|
||||
|
@ -621,7 +621,7 @@ void gprs_rlcmac_tbf::handle_timeout()
|
|||
}
|
||||
if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) {
|
||||
gprs_rlcmac_dl_tbf *dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(this);
|
||||
dl_tbf->dir.dl.wait_confirm = 0;
|
||||
dl_tbf->m_wait_confirm = 0;
|
||||
if (dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) {
|
||||
tbf_assign_control_ts(dl_tbf);
|
||||
|
||||
|
@ -898,15 +898,15 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(uint32_t fn, uint8_t ts)
|
|||
{
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink (V(A)==%d .. "
|
||||
"V(S)==%d)\n", tbf_name(this),
|
||||
dir.dl.window.v_a(), dir.dl.window.v_s());
|
||||
m_window.v_a(), m_window.v_s());
|
||||
|
||||
do_resend:
|
||||
/* check if there is a block with negative acknowledgement */
|
||||
int resend_bsn = dir.dl.window.resend_needed();
|
||||
int resend_bsn = m_window.resend_needed();
|
||||
if (resend_bsn >= 0) {
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "- Resending BSN %d\n", resend_bsn);
|
||||
/* re-send block with negative aknowlegement */
|
||||
dir.dl.window.m_v_b.mark_unacked(resend_bsn);
|
||||
m_window.m_v_b.mark_unacked(resend_bsn);
|
||||
bts->rlc_resent();
|
||||
return create_dl_acked_block(fn, ts, resend_bsn, false);
|
||||
}
|
||||
|
@ -917,12 +917,12 @@ do_resend:
|
|||
if (state_is(GPRS_RLCMAC_FINISHED)) {
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "- Restarting at BSN %d, "
|
||||
"because all blocks have been transmitted.\n",
|
||||
dir.dl.window.v_a());
|
||||
m_window.v_a());
|
||||
bts->rlc_restarted();
|
||||
} else {
|
||||
LOGP(DRLCMACDL, LOGL_NOTICE, "- Restarting at BSN %d, "
|
||||
"because all window is stalled.\n",
|
||||
dir.dl.window.v_a());
|
||||
m_window.v_a());
|
||||
bts->rlc_stalled();
|
||||
}
|
||||
/* If V(S) == V(A) and finished state, we would have received
|
||||
|
@ -931,17 +931,17 @@ do_resend:
|
|||
* from MS. But in this case we did not receive the final ack
|
||||
* indication from MS. This should never happen if MS works
|
||||
* correctly. */
|
||||
if (dir.dl.window.window_empty()) {
|
||||
if (m_window.window_empty()) {
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "- MS acked all blocks, "
|
||||
"so we re-transmit final block!\n");
|
||||
/* we just send final block again */
|
||||
int16_t index = dir.dl.window.v_s_mod(-1);
|
||||
int16_t index = m_window.v_s_mod(-1);
|
||||
bts->rlc_resent();
|
||||
return create_dl_acked_block(fn, ts, index, false);
|
||||
}
|
||||
|
||||
/* cycle through all unacked blocks */
|
||||
int resend = dir.dl.window.mark_for_resend();
|
||||
int resend = m_window.mark_for_resend();
|
||||
|
||||
/* At this point there should be at least one unacked block
|
||||
* to be resent. If not, this is an software error. */
|
||||
|
@ -950,7 +950,7 @@ do_resend:
|
|||
"There are no unacknowledged blocks, but V(A) "
|
||||
" != V(S). PLEASE FIX!\n");
|
||||
/* we just send final block again */
|
||||
int16_t index = dir.dl.window.v_s_mod(-1);
|
||||
int16_t index = m_window.v_s_mod(-1);
|
||||
return create_dl_acked_block(fn, ts, index, false);
|
||||
}
|
||||
goto do_resend;
|
||||
|
@ -968,10 +968,10 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t
|
|||
uint16_t space, chunk;
|
||||
gprs_rlc_data *rlc_data;
|
||||
bool first_fin_ack = false;
|
||||
const uint16_t bsn = dir.dl.window.v_s();
|
||||
const uint16_t bsn = m_window.v_s();
|
||||
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "- Sending new block at BSN %d\n",
|
||||
dir.dl.window.v_s());
|
||||
m_window.v_s());
|
||||
|
||||
#warning "Selection of the CS doesn't belong here"
|
||||
if (cs == 0) {
|
||||
|
@ -1120,8 +1120,8 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t
|
|||
#warning "move this up?"
|
||||
rlc_data->len = block_length;
|
||||
/* raise send state and set ack state array */
|
||||
dir.dl.window.m_v_b.mark_unacked(bsn);
|
||||
dir.dl.window.increment_send();
|
||||
m_window.m_v_b.mark_unacked(bsn);
|
||||
m_window.increment_send();
|
||||
|
||||
return create_dl_acked_block(fn, ts, bsn, first_fin_ack);
|
||||
}
|
||||
|
@ -1145,7 +1145,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
|
|||
|
||||
/* poll after POLL_ACK_AFTER_FRAMES frames, or when final block is tx.
|
||||
*/
|
||||
if (dir.dl.tx_counter >= POLL_ACK_AFTER_FRAMES || first_fin_ack) {
|
||||
if (m_tx_counter >= POLL_ACK_AFTER_FRAMES || first_fin_ack) {
|
||||
if (first_fin_ack) {
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "- Scheduling Ack/Nack "
|
||||
"polling, because first final block sent.\n");
|
||||
|
@ -1171,7 +1171,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
|
|||
else {
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "Polling sheduled in this "
|
||||
"TS %d\n", ts);
|
||||
dir.dl.tx_counter = 0;
|
||||
m_tx_counter = 0;
|
||||
/* start timer whenever we send the final block */
|
||||
if (rh->fbi == 1)
|
||||
tbf_timer_start(this, 3191, bts_data()->t3191, 0);
|
||||
|
@ -1192,7 +1192,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
|
|||
return NULL;
|
||||
|
||||
/* Increment TX-counter */
|
||||
dir.dl.tx_counter++;
|
||||
m_tx_counter++;
|
||||
|
||||
memcpy(msgb_put(dl_msg, len), data, len);
|
||||
bts->rlc_sent();
|
||||
|
@ -1233,7 +1233,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn)
|
|||
|
||||
/* be sure to check first, if contention resolution is done,
|
||||
* otherwise we cannot send the assignment yet */
|
||||
if (!ul_tbf->dir.ul.contention_resolution_done) {
|
||||
if (!ul_tbf->m_contention_resolution_done) {
|
||||
LOGP(DRLCMAC, LOGL_DEBUG, "Cannot assign DL TBF now, "
|
||||
"because contention resolution is not "
|
||||
"finished.\n");
|
||||
|
@ -1391,14 +1391,14 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn)
|
|||
|
||||
/* now we must set this flag, so we are allowed to assign downlink
|
||||
* TBF on PACCH. it is only allowed when TLLI is acknowledged. */
|
||||
dir.ul.contention_resolution_done = 1;
|
||||
m_contention_resolution_done = 1;
|
||||
|
||||
if (final) {
|
||||
poll_state = GPRS_RLCMAC_POLL_SCHED;
|
||||
poll_fn = (fn + 13) % 2715648;
|
||||
/* waiting for final acknowledge */
|
||||
ul_ack_state = GPRS_RLCMAC_UL_ACK_WAIT_ACK;
|
||||
dir.ul.final_ack_sent = 1;
|
||||
m_final_ack_sent = 1;
|
||||
} else
|
||||
ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE;
|
||||
|
||||
|
@ -1411,7 +1411,7 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
|
|||
uint16_t lost = 0, received = 0;
|
||||
char show_rbb[65];
|
||||
char show_v_b[RLC_MAX_SNS + 1];
|
||||
const uint16_t mod_sns = dir.dl.window.mod_sns();
|
||||
const uint16_t mod_sns = m_window.mod_sns();
|
||||
|
||||
Decoding::extract_rbb(rbb, show_rbb);
|
||||
/* show received array in debug (bit 64..1) */
|
||||
|
@ -1421,9 +1421,9 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
|
|||
|
||||
/* apply received array to receive state (SSN-64..SSN-1) */
|
||||
/* calculate distance of ssn from V(S) */
|
||||
dist = (dir.dl.window.v_s() - ssn) & mod_sns;
|
||||
dist = (m_window.v_s() - ssn) & mod_sns;
|
||||
/* check if distance is less than distance V(A)..V(S) */
|
||||
if (dist >= dir.dl.window.distance()) {
|
||||
if (dist >= m_window.distance()) {
|
||||
/* this might happpen, if the downlink assignment
|
||||
* was not received by ms and the ack refers
|
||||
* to previous TBF
|
||||
|
@ -1434,24 +1434,24 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
|
|||
return 1; /* indicate to free TBF */
|
||||
}
|
||||
|
||||
dir.dl.window.update(bts, show_rbb, ssn,
|
||||
m_window.update(bts, show_rbb, ssn,
|
||||
&lost, &received);
|
||||
|
||||
/* report lost and received packets */
|
||||
gprs_rlcmac_received_lost(this, received, lost);
|
||||
|
||||
/* raise V(A), if possible */
|
||||
dir.dl.window.raise(dir.dl.window.move_window());
|
||||
m_window.raise(m_window.move_window());
|
||||
|
||||
/* show receive state array in debug (V(A)..V(S)-1) */
|
||||
dir.dl.window.show_state(show_v_b);
|
||||
m_window.show_state(show_v_b);
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "- V(B): (V(A)=%d)\"%s\""
|
||||
"(V(S)-1=%d) A=Acked N=Nacked U=Unacked "
|
||||
"X=Resend-Unacked I=Invalid\n",
|
||||
dir.dl.window.v_a(), show_v_b,
|
||||
dir.dl.window.v_s_mod(-1));
|
||||
m_window.v_a(), show_v_b,
|
||||
m_window.v_s_mod(-1));
|
||||
|
||||
if (state_is(GPRS_RLCMAC_FINISHED) && dir.dl.window.window_empty()) {
|
||||
if (state_is(GPRS_RLCMAC_FINISHED) && m_window.window_empty()) {
|
||||
LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of "
|
||||
"all blocks, but without final ack "
|
||||
"inidcation (don't worry)\n");
|
||||
|
@ -1467,7 +1467,7 @@ int gprs_rlcmac_dl_tbf::maybe_start_new_window()
|
|||
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n");
|
||||
/* range V(A)..V(S)-1 */
|
||||
received = dir.dl.window.count_unacked();
|
||||
received = m_window.count_unacked();
|
||||
|
||||
/* report all outstanding packets as received */
|
||||
gprs_rlcmac_received_lost(this, received, 0);
|
||||
|
@ -1625,14 +1625,14 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t
|
|||
struct rlc_ul_header *rh = (struct rlc_ul_header *)data;
|
||||
int rc;
|
||||
|
||||
const uint16_t mod_sns = dir.ul.window.mod_sns();
|
||||
const uint16_t ws = dir.ul.window.ws();
|
||||
const uint16_t mod_sns = m_window.mod_sns();
|
||||
const uint16_t ws = m_window.ws();
|
||||
|
||||
this->state_flags |= (1 << GPRS_RLCMAC_FLAG_UL_DATA);
|
||||
|
||||
LOGP(DRLCMACUL, LOGL_DEBUG, "UL DATA TFI=%d received (V(Q)=%d .. "
|
||||
"V(R)=%d)\n", rh->tfi, this->dir.ul.window.v_q(),
|
||||
this->dir.ul.window.v_r());
|
||||
"V(R)=%d)\n", rh->tfi, this->m_window.v_q(),
|
||||
this->m_window.v_r());
|
||||
|
||||
/* process RSSI */
|
||||
gprs_rlcmac_rssi(this, rssi);
|
||||
|
@ -1662,13 +1662,13 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t
|
|||
tbf_timer_start(this, 3169, bts_data()->t3169, 0);
|
||||
|
||||
/* Increment RX-counter */
|
||||
this->dir.ul.rx_counter++;
|
||||
this->m_rx_counter++;
|
||||
|
||||
if (!dir.ul.window.is_in_window(rh->bsn)) {
|
||||
if (!m_window.is_in_window(rh->bsn)) {
|
||||
LOGP(DRLCMACUL, LOGL_DEBUG, "- BSN %d out of window "
|
||||
"%d..%d (it's normal)\n", rh->bsn,
|
||||
dir.ul.window.v_q(),
|
||||
(dir.ul.window.v_q() + ws - 1) & mod_sns);
|
||||
m_window.v_q(),
|
||||
(m_window.v_q() + ws - 1) & mod_sns);
|
||||
maybe_schedule_uplink_acknack(rh);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1676,15 +1676,15 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t
|
|||
/* Write block to buffer and set receive state array. */
|
||||
m_rlc.block(rh->bsn)->put_data(data, len);
|
||||
LOGP(DRLCMACUL, LOGL_DEBUG, "- BSN %d storing in window (%d..%d)\n",
|
||||
rh->bsn, dir.ul.window.v_q(),
|
||||
(dir.ul.window.v_q() + ws - 1) & mod_sns);
|
||||
rh->bsn, m_window.v_q(),
|
||||
(m_window.v_q() + ws - 1) & mod_sns);
|
||||
|
||||
/* Raise V(Q) if possible, and retrieve LLC frames from blocks.
|
||||
* This is looped until there is a gap (non received block) or
|
||||
* the window is empty.*/
|
||||
const uint16_t v_q_beg = dir.ul.window.v_q();
|
||||
const uint16_t v_q_beg = m_window.v_q();
|
||||
|
||||
const uint16_t count = dir.ul.window.receive_bsn(rh->bsn);
|
||||
const uint16_t count = m_window.receive_bsn(rh->bsn);
|
||||
|
||||
/* Retrieve LLC frames from blocks that are ready */
|
||||
for (uint16_t i = 0; i < count; ++i) {
|
||||
|
@ -1694,9 +1694,9 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t
|
|||
|
||||
/* Check CV of last frame in buffer */
|
||||
if (this->state_is(GPRS_RLCMAC_FLOW) /* still in flow state */
|
||||
&& this->dir.ul.window.v_q() == this->dir.ul.window.v_r()) { /* if complete */
|
||||
&& this->m_window.v_q() == this->m_window.v_r()) { /* if complete */
|
||||
struct rlc_ul_header *last_rh = (struct rlc_ul_header *)
|
||||
m_rlc.block((dir.ul.window.v_r() - 1) & mod_sns)->block;
|
||||
m_rlc.block((m_window.v_r() - 1) & mod_sns)->block;
|
||||
LOGP(DRLCMACUL, LOGL_DEBUG, "- No gaps in received block, "
|
||||
"last block: BSN=%d CV=%d\n", last_rh->bsn,
|
||||
last_rh->cv);
|
||||
|
@ -1705,7 +1705,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t
|
|||
"TBF\n");
|
||||
tbf_new_state(this, GPRS_RLCMAC_FINISHED);
|
||||
/* Reset N3103 counter. */
|
||||
this->dir.ul.n3103 = 0;
|
||||
this->m_n3103 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1719,7 +1719,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t
|
|||
void gprs_rlcmac_ul_tbf::maybe_schedule_uplink_acknack(const rlc_ul_header *rh)
|
||||
{
|
||||
if (rh->si || rh->ti || state_is(GPRS_RLCMAC_FINISHED)
|
||||
|| (dir.ul.rx_counter % SEND_ACK_AFTER_FRAMES) == 0) {
|
||||
|| (m_rx_counter % SEND_ACK_AFTER_FRAMES) == 0) {
|
||||
if (rh->si) {
|
||||
LOGP(DRLCMACUL, LOGL_NOTICE, "- Scheduling Ack/Nack, "
|
||||
"because MS is stalled.\n");
|
||||
|
@ -1732,7 +1732,7 @@ void gprs_rlcmac_ul_tbf::maybe_schedule_uplink_acknack(const rlc_ul_header *rh)
|
|||
LOGP(DRLCMACUL, LOGL_DEBUG, "- Scheduling Ack/Nack, "
|
||||
"because last block has CV==0.\n");
|
||||
}
|
||||
if ((dir.ul.rx_counter % SEND_ACK_AFTER_FRAMES) == 0) {
|
||||
if ((m_rx_counter % SEND_ACK_AFTER_FRAMES) == 0) {
|
||||
LOGP(DRLCMACUL, LOGL_DEBUG, "- Scheduling Ack/Nack, "
|
||||
"because %d frames received.\n",
|
||||
SEND_ACK_AFTER_FRAMES);
|
||||
|
@ -1793,8 +1793,9 @@ void gprs_rlcmac_dl_tbf::reuse_tbf(const uint8_t *data, const uint16_t len)
|
|||
bts->llc_frame_sched();
|
||||
|
||||
/* reset rlc states */
|
||||
memset(&dir.dl, 0, sizeof(dir.dl));
|
||||
dir.dl.window.m_v_b.reset();
|
||||
m_tx_counter = 0;
|
||||
m_wait_confirm = 0;
|
||||
m_window.reset();
|
||||
|
||||
/* keep to flags */
|
||||
state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;
|
||||
|
@ -1810,7 +1811,7 @@ void gprs_rlcmac_dl_tbf::reuse_tbf(const uint8_t *data, const uint16_t len)
|
|||
|
||||
bool gprs_rlcmac_dl_tbf::dl_window_stalled() const
|
||||
{
|
||||
return dir.dl.window.window_stalled();
|
||||
return m_window.window_stalled();
|
||||
}
|
||||
|
||||
void gprs_rlcmac_tbf::rotate_in_list()
|
||||
|
|
26
src/tbf.h
26
src/tbf.h
|
@ -319,13 +319,9 @@ struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf {
|
|||
* All states that need reset must be in this struct, so this is why
|
||||
* variables are in both (dl and ul) structs and not outside union.
|
||||
*/
|
||||
union {
|
||||
struct {
|
||||
gprs_rlc_dl_window window;
|
||||
int32_t tx_counter; /* count all transmitted blocks */
|
||||
uint8_t wait_confirm; /* wait for CCCH IMM.ASS cnf */
|
||||
} dl;
|
||||
} dir;
|
||||
gprs_rlc_dl_window m_window;
|
||||
int32_t m_tx_counter; /* count all transmitted blocks */
|
||||
uint8_t m_wait_confirm; /* wait for CCCH IMM.ASS cnf */
|
||||
|
||||
protected:
|
||||
struct msgb *create_new_bsn(const uint32_t fn, const uint8_t ts);
|
||||
|
@ -348,16 +344,12 @@ struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {
|
|||
* All states that need reset must be in this struct, so this is why
|
||||
* variables are in both (dl and ul) structs and not outside union.
|
||||
*/
|
||||
union {
|
||||
struct {
|
||||
gprs_rlc_ul_window window;
|
||||
int32_t rx_counter; /* count all received blocks */
|
||||
uint8_t n3103; /* N3103 counter */
|
||||
uint8_t usf[8]; /* list USFs per PDCH (timeslot) */
|
||||
uint8_t contention_resolution_done; /* set after done */
|
||||
uint8_t final_ack_sent; /* set if we sent final ack */
|
||||
} ul;
|
||||
} dir;
|
||||
gprs_rlc_ul_window m_window;
|
||||
int32_t m_rx_counter; /* count all received blocks */
|
||||
uint8_t m_n3103; /* N3103 counter */
|
||||
uint8_t m_usf[8]; /* list USFs per PDCH (timeslot) */
|
||||
uint8_t m_contention_resolution_done; /* set after done */
|
||||
uint8_t m_final_ack_sent; /* set if we sent final ack */
|
||||
|
||||
protected:
|
||||
void maybe_schedule_uplink_acknack(const rlc_ul_header *rh);
|
||||
|
|
|
@ -200,7 +200,7 @@ static void test_alloc_b(int ms_class)
|
|||
ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf, tfi, trx_no, ms_class, 0);
|
||||
ul_tbf->m_tlli = 0x23;
|
||||
ul_tbf->m_tlli_valid = true;
|
||||
ul_tbf->dir.ul.contention_resolution_done = 1;
|
||||
ul_tbf->m_contention_resolution_done = 1;
|
||||
OSMO_ASSERT(ul_tbf);
|
||||
dump_assignment(ul_tbf, "UL");
|
||||
|
||||
|
@ -357,7 +357,7 @@ static void test_alloc_b(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool
|
|||
OSMO_ASSERT(ul_tbf);
|
||||
ul_tbf->m_tlli = 0x23;
|
||||
ul_tbf->m_tlli_valid = true;
|
||||
ul_tbf->dir.ul.contention_resolution_done = 1;
|
||||
ul_tbf->m_contention_resolution_done = 1;
|
||||
|
||||
OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);
|
||||
|
||||
|
|
Loading…
Reference in New Issue