TBF: unify timer handling
Use generic timer handling infrastracture to handle assignment/reject internal timer. Rename timer array accordingly. Use defines with explicit second/microsecond values to make it more readable. Change-Id: I63fb7e6f0695383a83472c836a381a055f64690b
This commit is contained in:
parent
effdec6e13
commit
b2de1f7888
|
@ -554,7 +554,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->m_wait_confirm)
|
||||
tbf_timer_start(dl_tbf, 0, Tassign_agch, "assignment (AGCH)");
|
||||
dl_tbf->t_start(T0, 0, T_ASS_AGCH_USEC, "assignment (AGCH)", true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1041,7 +1041,7 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet,
|
|||
}
|
||||
new_tbf->set_state(GPRS_RLCMAC_FLOW);
|
||||
/* stop pending assignment timer */
|
||||
new_tbf->stop_timer("control acked (DL-TBF)");
|
||||
new_tbf->t_stop(T0, "control acked (DL-TBF)");
|
||||
if ((new_tbf->state_flags &
|
||||
(1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) {
|
||||
new_tbf->state_flags &=
|
||||
|
|
75
src/tbf.cpp
75
src/tbf.cpp
|
@ -60,6 +60,7 @@ const struct value_string gprs_rlcmac_tbf_ul_ass_state_names[] = {
|
|||
};
|
||||
|
||||
static const struct value_string tbf_timers_names[] = {
|
||||
OSMO_VALUE_STRING(T0),
|
||||
OSMO_VALUE_STRING(T3169),
|
||||
OSMO_VALUE_STRING(T3191),
|
||||
OSMO_VALUE_STRING(T3193),
|
||||
|
@ -170,7 +171,6 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir) :
|
|||
poll_fn(0),
|
||||
poll_ts(0),
|
||||
n3105(0),
|
||||
T(0),
|
||||
fT(0),
|
||||
num_fT_exp(0),
|
||||
state(GPRS_RLCMAC_NULL),
|
||||
|
@ -191,8 +191,7 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir) :
|
|||
/* The classes of these members do not have proper constructors yet.
|
||||
* Just set them to 0 like talloc_zero did */
|
||||
memset(&pdch, 0, sizeof(pdch));
|
||||
memset(&timer, 0, sizeof(timer));
|
||||
memset(&T31, 0, sizeof(T31));
|
||||
memset(&T, 0, sizeof(T));
|
||||
memset(&m_rlc, 0, sizeof(m_rlc));
|
||||
memset(&gsm_timer, 0, sizeof(gsm_timer));
|
||||
|
||||
|
@ -472,7 +471,7 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf)
|
|||
"be sure not to free in this state. PLEASE FIX!\n",
|
||||
get_value_string(gprs_rlcmac_tbf_dl_ass_state_names,
|
||||
tbf->dl_ass_state));
|
||||
tbf->stop_timer("freeing TBF");
|
||||
|
||||
tbf->stop_timers("freeing TBF");
|
||||
/* TODO: Could/Should generate bssgp_tx_llc_discarded */
|
||||
tbf_unlink_pdch(tbf);
|
||||
|
@ -538,27 +537,6 @@ const char *gprs_rlcmac_tbf::tbf_state_name[] = {
|
|||
"RELEASING",
|
||||
};
|
||||
|
||||
void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T,
|
||||
unsigned int seconds, unsigned int microseconds, const char *reason)
|
||||
{
|
||||
LOGPC(DRLCMAC, (T != tbf->T) ? LOGL_ERROR : LOGL_DEBUG,
|
||||
"%s %sstarting timer T%u [%s] with %u sec. %u microsec.",
|
||||
tbf_name(tbf), osmo_timer_pending(&tbf->timer) ? "re" : "", T, reason, seconds, microseconds);
|
||||
|
||||
if (T != tbf->T && osmo_timer_pending(&tbf->timer))
|
||||
LOGPC(DRLCMAC, LOGL_ERROR, " while old timer T%u pending", tbf->T);
|
||||
|
||||
LOGPC(DRLCMAC, (T != tbf->T) ? LOGL_ERROR : LOGL_DEBUG, "\n");
|
||||
|
||||
tbf->T = T;
|
||||
|
||||
/* Tunning timers can be safely re-scheduled. */
|
||||
tbf->timer.data = tbf;
|
||||
tbf->timer.cb = &tbf_timer_cb;
|
||||
|
||||
osmo_timer_schedule(&tbf->timer, seconds, microseconds);
|
||||
}
|
||||
|
||||
void gprs_rlcmac_tbf::t_stop(enum tbf_timers t, const char *reason)
|
||||
{
|
||||
if (t >= T_MAX) {
|
||||
|
@ -579,10 +557,11 @@ bool gprs_rlcmac_tbf::timers_pending(enum tbf_timers t)
|
|||
uint8_t i;
|
||||
|
||||
if (t != T_MAX)
|
||||
return osmo_timer_pending(&T31[t]);
|
||||
return osmo_timer_pending(&T[t]);
|
||||
|
||||
/* we don't start with T0 because it's internal timer which requires special handling */
|
||||
for (i = T3169; i < T_MAX; i++)
|
||||
if (osmo_timer_pending(&T31[i]))
|
||||
if (osmo_timer_pending(&T[i]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -591,19 +570,11 @@ bool gprs_rlcmac_tbf::timers_pending(enum tbf_timers t)
|
|||
void gprs_rlcmac_tbf::stop_timers(const char *reason)
|
||||
{
|
||||
uint8_t i;
|
||||
for (i = 0; i < T_MAX; i++)
|
||||
/* we start with T0 because timer reset does not require any special handling */
|
||||
for (i = T0; i < T_MAX; i++)
|
||||
t_stop((enum tbf_timers)i, reason);
|
||||
}
|
||||
|
||||
void gprs_rlcmac_tbf::stop_timer(const char *reason)
|
||||
{
|
||||
if (osmo_timer_pending(&timer)) {
|
||||
LOGPTBF(this, LOGL_DEBUG, "stopping timer T%u [%s]\n",
|
||||
T, reason);
|
||||
osmo_timer_del(&timer);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void tbf_timeout_free(struct gprs_rlcmac_tbf *tbf, enum tbf_timers t, bool run_diag)
|
||||
{
|
||||
LOGPTBF(tbf, LOGL_NOTICE, "%s timeout expired, freeing TBF\n",
|
||||
|
@ -629,33 +600,36 @@ void gprs_rlcmac_tbf::t_start(enum tbf_timers t, uint32_t sec, uint32_t microsec
|
|||
get_value_string(tbf_timers_names, t), reason);
|
||||
}
|
||||
|
||||
if (!force && osmo_timer_pending(&T31[t]))
|
||||
if (!force && osmo_timer_pending(&T[t]))
|
||||
return;
|
||||
|
||||
LOGPTBF(this, LOGL_DEBUG, "%sstarting timer %s [%s] with %u sec. %u microsec.\n",
|
||||
osmo_timer_pending(&T31[t]) ? "re" : "", get_value_string(tbf_timers_names, t), reason, sec, microsec);
|
||||
osmo_timer_pending(&T[t]) ? "re" : "", get_value_string(tbf_timers_names, t), reason, sec, microsec);
|
||||
|
||||
T31[t].data = this;
|
||||
T[t].data = this;
|
||||
|
||||
switch(t) {
|
||||
case T0:
|
||||
T[t].cb = tbf_timer_cb;
|
||||
break;
|
||||
case T3169:
|
||||
T31[t].cb = cb_T3169;
|
||||
T[t].cb = cb_T3169;
|
||||
break;
|
||||
case T3191:
|
||||
T31[t].cb = cb_T3191;
|
||||
T[t].cb = cb_T3191;
|
||||
break;
|
||||
case T3193:
|
||||
T31[t].cb = cb_T3193;
|
||||
T[t].cb = cb_T3193;
|
||||
break;
|
||||
case T3195:
|
||||
T31[t].cb = cb_T3195;
|
||||
T[t].cb = cb_T3195;
|
||||
break;
|
||||
default:
|
||||
LOGPTBF(this, LOGL_ERROR, "attempting to set callback for unknown timer %s [%s]\n",
|
||||
get_value_string(tbf_timers_names, t), reason);
|
||||
}
|
||||
|
||||
osmo_timer_schedule(&T31[t], sec, microsec);
|
||||
osmo_timer_schedule(&T[t], sec, microsec);
|
||||
}
|
||||
|
||||
int gprs_rlcmac_tbf::check_polling(uint32_t fn, uint8_t ts,
|
||||
|
@ -1102,12 +1076,7 @@ static void tbf_timer_cb(void *_tbf)
|
|||
|
||||
void gprs_rlcmac_tbf::handle_timeout()
|
||||
{
|
||||
LOGPTBF(this, LOGL_DEBUG, "timer %u expired.\n", T);
|
||||
|
||||
if (T) {
|
||||
LOGPTBF(this, LOGL_ERROR, "%s timer expired in unknown mode: %u\n", T);
|
||||
return;
|
||||
}
|
||||
LOGPTBF(this, LOGL_DEBUG, "timer 0 expired.\n");
|
||||
|
||||
/* assignment */
|
||||
if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) {
|
||||
|
@ -1267,7 +1236,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts)
|
|||
new_dl_tbf->set_state(GPRS_RLCMAC_FLOW);
|
||||
tbf_assign_control_ts(new_dl_tbf);
|
||||
/* stop pending assignment timer */
|
||||
new_dl_tbf->stop_timer("assignment (DL-TBF)");
|
||||
new_dl_tbf->t_stop(T0, "assignment (DL-TBF)");
|
||||
|
||||
}
|
||||
|
||||
|
@ -1297,7 +1266,7 @@ struct msgb *gprs_rlcmac_tbf::create_packet_access_reject()
|
|||
|
||||
/* Start Tmr only if it is UL TBF */
|
||||
if (direction == GPRS_RLCMAC_UL_TBF)
|
||||
tbf_timer_start(this, 0, Treject_pacch, "reject (PACCH)");
|
||||
t_start(T0, 0, T_REJ_PACCH_USEC, "reject (PACCH)", true);
|
||||
|
||||
return msg;
|
||||
|
||||
|
|
18
src/tbf.h
18
src/tbf.h
|
@ -39,9 +39,9 @@ class GprsMs;
|
|||
* TBF instance
|
||||
*/
|
||||
|
||||
#define Tassign_agch 0,200000 /* waiting after IMM.ASS confirm */
|
||||
#define Tassign_pacch 2,0 /* timeout for pacch assigment */
|
||||
#define Treject_pacch 0,2000 /* timeout for tbf reject for PRR*/
|
||||
#define T_ASS_AGCH_USEC 200000 /* waiting after IMM.ASS confirm */
|
||||
#define T_ASS_PACCH_SEC 2 /* timeout for pacch assigment */
|
||||
#define T_REJ_PACCH_USEC 2000 /* timeout for tbf reject for PRR*/
|
||||
|
||||
enum gprs_rlcmac_tbf_state {
|
||||
GPRS_RLCMAC_NULL = 0, /* new created TBF */
|
||||
|
@ -139,6 +139,9 @@ enum tbf_egprs_ul_counters {
|
|||
#define LOGPTBFDL(tbf, level, fmt, args...) LOGP(DRLCMACDL, level, "%s " fmt, tbf_name(tbf), ## args)
|
||||
|
||||
enum tbf_timers {
|
||||
/* internal assign/reject timer */
|
||||
T0,
|
||||
|
||||
/* Wait for reuse of USF and TFI(s) after the MS uplink assignment for this TBF is invalid. */
|
||||
T3169,
|
||||
|
||||
|
@ -194,7 +197,6 @@ struct gprs_rlcmac_tbf {
|
|||
|
||||
int update();
|
||||
void handle_timeout();
|
||||
void stop_timer(const char *reason);
|
||||
void stop_timers(const char *reason);
|
||||
bool timers_pending(enum tbf_timers t);
|
||||
void t_stop(enum tbf_timers t, const char *reason);
|
||||
|
@ -266,9 +268,6 @@ struct gprs_rlcmac_tbf {
|
|||
gprs_rlc m_rlc;
|
||||
|
||||
uint8_t n3105; /* N3105 counter */
|
||||
|
||||
struct osmo_timer_list timer;
|
||||
unsigned int T; /* Txxxx number */
|
||||
|
||||
struct osmo_gsm_timer_list gsm_timer;
|
||||
unsigned int fT; /* fTxxxx number */
|
||||
|
@ -328,7 +327,7 @@ private:
|
|||
LListHead<gprs_rlcmac_tbf> m_list;
|
||||
LListHead<gprs_rlcmac_tbf> m_ms_list;
|
||||
bool m_egprs_enabled;
|
||||
struct osmo_timer_list T31[T_MAX];
|
||||
struct osmo_timer_list T[T_MAX];
|
||||
mutable char m_name_buf[60];
|
||||
};
|
||||
|
||||
|
@ -352,9 +351,6 @@ struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts,
|
|||
|
||||
int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf);
|
||||
|
||||
void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T,
|
||||
unsigned int seconds, unsigned int microseconds, const char *reason);
|
||||
|
||||
inline bool gprs_rlcmac_tbf::state_is(enum gprs_rlcmac_tbf_state rhs) const
|
||||
{
|
||||
return state == rhs;
|
||||
|
|
|
@ -484,7 +484,6 @@ 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("assignment (DL-TBF)");
|
||||
stop_timers("assignment (DL-TBF)");
|
||||
|
||||
/* check for downlink tbf: */
|
||||
|
@ -499,7 +498,7 @@ void gprs_rlcmac_dl_tbf::trigger_ass(struct gprs_rlcmac_tbf *old_tbf)
|
|||
state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH);
|
||||
|
||||
/* start timer */
|
||||
tbf_timer_start(this, 0, Tassign_pacch, "assignment (PACCH)");
|
||||
t_start(T0, T_ASS_PACCH_SEC, 0, "assignment (PACCH)", true);
|
||||
} else {
|
||||
LOGPTBFDL(this, LOGL_DEBUG, "Send dowlink assignment on PCH, no TBF exist (IMSI=%s)\n",
|
||||
imsi());
|
||||
|
|
Loading…
Reference in New Issue