tbf: Split the handling of DL ACK/NACK into two separate parts

Split the handling of the final ack and the handling of frames
that is moving frames.
This commit is contained in:
Holger Hans Peter Freyther 2013-11-24 17:28:49 +01:00
parent bc15570651
commit 86dc355a33
2 changed files with 71 additions and 61 deletions

View File

@ -1361,19 +1361,12 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ack(uint32_t fn)
return msg;
}
int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb)
int gprs_rlcmac_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
{
uint16_t mod_sns = m_sns - 1;
uint16_t mod_sns_half = (m_sns >> 1) - 1;
int i; /* must be signed */
int16_t dist; /* must be signed */
uint16_t bsn;
struct msgb *msg;
uint16_t lost = 0, received = 0;
LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink acknowledge\n", tbf_name(this));
if (!final) {
const uint16_t mod_sns = m_sns - 1;
const uint16_t mod_sns_half = (m_sns >> 1) - 1;
char show_rbb[65];
char show_v_b[RLC_MAX_SNS + 1];
@ -1399,8 +1392,7 @@ int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb)
}
dir.dl.v_b.update(bts, show_rbb, ssn, dir.dl.v_a,
mod_sns, mod_sns_half,
&lost, &received);
mod_sns, mod_sns_half, &lost, &received);
/* report lost and received packets */
gprs_rlcmac_received_lost(this, received, lost);
@ -1417,8 +1409,7 @@ int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb)
"X=Resend-Unacked\n", dir.dl.v_a, show_v_b,
(dir.dl.v_s - 1) & mod_sns);
if (state_is(GPRS_RLCMAC_FINISHED)
&& dir.dl.v_s == dir.dl.v_a) {
if (state_is(GPRS_RLCMAC_FINISHED) && dir.dl.v_s == dir.dl.v_a) {
LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of "
"all blocks, but without final ack "
"inidcation (don't worry)\n");
@ -1426,6 +1417,15 @@ int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb)
return 0;
}
int gprs_rlcmac_tbf::maybe_start_new_window()
{
const uint16_t mod_sns = m_sns - 1;
const uint16_t mod_sns_half = (m_sns >> 1) - 1;
uint16_t bsn;
struct msgb *msg;
uint16_t lost = 0, received = 0;
LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n");
/* range V(A)..V(S)-1 */
for (bsn = dir.dl.v_a; bsn != dir.dl.v_s;
@ -1441,8 +1441,7 @@ int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb)
msg = llc_dequeue(gprs_bssgp_pcu_current_bctx());
if (!msg) {
/* no message, start T3193, change state to RELEASE */
LOGP(DRLCMACDL, LOGL_DEBUG, "- No new message, so we "
"release.\n");
LOGP(DRLCMACDL, LOGL_DEBUG, "- No new message, so we release.\n");
/* start T3193 */
tbf_timer_start(this, 3193,
bts_data()->t3193_msec / 1000,
@ -1458,6 +1457,15 @@ int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb)
return 0;
}
int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final_ack, uint8_t ssn, uint8_t *rbb)
{
LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink acknowledge\n", tbf_name(this));
if (!final_ack)
return update_window(ssn, rbb);
return maybe_start_new_window();
}
void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx)
{
for (uint8_t tfi = 0; tfi < 32; tfi++) {

View File

@ -234,6 +234,8 @@ struct gprs_rlcmac_tbf {
char m_imsi[16];
protected:
int update_window(const uint8_t ssn, const uint8_t *rbb);
int maybe_start_new_window();
void reuse_tbf(const uint8_t *data, const uint16_t len);
gprs_rlcmac_bts *bts_data() const;
bool dl_window_stalled() const;