summaryrefslogtreecommitdiff
path: root/src/tbf_dl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tbf_dl.cpp')
-rw-r--r--src/tbf_dl.cpp344
1 files changed, 154 insertions, 190 deletions
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index 3d27883..dd24963 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -28,18 +28,28 @@
#include <gprs_codel.h>
#include <decoding.h>
#include <encoding.h>
-
+#include <gprs_coding_scheme.h>
+#include <gprs_ms.h>
+#include <gprs_ms_storage.h>
+#include <llc.h>
#include "pcu_utils.h"
extern "C" {
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>
+ #include <osmocom/core/bitvec.h>
+ #include <osmocom/core/linuxlist.h>
+ #include <osmocom/core/logging.h>
+ #include <osmocom/core/rate_ctr.h>
+ #include <osmocom/core/timer.h>
+ #include <osmocom/core/utils.h>
+ #include <osmocom/gsm/gsm_utils.h>
+ #include <osmocom/gsm/protocol/gsm_04_08.h>
}
#include <errno.h>
#include <string.h>
-#include <math.h>
/* After sending these frames, we poll for ack/nack. */
#define POLL_ACK_AFTER_FRAMES 20
@@ -58,8 +68,7 @@ static void llc_timer_cb(void *_tbf)
if (tbf->state_is_not(GPRS_RLCMAC_FLOW))
return;
- LOGP(DRLCMAC, LOGL_DEBUG,
- "%s LLC receive timeout, requesting DL ACK\n", tbf_name(tbf));
+ LOGPTBFDL(tbf, LOGL_DEBUG, "LLC receive timeout, requesting DL ACK\n");
tbf->request_dl_ack();
}
@@ -87,7 +96,7 @@ int gprs_rlcmac_dl_tbf::append_data(const uint8_t ms_class,
const uint16_t pdu_delay_csec,
const uint8_t *data, const uint16_t len)
{
- LOGP(DRLCMAC, LOGL_INFO, "%s append\n", tbf_name(this));
+ LOGPTBFDL(this, LOGL_DEBUG, "appending %u bytes\n", len);
gprs_llc_queue::MetaInfo info;
struct msgb *llc_msg = msgb_alloc(len, "llc_pdu_queue");
if (!llc_msg)
@@ -101,9 +110,7 @@ int gprs_rlcmac_dl_tbf::append_data(const uint8_t ms_class,
start_llc_timer();
if (state_is(GPRS_RLCMAC_WAIT_RELEASE)) {
- LOGP(DRLCMAC, LOGL_DEBUG,
- "%s in WAIT RELEASE state "
- "(T3193), so reuse TBF\n", tbf_name(this));
+ LOGPTBFDL(this, LOGL_DEBUG, "in WAIT RELEASE state (T3193), so reuse TBF\n");
tbf_update_ms_class(this, ms_class);
establish_dl_tbf_on_pacch();
}
@@ -118,7 +125,7 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts,
const uint8_t egprs_ms_class,
struct gprs_rlcmac_dl_tbf **tbf)
{
- uint8_t ss;
+ bool ss;
int8_t use_trx;
uint16_t ta = GSM48_TA_INVALID;
struct gprs_rlcmac_ul_tbf *ul_tbf = NULL, *old_ul_tbf;
@@ -136,11 +143,11 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts,
if (ul_tbf && ul_tbf->m_contention_resolution_done
&& !ul_tbf->m_final_ack_sent) {
use_trx = ul_tbf->trx->trx_no;
- ss = 0;
+ ss = false;
old_ul_tbf = ul_tbf;
} else {
use_trx = -1;
- ss = 1; /* PCH assignment only allows one timeslot */
+ ss = true; /* PCH assignment only allows one timeslot */
old_ul_tbf = NULL;
}
@@ -150,13 +157,13 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts,
dl_tbf = tbf_alloc_dl_tbf(bts, ms, use_trx, ms_class, egprs_ms_class, ss);
if (!dl_tbf) {
- LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
+ LOGP(DTBF, LOGL_NOTICE, "No PDCH resource\n");
return -EBUSY;
}
dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
dl_tbf->ms()->set_ta(ta);
- LOGP(DRLCMAC, LOGL_DEBUG, "%s [DOWNLINK] START\n", tbf_name(dl_tbf));
+ LOGPTBFDL(dl_tbf, LOGL_DEBUG, "[DOWNLINK] START\n");
/* Store IMSI for later look-up and PCH retransmission */
dl_tbf->assign_imsi(imsi);
@@ -200,28 +207,25 @@ int gprs_rlcmac_dl_tbf::handle(struct gprs_rlcmac_bts *bts,
if (ms_old && ms_old != ms) {
/* The TLLI has changed (RAU), so there are two MS
* objects for the same MS */
- LOGP(DRLCMAC, LOGL_NOTICE,
- "There is a new MS object for the same MS: "
- "(0x%08x, '%s') -> (0x%08x, '%s')\n",
- ms_old->tlli(), ms_old->imsi(),
- ms->tlli(), ms->imsi());
+ LOGP(DTBF, LOGL_NOTICE,
+ "There is a new MS object for the same MS: (0x%08x, '%s') -> (0x%08x, '%s')\n",
+ ms_old->tlli(), ms_old->imsi(), ms->tlli(), ms->imsi());
GprsMs::Guard guard_old(ms_old);
if (!dl_tbf && ms_old->dl_tbf()) {
- LOGP(DRLCMAC, LOGL_NOTICE,
- "%s IMSI %s: "
- "moving DL TBF to new MS object\n",
- ms_old->dl_tbf()->name(), imsi);
+ LOGP(DTBF, LOGL_NOTICE,
+ "IMSI %s, old TBF %s: moving DL TBF to new MS object\n",
+ imsi, ms_old->dl_tbf()->name());
dl_tbf = ms_old->dl_tbf();
/* Move the DL TBF to the new MS */
dl_tbf->set_ms(ms);
}
/* Clean up the old MS object */
/* TODO: Put this into a separate function, use timer? */
- if (ms_old->ul_tbf() && ms_old->ul_tbf()->T == 0)
+ if (ms_old->ul_tbf() && !ms_old->ul_tbf()->timers_pending(T_MAX))
tbf_free(ms_old->ul_tbf());
- if (ms_old->dl_tbf() && ms_old->dl_tbf()->T == 0)
+ if (ms_old->dl_tbf() && !ms_old->dl_tbf()->timers_pending(T_MAX))
tbf_free(ms_old->dl_tbf());
ms->merge_old_ms(ms_old);
@@ -305,10 +309,10 @@ drop_frame:
}
if (frames) {
- LOGP(DRLCMACDL, LOGL_NOTICE, "%s Discarding LLC PDU "
+ LOGPTBFDL(this, LOGL_NOTICE, "Discarding LLC PDU "
"because lifetime limit reached, "
"count=%u new_queue_size=%zu\n",
- tbf_name(this), frames, llc_queue_size());
+ frames, llc_queue_size());
if (frames > 0xff)
frames = 0xff;
if (octets > 0xffffff)
@@ -329,7 +333,7 @@ bool gprs_rlcmac_dl_tbf::restart_bsn_cycle()
* should never happen if MS works correctly.
*/
if (m_window.window_empty()) {
- LOGP(DRLCMACDL, LOGL_DEBUG, "- MS acked all blocks\n");
+ LOGPTBFDL(this, LOGL_DEBUG, "MS acked all blocks\n");
return false;
}
@@ -339,9 +343,8 @@ bool gprs_rlcmac_dl_tbf::restart_bsn_cycle()
/* At this point there should be at least one unacked block
* to be resent. If not, this is an software error. */
if (resend == 0) {
- LOGP(DRLCMACDL, LOGL_ERROR, "Software error: "
- "There are no unacknowledged blocks, but V(A) "
- " != V(S). PLEASE FIX!\n");
+ LOGPTBFDL(this, LOGL_ERROR,
+ "FIXME: Software error: There are no unacknowledged blocks, but V(A) != V(S). PLEASE FIX!\n");
return false;
}
@@ -380,15 +383,13 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
ms()->current_cs_dl(),
bts->bts_data()->dl_arq_type);
- LOGP(DRLCMACDL, LOGL_DEBUG,
- "- initial_cs_dl(%d) last_mcs(%d)"
- " demanded_mcs(%d) cs_trans(%d)"
- " arq_type(%d) bsn(%d)\n",
- m_rlc.block(bsn)->cs_init.to_num(),
- m_rlc.block(bsn)->cs_last.to_num(),
- ms()->current_cs_dl().to_num(),
- m_rlc.block(bsn)->cs_current_trans.to_num(),
- bts->bts_data()->dl_arq_type, bsn);
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "initial_cs_dl(%d) last_mcs(%d) demanded_mcs(%d) cs_trans(%d) arq_type(%d) bsn(%d)\n",
+ m_rlc.block(bsn)->cs_init.to_num(),
+ m_rlc.block(bsn)->cs_last.to_num(),
+ ms()->current_cs_dl().to_num(),
+ m_rlc.block(bsn)->cs_current_trans.to_num(),
+ bts->bts_data()->dl_arq_type, bsn);
/* TODO: Need to remove this check when MCS-8 -> MCS-6
* transistion is handled.
@@ -404,21 +405,21 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
data_len2 = m_rlc.block(bsn)->len;
if (force_data_len > 0 && force_data_len != data_len2)
return -1;
- LOGP(DRLCMACDL, LOGL_DEBUG, "- Resending BSN %d\n", bsn);
+ LOGPTBFDL(this, LOGL_DEBUG, "Resending BSN %d\n", bsn);
/* re-send block with negative aknowlegement */
m_window.m_v_b.mark_unacked(bsn);
bts->rlc_resent();
} else if (state_is(GPRS_RLCMAC_FINISHED)) {
- LOGP(DRLCMACDL, LOGL_DEBUG, "- Restarting at BSN %d, "
- "because all blocks have been transmitted.\n",
- m_window.v_a());
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "Restarting at BSN %d, because all blocks have been transmitted.\n",
+ m_window.v_a());
bts->rlc_restarted();
if (restart_bsn_cycle())
return take_next_bsn(fn, previous_bsn, may_combine);
} else if (dl_window_stalled()) {
- LOGP(DRLCMACDL, LOGL_NOTICE, "- Restarting at BSN %d, "
- "because the window is stalled.\n",
- m_window.v_a());
+ LOGPTBFDL(this, LOGL_NOTICE,
+ "Restarting at BSN %d, because the window is stalled.\n",
+ m_window.v_a());
bts->rlc_stalled();
if (restart_bsn_cycle())
return take_next_bsn(fn, previous_bsn, may_combine);
@@ -426,31 +427,31 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
GprsCodingScheme new_cs;
/* New blocks may be send */
new_cs = force_cs ? force_cs : current_cs();
- LOGP(DRLCMACDL, LOGL_DEBUG,
- "- Sending new block at BSN %d, CS=%s\n",
- m_window.v_s(), new_cs.name());
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "Sending new block at BSN %d, CS=%s\n",
+ m_window.v_s(), new_cs.name());
bsn = create_new_bsn(fn, new_cs);
} else if (!m_window.window_empty()) {
- LOGP(DRLCMACDL, LOGL_DEBUG, "- Restarting at BSN %d, "
- "because all blocks have been transmitted (FLOW).\n",
- m_window.v_a());
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "Restarting at BSN %d, because all blocks have been transmitted (FLOW).\n",
+ m_window.v_a());
bts->rlc_restarted();
if (restart_bsn_cycle())
return take_next_bsn(fn, previous_bsn, may_combine);
} else {
/* Nothing left to send, create dummy LLC commands */
- LOGP(DRLCMACDL, LOGL_DEBUG,
- "- Sending new dummy block at BSN %d, CS=%s\n",
- m_window.v_s(), current_cs().name());
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "Sending new dummy block at BSN %d, CS=%s\n",
+ m_window.v_s(), current_cs().name());
bsn = create_new_bsn(fn, current_cs());
/* Don't send a second block, so don't set cs_current_trans */
}
if (bsn < 0) {
/* we just send final block again */
- LOGP(DRLCMACDL, LOGL_DEBUG,
- "- Nothing else to send, Re-transmit final block!\n");
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "Nothing else to send, Re-transmit final block!\n");
bsn = m_window.v_s_mod(-1);
bts->rlc_final_block_resent();
bts->rlc_resent();
@@ -470,9 +471,8 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(uint32_t fn, uint8_t ts)
int bsn, bsn2 = -1;
bool may_combine;
- LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink (V(A)==%d .. "
- "V(S)==%d)\n", tbf_name(this),
- m_window.v_a(), m_window.v_s());
+ LOGPTBFDL(this, LOGL_DEBUG, "downlink (V(A)==%d .. V(S)==%d)\n",
+ m_window.v_a(), m_window.v_s());
bsn = take_next_bsn(fn, -1, &may_combine);
if (bsn < 0)
@@ -488,29 +488,26 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(uint32_t fn, uint8_t ts)
void gprs_rlcmac_dl_tbf::trigger_ass(struct gprs_rlcmac_tbf *old_tbf)
{
/* stop pending timer */
- stop_timer();
+ stop_timers("assignment (DL-TBF)");
/* check for downlink tbf: */
if (old_tbf) {
- LOGP(DRLCMACDL, LOGL_DEBUG, "Send dowlink assignment on PACCH, because %s exists\n", tbf_name(old_tbf));
- old_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
+ LOGPTBFDL(this, LOGL_DEBUG, "Send dowlink assignment on PACCH, because %s exists\n", old_tbf->name());
+ TBF_SET_ASS_STATE_DL(old_tbf, GPRS_RLCMAC_DL_ASS_SEND_ASS);
old_tbf->was_releasing = old_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE);
/* change state */
- set_state(GPRS_RLCMAC_ASSIGN);
- if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)))
- state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH);
+ TBF_SET_ASS_ON(this, GPRS_RLCMAC_FLAG_PACCH, true);
/* start timer */
- tbf_timer_start(this, 0, Tassign_pacch);
+ T_START(this, T0, T_ASS_PACCH_SEC, 0, "assignment (PACCH)", true);
} else {
- LOGP(DRLCMACDL, LOGL_DEBUG, "Send dowlink assignment for %s on PCH, no TBF exist (IMSI=%s)\n",
- tbf_name(this), imsi());
+ LOGPTBFDL(this, LOGL_DEBUG, "Send dowlink assignment on PCH, no TBF exist (IMSI=%s)\n",
+ imsi());
was_releasing = state_is(GPRS_RLCMAC_WAIT_RELEASE);
/* change state */
- set_state(GPRS_RLCMAC_ASSIGN);
- state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH);
+ TBF_SET_ASS_ON(this, GPRS_RLCMAC_FLAG_CCCH, false);
/* send immediate assignment */
bts->snd_dl_ass(this, 0, imsi());
@@ -530,9 +527,7 @@ void gprs_rlcmac_dl_tbf::schedule_next_frame()
if (!msg)
return;
- LOGP(DRLCMACDL, LOGL_INFO,
- "- Dequeue next LLC for %s (len=%d)\n",
- tbf_name(this), msg->len);
+ LOGPTBFDL(this, LOGL_DEBUG, "Dequeue next LLC (len=%d)\n", msg->len);
m_llc.put_frame(msg->data, msg->len);
bts->llc_frame_sched();
@@ -598,11 +593,9 @@ int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, GprsCodingScheme cs)
* arrive, so request a DL ack/nack now */
request_dl_ack();
- LOGP(DRLCMACDL, LOGL_DEBUG,
- "-- Empty chunk, "
- "added LLC dummy command of size %d, "
- "drained_since=%d\n",
- m_llc.frame_length(), frames_since_last_drain(fn));
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "Empty chunk, added LLC dummy command of size %d, drained_since=%d\n",
+ m_llc.frame_length(), frames_since_last_drain(fn));
}
is_final = llc_queue_size() == 0 && !keep_open(fn);
@@ -616,24 +609,23 @@ int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, GprsCodingScheme cs)
if (ar == Encoding::AR_NEED_MORE_BLOCKS)
break;
- LOGP(DRLCMACDL, LOGL_INFO, "Complete DL frame for %s"
- "len=%d\n", tbf_name(this), m_llc.frame_length());
+ LOGPTBFDL(this, LOGL_DEBUG, "Complete DL frame, len=%d\n", m_llc.frame_length());
gprs_rlcmac_dl_bw(this, m_llc.frame_length());
bts->llc_dl_bytes(m_llc.frame_length());
m_llc.reset();
if (is_final) {
request_dl_ack();
- set_state(GPRS_RLCMAC_FINISHED);
+ TBF_SET_STATE(this, GPRS_RLCMAC_FINISHED);
}
/* dequeue next LLC frame, if any */
schedule_next_frame();
} while (ar == Encoding::AR_COMPLETED_SPACE_LEFT);
- LOGP(DRLCMACDL, LOGL_DEBUG, "data block (BSN %d, %s): %s\n",
- bsn, rlc_data->cs_last.name(),
- osmo_hexdump(rlc_data->block, block_data_len));
+ LOGPTBFDL(this, LOGL_DEBUG, "data block (BSN %d, %s): %s\n",
+ bsn, rlc_data->cs_last.name(),
+ osmo_hexdump(rlc_data->block, block_data_len));
/* raise send state and set ack state array */
m_window.m_v_b.mark_unacked(bsn);
m_window.increment_send();
@@ -641,25 +633,19 @@ int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, GprsCodingScheme cs)
return bsn;
}
-void gprs_rlcmac_dl_tbf::clear_poll_timeout_flag()
-{
- state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
-}
-
bool gprs_rlcmac_dl_tbf::handle_ack_nack()
{
bool ack_recovered = false;
state_flags |= (1 << GPRS_RLCMAC_FLAG_DL_ACK);
- if ((state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {
- clear_poll_timeout_flag();
+ if (check_n_clear(GPRS_RLCMAC_FLAG_TO_DL_ACK)) {
ack_recovered = true;
}
/* reset N3105 */
- n3105 = 0;
- stop_t3191();
- poll_state = GPRS_RLCMAC_POLL_NONE;
+ n_reset(N3105);
+ t_stop(T3191, "ACK/NACK received");
+ TBF_POLL_SCHED_UNSET(this);
return ack_recovered;
}
@@ -673,7 +659,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
unsigned msg_len;
bool need_poll;
/* TODO: support MCS-7 - MCS-9, where data_block_idx can be 1 */
- unsigned int data_block_idx = 0;
+ uint8_t data_block_idx = 0;
unsigned int rrbp;
uint32_t new_poll_fn;
int rc;
@@ -735,10 +721,8 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
spb = get_egprs_dl_spb(index);
- LOGP(DRLCMACDL, LOGL_DEBUG, "- need_padding %d spb_status %d spb %d"
- "(BSN1 %d BSN2 %d)\n",
- need_padding,
- spb_status, spb, index, index2);
+ LOGPTBFDL(this, LOGL_DEBUG, "need_padding %d spb_status %d spb %d (BSN1 %d BSN2 %d)\n",
+ need_padding, spb_status, spb, index, index2);
gprs_rlc_data_info_init_dl(&rlc, cs, need_padding, spb);
@@ -757,10 +741,10 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
OSMO_ASSERT(rlc.num_data_blocks <= ARRAY_SIZE(rlc.block_info));
OSMO_ASSERT(rlc.num_data_blocks > 0);
- LOGP(DRLCMACDL, LOGL_DEBUG, "- Copying %u RLC blocks, %u BSNs\n", rlc.num_data_blocks, num_bsns);
+ LOGPTBFDL(this, LOGL_DEBUG, "Copying %u RLC blocks, %u BSNs\n", rlc.num_data_blocks, num_bsns);
- /* Copy block(s) to RLC message */
- for (data_block_idx = 0; data_block_idx < rlc.num_data_blocks;
+ /* Copy block(s) to RLC message: the num_data_blocks cannot be more than 2 - see assert above */
+ for (data_block_idx = 0; data_block_idx < OSMO_MIN(rlc.num_data_blocks, 2);
data_block_idx++)
{
int bsn;
@@ -784,7 +768,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
OSMO_ASSERT(m_rlc.block(bsn)->next_ps >= EGPRS_PS_1);
OSMO_ASSERT(m_rlc.block(bsn)->next_ps <= EGPRS_PS_3);
}
- OSMO_ASSERT(data_block_idx < 2); /* punct defined above as 2-element array */
+
punct[data_block_idx] = m_rlc.block(bsn)->next_ps;
rdbi = &rlc.block_info[data_block_idx];
@@ -819,8 +803,8 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
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);
+ LOGPTBFDL(this, 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);
@@ -842,15 +826,15 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
if (m_tx_counter >= POLL_ACK_AFTER_FRAMES || m_dl_ack_requested ||
need_poll) {
if (m_dl_ack_requested) {
- LOGP(DRLCMACDL, LOGL_DEBUG, "- Scheduling Ack/Nack "
- "polling, because is was requested explicitly "
- "(e.g. first final block sent).\n");
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "Scheduling Ack/Nack polling, because is was requested explicitly "
+ "(e.g. first final block sent).\n");
} else if (need_poll) {
- LOGP(DRLCMACDL, LOGL_DEBUG, "- Scheduling Ack/Nack "
- "polling, because polling timed out.\n");
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "Scheduling Ack/Nack polling, because polling timed out.\n");
} else {
- LOGP(DRLCMACDL, LOGL_DEBUG, "- Scheduling Ack/Nack "
- "polling, because %d blocks sent.\n",
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "Scheduling Ack/Nack polling, because %d blocks sent.\n",
POLL_ACK_AFTER_FRAMES);
}
@@ -861,9 +845,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
m_tx_counter = 0;
/* start timer whenever we send the final block */
if (is_final)
- tbf_timer_start(this, 3191, bts_data()->t3191, 0);
+ T_START(this, T3191, bts_data()->t3191, 0, "final block (DL-TBF)", true);
- clear_poll_timeout_flag();
+ state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); /* clear poll timeout flag */
/* Clear request flag */
m_dl_ack_requested = false;
@@ -874,18 +858,18 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
m_last_dl_poll_fn = poll_fn;
- LOGP(DRLCMACDL, LOGL_INFO,
- "%s Scheduled Ack/Nack polling on FN=%d, TS=%d\n",
- name(), poll_fn, poll_ts);
+ LOGPTBFDL(this, LOGL_INFO,
+ "Scheduled Ack/Nack polling on FN=%d, TS=%d\n",
+ poll_fn, poll_ts);
}
}
Encoding::rlc_write_dl_data_header(&rlc, msg_data);
- LOGP(DRLCMACDL, LOGL_DEBUG, "msg block (BSN %d, %s%s): %s\n",
- index, cs.name(),
- need_padding ? ", padded" : "",
- msgb_hexdump(dl_msg));
+ LOGPTBFDL(this, LOGL_DEBUG, "msg block (BSN %d, %s%s): %s\n",
+ index, cs.name(),
+ need_padding ? ", padded" : "",
+ msgb_hexdump(dl_msg));
/* Increment TX-counter */
m_tx_counter++;
@@ -969,10 +953,9 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn,
}
}
- LOGP(DRLCMACDL, LOGL_DEBUG, "%s DL analysis, range=%d:%d, lost=%d, recv=%d, "
- "skipped=%d, bsn=%d, info='%s'\n",
- name(), m_window.v_a(), m_window.v_s(), lost, received,
- skipped, bsn, info);
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "DL analysis, range=%d:%d, lost=%d, recv=%d, skipped=%d, bsn=%d, info='%s'\n",
+ m_window.v_a(), m_window.v_s(), lost, received, skipped, bsn, info);
res->received_packets = received_packets;
res->lost_packets = lost_packets;
@@ -985,6 +968,11 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn,
return lost * 100 / (lost + received);
}
+gprs_rlc_dl_window *gprs_rlcmac_dl_tbf::window()
+{
+ return &m_window;
+}
+
int gprs_rlcmac_dl_tbf::update_window(unsigned first_bsn,
const struct bitvec *rbb)
{
@@ -1001,9 +989,9 @@ int gprs_rlcmac_dl_tbf::update_window(unsigned first_bsn,
Decoding::extract_rbb(rbb, show_rbb);
/* show received array in debug */
- LOGP(DRLCMACDL, LOGL_DEBUG, "- ack: (BSN=%d)\"%s\""
- "(BSN=%d) R=ACK I=NACK\n", first_bsn,
- show_rbb, m_window.mod_sns(behind_last_bsn - 1));
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "ack: (BSN=%d)\"%s\"(BSN=%d) R=ACK I=NACK\n",
+ first_bsn, show_rbb, m_window.mod_sns(behind_last_bsn - 1));
error_rate = analyse_errors(show_rbb, behind_last_bsn, &ana_res);
@@ -1025,11 +1013,9 @@ int gprs_rlcmac_dl_tbf::update_window(unsigned first_bsn,
/* show receive state array in debug (V(A)..V(S)-1) */
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",
- m_window.v_a(), show_v_b,
- m_window.v_s_mod(-1));
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "V(B): (V(A)=%d)\"%s\"(V(S)-1=%d) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid\n",
+ m_window.v_a(), show_v_b, m_window.v_s_mod(-1));
return 0;
}
@@ -1044,9 +1030,9 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
Decoding::extract_rbb(rbb, show_rbb);
/* show received array in debug (bit 64..1) */
- LOGP(DRLCMACDL, LOGL_DEBUG, "- ack: (BSN=%d)\"%s\""
- "(BSN=%d) R=ACK I=NACK\n", m_window.mod_sns(ssn - 64),
- show_rbb, m_window.mod_sns(ssn - 1));
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "ack: (BSN=%d)\"%s\"(BSN=%d) R=ACK I=NACK\n",
+ m_window.mod_sns(ssn - 64), show_rbb, m_window.mod_sns(ssn - 1));
/* apply received array to receive state (SSN-64..SSN-1) */
/* calculate distance of ssn from V(S) */
@@ -1058,8 +1044,7 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
* to previous TBF
* FIXME: we should implement polling for
* control ack!*/
- LOGP(DRLCMACDL, LOGL_NOTICE, "- ack range is out of "
- "V(A)..V(S) range %s Free TBF!\n", tbf_name(this));
+ LOGPTBFDL(this, LOGL_NOTICE, "ack range is out of V(A)..V(S) range - Free TBF!\n");
return 1; /* indicate to free TBF */
}
@@ -1084,16 +1069,13 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
/* show receive state array in debug (V(A)..V(S)-1) */
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",
- m_window.v_a(), show_v_b,
- m_window.v_s_mod(-1));
+ LOGPTBFDL(this, LOGL_DEBUG,
+ "V(B): (V(A)=%d)\"%s\"(V(S)-1=%d) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid\n",
+ m_window.v_a(), show_v_b, m_window.v_s_mod(-1));
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");
+ LOGPTBFDL(this, LOGL_NOTICE,
+ "Received acknowledge of all blocks, but without final ack inidcation (don't worry)\n");
}
return 0;
}
@@ -1121,21 +1103,18 @@ int gprs_rlcmac_dl_tbf::release()
/* report all outstanding packets as received */
gprs_rlcmac_received_lost(this, received, 0);
- set_state(GPRS_RLCMAC_WAIT_RELEASE);
+ TBF_SET_STATE(this, GPRS_RLCMAC_WAIT_RELEASE);
/* start T3193 */
- tbf_timer_start(this, 3193,
- bts_data()->t3193_msec / 1000,
- (bts_data()->t3193_msec % 1000) * 1000);
+ T_START(this, T3193, bts_data()->t3193_msec / 1000, (bts_data()->t3193_msec % 1000) * 1000,
+ "release (DL-TBF)", true);
/* reset rlc states */
m_tx_counter = 0;
m_wait_confirm = 0;
m_window.reset();
- /* keep to flags */
- state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;
- state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH);
+ TBF_ASS_TYPE_UNSET(this, GPRS_RLCMAC_FLAG_CCCH);
return 0;
}
@@ -1156,46 +1135,43 @@ int gprs_rlcmac_dl_tbf::abort()
* (partly) encoded in chunk 1 of block V(A). (optional) */
}
- set_state(GPRS_RLCMAC_RELEASING);
+ TBF_SET_STATE(this, GPRS_RLCMAC_RELEASING);
/* reset rlc states */
m_window.reset();
- /* keep to flags */
- state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;
- state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH);
+ TBF_ASS_TYPE_UNSET(this, GPRS_RLCMAC_FLAG_CCCH);
return 0;
}
-int gprs_rlcmac_dl_tbf::rcvd_dl_ack(uint8_t final_ack, unsigned first_bsn,
+int gprs_rlcmac_dl_tbf::rcvd_dl_ack(bool final_ack, unsigned first_bsn,
struct bitvec *rbb)
{
int rc;
- LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink acknowledge\n", tbf_name(this));
+ LOGPTBFDL(this, LOGL_DEBUG, "downlink acknowledge\n");
rc = update_window(first_bsn, rbb);
if (final_ack) {
- LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n");
+ LOGPTBFDL(this, LOGL_DEBUG, "Final ACK received.\n");
rc = maybe_start_new_window();
} else if (state_is(GPRS_RLCMAC_FINISHED) && m_window.window_empty()) {
- LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of "
- "all blocks, but without final ack "
- "indication (don't worry)\n");
+ LOGPTBFDL(this, LOGL_NOTICE,
+ "Received acknowledge of all blocks, but without final ack indication (don't worry)\n");
}
return rc;
}
-int gprs_rlcmac_dl_tbf::rcvd_dl_ack(uint8_t final_ack, uint8_t ssn, uint8_t *rbb)
+int gprs_rlcmac_dl_tbf::rcvd_dl_ack(bool final_ack, uint8_t ssn, uint8_t *rbb)
{
- LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink acknowledge\n", tbf_name(this));
+ LOGPTBFDL(this, LOGL_DEBUG, "downlink acknowledge\n");
if (!final_ack)
return update_window(ssn, rbb);
- LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n");
+ LOGPTBFDL(this, LOGL_DEBUG, "Final ACK received.\n");
return maybe_start_new_window();
}
@@ -1211,7 +1187,7 @@ void gprs_rlcmac_dl_tbf::request_dl_ack()
bool gprs_rlcmac_dl_tbf::need_control_ts() const
{
- if (poll_state != GPRS_RLCMAC_POLL_NONE)
+ if (poll_scheduled())
return false;
return state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK) ||
@@ -1252,7 +1228,7 @@ bool gprs_rlcmac_dl_tbf::keep_open(unsigned fn) const
{
int keep_time_frames;
- if (bts_data()->dl_tbf_idle_msec <= 0)
+ if (bts_data()->dl_tbf_idle_msec == 0)
return false;
keep_time_frames = msecs_to_frames(bts_data()->dl_tbf_idle_msec);
@@ -1301,11 +1277,11 @@ enum egprs_rlc_dl_reseg_bsn_state
*block_data = &rlc_data->block[22];
break;
default:
- LOGP(DRLCMACDL, LOGL_ERROR, "Software error: "
- "--%s hit invalid condition. headerType(%d) "
- " blockstatus(%d) cs(%s) PLEASE FIX!\n", name(),
- cs_current_trans.headerTypeData(),
- *block_status_dl, cs_init.name());
+ LOGPTBFDL(this, LOGL_ERROR,
+ "FIXME: Software error: hit invalid condition. "
+ "headerType(%d) blockstatus(%d) cs(%s) PLEASE FIX!\n",
+ cs_current_trans.headerTypeData(),
+ *block_status_dl, cs_init.name());
break;
}
@@ -1379,23 +1355,11 @@ enum egprs_rlcmac_dl_spb gprs_rlcmac_dl_tbf::get_egprs_dl_spb(const int bsn)
return EGPRS_RLCMAC_DL_NO_RETX;
}
-void gprs_rlcmac_dl_tbf::egprs_calc_window_size()
+void gprs_rlcmac_dl_tbf::set_window_size()
{
- struct gprs_rlcmac_bts *bts_data = bts->bts_data();
- unsigned int num_pdch = pcu_bitcount(dl_slots());
- unsigned int ws = bts_data->ws_base + num_pdch * bts_data->ws_pdch;
-
- ws = (ws / 32) * 32;
- ws = OSMO_MAX(64, ws);
-
- if (num_pdch == 1)
- ws = OSMO_MIN(192, ws);
- else
- ws = OSMO_MIN(128 * num_pdch, ws);
-
- LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n",
- name(), ws);
-
+ uint16_t ws = egprs_window_size(bts->bts_data(), dl_slots());
+ LOGPTBFDL(this, LOGL_INFO, "setting EGPRS DL window size to %u, base(%u) slots(%u) ws_pdch(%u)\n",
+ ws, bts->bts_data()->ws_base, pcu_bitcount(dl_slots()), bts->bts_data()->ws_pdch);
m_window.set_ws(ws);
}