aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2021-07-22 19:20:50 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2021-08-23 17:14:21 +0200
commit33e80071002c3c0bf097a71c2c8e29d445304255 (patch)
treeef6a034fc74ca39cfe3f410bbf4d58da884615ee /src
parent88f34812dfbda0ae46ecc6d729d503604b346761 (diff)
Move NULL and ASSIGN tbf_state transition to tbf_fsm
At some point later in time the state_flags will most probably be split into different variables, one ending up in a different FSM. It is moved so far to the exsiting FSM from the C++ class since it's easier to access it from C and C++ code, and anyway that kind of information belongs to the FSM. Related: OS#2709 Change-Id: I3c62e9e83965cb28065338733f182863e54d7474
Diffstat (limited to 'src')
-rw-r--r--src/pcu_vty_functions.cpp10
-rw-r--r--src/pdch.cpp5
-rw-r--r--src/tbf.cpp39
-rw-r--r--src/tbf.h69
-rw-r--r--src/tbf_dl.cpp16
-rw-r--r--src/tbf_fsm.c108
-rw-r--r--src/tbf_fsm.h5
-rw-r--r--src/tbf_ul.cpp11
8 files changed, 144 insertions, 119 deletions
diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp
index 0b83a68f..657e5a16 100644
--- a/src/pcu_vty_functions.cpp
+++ b/src/pcu_vty_functions.cpp
@@ -55,9 +55,9 @@ static void tbf_print_vty_info(struct vty *vty, struct gprs_rlcmac_tbf *tbf)
tbf->direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL",
tbf->imsi(), VTY_NEWLINE);
vty_out(vty, " created=%lu state=%08x [CCCH:%u, PACCH:%u] 1st_TS=%d 1st_cTS=%d ctrl_TS=%d MS_CLASS=%d/%d%s",
- tbf->created_ts(), tbf->state_flags,
- tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH),
- tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH),
+ tbf->created_ts(), tbf->state_fsm.state_flags,
+ tbf->state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH),
+ tbf->state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH),
tbf->first_ts,
tbf->first_common_ts, tbf->control_ts,
tbf->ms_class(),
@@ -113,7 +113,7 @@ int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts, uint32_t
trx = &bts->trx[trx_no];
llist_for_each_entry(iter, &trx->ul_tbfs, list) {
tbf = (struct gprs_rlcmac_tbf *)iter->entry;
- if (tbf->state_flags & flags)
+ if (tbf->state_fsm.state_flags & flags)
tbf_print_vty_info(vty, tbf);
}
}
@@ -123,7 +123,7 @@ int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts, uint32_t
trx = &bts->trx[trx_no];
llist_for_each_entry(iter, &trx->dl_tbfs, list) {
tbf = (struct gprs_rlcmac_tbf *)iter->entry;
- if (tbf->state_flags & flags)
+ if (tbf->state_fsm.state_flags & flags)
tbf_print_vty_info(vty, tbf);
}
}
diff --git a/src/pdch.cpp b/src/pdch.cpp
index 2ec40ce1..f53e155d 100644
--- a/src/pdch.cpp
+++ b/src/pdch.cpp
@@ -368,12 +368,13 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet,
tbf->direction == new_tbf->direction)
tbf_free(tbf);
- if (new_tbf->check_n_clear(GPRS_RLCMAC_FLAG_CCCH)) {
+ if (new_tbf->state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)) {
/* We now know that the PACCH really existed */
LOGPTBF(new_tbf, LOGL_INFO,
"The TBF has been confirmed on the PACCH, "
"changed type from CCCH to PACCH\n");
- TBF_ASS_TYPE_SET(new_tbf, GPRS_RLCMAC_FLAG_PACCH);
+ osmo_fsm_inst_dispatch(new_tbf->state_fsm.fi, TBF_EV_ASSIGN_DEL_CCCH, NULL);
+ osmo_fsm_inst_dispatch(new_tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_PACCH, NULL);
}
TBF_SET_STATE(new_tbf, TBF_ST_FLOW);
/* stop pending assignment timer */
diff --git a/src/tbf.cpp b/src/tbf.cpp
index fcad879f..8b17059a 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -120,7 +120,6 @@ gprs_rlcmac_tbf::Meas::Meas() :
}
gprs_rlcmac_tbf::gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir) :
- state_flags(0),
direction(dir),
trx(NULL),
first_ts(0),
@@ -152,6 +151,7 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_
memset(&m_trx_list, 0, sizeof(m_trx_list));
m_trx_list.entry = this;
+ memset(&state_fsm, 0, sizeof(state_fsm));
state_fsm.tbf = this;
state_fsm.fi = osmo_fsm_inst_alloc(&tbf_fsm, this, &state_fsm, LOGL_INFO, NULL);
@@ -572,13 +572,14 @@ void gprs_rlcmac_tbf::set_polling(uint32_t new_poll_fn, uint8_t ts, enum pdch_ul
{
const char *chan = "UNKNOWN";
- if (state_flags & (1 << (GPRS_RLCMAC_FLAG_CCCH)))
+ if (state_fsm.state_flags & (1 << (GPRS_RLCMAC_FLAG_CCCH)))
chan = "CCCH";
- if (state_flags & (1 << (GPRS_RLCMAC_FLAG_PACCH)))
+ if (state_fsm.state_flags & (1 << (GPRS_RLCMAC_FLAG_PACCH)))
chan = "PACCH";
- if ((state_flags & (1 << (GPRS_RLCMAC_FLAG_PACCH))) && (state_flags & (1 << (GPRS_RLCMAC_FLAG_CCCH))))
+ if ((state_fsm.state_flags & (1 << (GPRS_RLCMAC_FLAG_PACCH))) &&
+ (state_fsm.state_flags & (1 << (GPRS_RLCMAC_FLAG_CCCH))))
LOGPTBFDL(this, LOGL_ERROR,
"Attempt to schedule polling on %s (FN=%d, TS=%d) with both CCCH and PACCH flags set - FIXME!\n",
chan, new_poll_fn, ts);
@@ -648,11 +649,11 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_
}
} else if (ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) {
- if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) {
+ if (!(state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) {
LOGPTBF(this, LOGL_NOTICE,
"Timeout for polling PACKET CONTROL ACK for PACKET UPLINK ASSIGNMENT: %s\n",
rlcmac_diag().c_str());
- state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);
+ state_fsm.state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);
}
ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_TIMEDOUT);
@@ -667,11 +668,11 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_
/* reschedule UL assignment */
ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
} else if (dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) {
- if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) {
+ if (!(state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) {
LOGPTBF(this, LOGL_NOTICE,
"Timeout for polling PACKET CONTROL ACK for PACKET DOWNLINK ASSIGNMENT: %s\n",
rlcmac_diag().c_str());
- state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);
+ state_fsm.state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);
}
dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_TIMEDOUT);
@@ -693,11 +694,11 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_
} else if (direction == GPRS_RLCMAC_DL_TBF) {
gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);
- if (!(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {
+ if (!(dl_tbf->state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {
LOGPTBF(this, LOGL_NOTICE,
"Timeout for polling PACKET DOWNLINK ACK: %s\n",
dl_tbf->rlcmac_diag().c_str());
- dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
+ dl_tbf->state_fsm.state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
}
if (dl_tbf->state_is(TBF_ST_RELEASING))
@@ -715,8 +716,8 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_
return;
}
/* resend IMM.ASS on CCCH on timeout */
- if ((dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))
- && !(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) {
+ if ((dl_tbf->state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))
+ && !(dl_tbf->state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) {
LOGPTBF(dl_tbf, LOGL_DEBUG, "Re-send dowlink assignment on PCH (IMSI=%s)\n",
imsi());
/* send immediate assignment */
@@ -788,7 +789,7 @@ void gprs_rlcmac_tbf::handle_timeout()
LOGPTBF(this, LOGL_DEBUG, "timer 0 expired. cur_fn=%d\n", current_fn);
/* PACCH assignment timeout (see timers X2000, X2001) */
- if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) {
+ if ((state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) {
if (state_is(TBF_ST_ASSIGN)) {
LOGPTBF(this, LOGL_NOTICE, "releasing due to PACCH assignment timeout.\n");
tbf_free(this);
@@ -798,7 +799,7 @@ void gprs_rlcmac_tbf::handle_timeout()
}
/* Finish waiting after IMM.ASS confirm timer for CCCH assignment (see timer X2002) */
- if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) {
+ if ((state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) {
gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);
dl_tbf->m_wait_confirm = 0;
if (dl_tbf->state_is(TBF_ST_ASSIGN)) {
@@ -817,7 +818,7 @@ void gprs_rlcmac_tbf::handle_timeout()
* PDCH. */
/* keep to flags */
- dl_tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;
+ dl_tbf->state_fsm.state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;
dl_tbf->update();
@@ -831,15 +832,15 @@ std::string gprs_rlcmac_tbf::rlcmac_diag()
{
std::ostringstream os;
os << "|";
- if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)))
+ if ((state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)))
os << "Assignment was on CCCH|";
- if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH)))
+ if ((state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH)))
os << "Assignment was on PACCH|";
- if ((state_flags & (1 << GPRS_RLCMAC_FLAG_UL_DATA)))
+ if ((state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_UL_DATA)))
os << "Uplink data was received|";
else if (direction == GPRS_RLCMAC_UL_TBF)
os << "No uplink data received yet|";
- if ((state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK)))
+ if ((state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK)))
os << "Downlink ACK was received|";
else if (direction == GPRS_RLCMAC_DL_TBF)
os << "No downlink ACK received yet|";
diff --git a/src/tbf.h b/src/tbf.h
index d9fdaacc..adc648ce 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -162,9 +162,6 @@ enum tbf_counters { /* TBF counters from 3GPP TS 44.060 ยง13.4 */
#define TBF_SET_ASS_STATE_DL(t, st) do { t->set_ass_state_dl(st, __FILE__, __LINE__); } while(0)
#define TBF_SET_ASS_STATE_UL(t, st) do { t->set_ass_state_ul(st, __FILE__, __LINE__); } while(0)
#define TBF_SET_ACK_STATE(t, st) do { t->set_ack_state(st, __FILE__, __LINE__); } while(0)
-#define TBF_SET_ASS_ON(t, fl, chk) do { t->set_assigned_on(fl, chk, __FILE__, __LINE__); } while(0)
-#define TBF_ASS_TYPE_SET(t, kind) do { t->ass_type_mod(kind, false, __FILE__, __LINE__); } while(0)
-#define TBF_ASS_TYPE_UNSET(t, kind) do { t->ass_type_mod(kind, true, __FILE__, __LINE__); } while(0)
#ifdef __cplusplus
extern "C" {
@@ -214,8 +211,6 @@ struct gprs_rlcmac_tbf {
void poll_sched_set(const char *file, int line);
void poll_sched_unset(const char *file, int line);
bool check_n_clear(uint8_t state_flag);
- void set_assigned_on(uint8_t state_flag, bool check_ccch, const char *file, int line);
- void ass_type_mod(uint8_t t, bool unset, const char *file, int line);
const char *state_name() const;
const char *name() const;
@@ -276,7 +271,6 @@ struct gprs_rlcmac_tbf {
/* attempt to make things a bit more fair */
void rotate_in_list();
- uint32_t state_flags;
enum gprs_rlcmac_tbf_direction direction;
struct gprs_rlcmac_trx *trx;
uint8_t first_ts; /* first TS used by TBF */
@@ -370,63 +364,6 @@ inline const char *gprs_rlcmac_tbf::state_name() const
return osmo_fsm_inst_state_name(state_fsm.fi);
}
-/* Set assignment state and corrsponding flags */
-inline void gprs_rlcmac_tbf::set_assigned_on(uint8_t state_flag, bool check_ccch, const char *file, int line)
-{
- tbf_fsm_state_chg(state_fsm.fi, TBF_ST_ASSIGN);
- if (check_ccch) {
- if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)))
- ass_type_mod(state_flag, false, file, line);
- } else
- state_flags |= (1 << state_flag);
-}
-
-inline void gprs_rlcmac_tbf::ass_type_mod(uint8_t t, bool unset, const char *file, int line)
-{
- const char *ch = "UNKNOWN";
- switch (t) {
- case GPRS_RLCMAC_FLAG_CCCH:
- if (unset) {
- if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)))
- return;
- } else {
- if (state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))
- LOGPSRC(DTBF, LOGL_ERROR, file, line,
- "%s attempted to set ass. type CCCH which is already set.\n",
- tbf_name(this));
- }
- ch = "CCCH";
- break;
- case GPRS_RLCMAC_FLAG_PACCH:
- if (unset) {
- if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH)))
- return;
- } else {
- if (state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))
- LOGPSRC(DTBF, LOGL_ERROR, file, line,
- "%s attempted to set ass. type PACCH which is already set.\n",
- tbf_name(this));
- }
- ch = "PACCH";
- break;
- default:
- LOGPSRC(DTBF, LOGL_ERROR, file, line, "%s attempted to %sset unexpected ass. type %d - FIXME!\n",
- tbf_name(this), unset ? "un" : "", t);
- return;
- }
-
- LOGPSRC(DTBF, LOGL_INFO, file, line, "%s %sset ass. type %s [prev CCCH:%u, PACCH:%u]\n",
- tbf_name(this), unset ? "un" : "", ch,
- state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH),
- state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH));
-
- if (unset) {
- state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; /* keep to flags */
- state_flags &= ~(1 << t);
- } else
- state_flags |= (1 << t);
-}
-
inline void gprs_rlcmac_tbf::set_ass_state_dl(enum gprs_rlcmac_tbf_dl_ass_state new_state, const char *file, int line)
{
LOGPSRC(DTBF, LOGL_DEBUG, file, line, "%s changes DL ASS state from %s to %s\n",
@@ -456,8 +393,8 @@ inline void gprs_rlcmac_tbf::set_ack_state(enum gprs_rlcmac_tbf_ul_ack_state new
inline bool gprs_rlcmac_tbf::check_n_clear(uint8_t state_flag)
{
- if ((state_flags & (1 << state_flag))) {
- state_flags &= ~(1 << state_flag);
+ if ((state_fsm.state_flags & (1 << state_flag))) {
+ state_fsm.state_flags &= ~(1 << state_flag);
return true;
}
@@ -481,7 +418,7 @@ inline bool gprs_rlcmac_tbf::is_tfi_assigned() const
return state_fsm.fi->state > TBF_ST_ASSIGN ||
(direction == GPRS_RLCMAC_DL_TBF &&
state_fsm.fi->state == TBF_ST_ASSIGN &&
- (state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)));
+ (state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)));
}
inline uint8_t gprs_rlcmac_tbf::tfi() const
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index eb215fe4..12fd99fa 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -605,7 +605,7 @@ void gprs_rlcmac_dl_tbf::trigger_ass(struct gprs_rlcmac_tbf *old_tbf)
old_tbf->was_releasing = old_tbf->state_is(TBF_ST_WAIT_RELEASE);
/* change state */
- TBF_SET_ASS_ON(this, GPRS_RLCMAC_FLAG_PACCH, true);
+ osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_ASSIGN_ADD_PACCH, NULL);
/* Start timer, expiry in gprs_rlcmac_tbf::handle_timeout tbf_free()s the TBF */
T_START(this, T0, -2001, "assignment (PACCH)", true);
@@ -615,7 +615,7 @@ void gprs_rlcmac_dl_tbf::trigger_ass(struct gprs_rlcmac_tbf *old_tbf)
was_releasing = state_is(TBF_ST_WAIT_RELEASE);
/* change state */
- TBF_SET_ASS_ON(this, GPRS_RLCMAC_FLAG_CCCH, false);
+ osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_ASSIGN_ADD_CCCH, NULL);
/* send immediate assignment */
if ((pgroup = imsi2paging_group(imsi())) > 999)
@@ -777,7 +777,7 @@ bool gprs_rlcmac_dl_tbf::handle_ack_nack()
{
bool ack_recovered = false;
- state_flags |= (1 << GPRS_RLCMAC_FLAG_DL_ACK);
+ state_fsm.state_flags |= (1 << GPRS_RLCMAC_FLAG_DL_ACK);
if (check_n_clear(GPRS_RLCMAC_FLAG_TO_DL_ACK)) {
ack_recovered = true;
}
@@ -957,7 +957,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
if (m_last_dl_poll_fn < 0)
m_last_dl_poll_fn = fn;
- need_poll = state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
+ need_poll = state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
/* poll after POLL_ACK_AFTER_FRAMES frames, or when final block is tx.
*/
@@ -985,7 +985,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
if (is_final)
T_START(this, T3191, 3191, "final block (DL-TBF)", true);
- state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); /* clear poll timeout flag */
+ state_fsm.state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); /* clear poll timeout flag */
/* Clear request flag */
m_dl_ack_requested = false;
@@ -1251,7 +1251,7 @@ int gprs_rlcmac_dl_tbf::release()
m_wait_confirm = 0;
m_window.reset();
- TBF_ASS_TYPE_UNSET(this, GPRS_RLCMAC_FLAG_CCCH);
+ osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_ASSIGN_DEL_CCCH, NULL);
return 0;
}
@@ -1277,7 +1277,7 @@ int gprs_rlcmac_dl_tbf::abort()
/* reset rlc states */
m_window.reset();
- TBF_ASS_TYPE_UNSET(this, GPRS_RLCMAC_FLAG_CCCH);
+ osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_ASSIGN_DEL_CCCH, NULL);
return 0;
}
@@ -1324,7 +1324,7 @@ void gprs_rlcmac_dl_tbf::request_dl_ack()
bool gprs_rlcmac_dl_tbf::need_control_ts() const
{
- return state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK) ||
+ return state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK) ||
m_tx_counter >= POLL_ACK_AFTER_FRAMES ||
m_dl_ack_requested;
}
diff --git a/src/tbf_fsm.c b/src/tbf_fsm.c
index 3bf701a4..93019313 100644
--- a/src/tbf_fsm.c
+++ b/src/tbf_fsm.c
@@ -41,10 +41,85 @@ const struct osmo_tdef_state_timeout tbf_fsm_timeouts[32] = {
};
const struct value_string tbf_fsm_event_names[] = {
- { TBF_EV_FOOBAR, "FOOBAR" },
+ { TBF_EV_ASSIGN_ADD_CCCH, "ASSIGN_ADD_CCCH" },
+ { TBF_EV_ASSIGN_ADD_PACCH, "ASSIGN_ADD_PACCH" },
+ { TBF_EV_ASSIGN_DEL_CCCH, "ASSIGN_DEL_CCCH" },
{ 0, NULL }
};
+static void mod_ass_type(struct tbf_fsm_ctx *ctx, uint8_t t, bool set)
+{
+ const char *ch = "UNKNOWN";
+ bool prev_set = ctx->state_flags & (1 << t);
+
+ switch (t) {
+ case GPRS_RLCMAC_FLAG_CCCH:
+ ch = "CCCH";
+ break;
+ case GPRS_RLCMAC_FLAG_PACCH:
+ ch = "PACCH";
+ break;
+ default:
+ LOGPTBF(ctx->tbf, LOGL_ERROR,
+ "attempted to %sset unexpected ass. type %d - FIXME!\n",
+ set ? "" : "un", t);
+ return;
+ }
+
+ if (set && prev_set) {
+ LOGPTBF(ctx->tbf, LOGL_ERROR,
+ "attempted to set ass. type %s which is already set.\n", ch);
+ } else if (!set && !prev_set) {
+ return;
+ }
+
+ LOGPTBF(ctx->tbf, LOGL_INFO, "%sset ass. type %s [prev CCCH:%u, PACCH:%u]\n",
+ set ? "" : "un", ch,
+ !!(ctx->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)),
+ !!(ctx->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH)));
+
+ if (set) {
+ ctx->state_flags |= (1 << t);
+ } else {
+ ctx->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; /* keep to flags */
+ ctx->state_flags &= ~(1 << t);
+ }
+}
+
+
+static void st_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv;
+ switch (event) {
+ case TBF_EV_ASSIGN_ADD_CCCH:
+ mod_ass_type(ctx, GPRS_RLCMAC_FLAG_CCCH, true);
+ tbf_fsm_state_chg(fi, tbf_direction(ctx->tbf) == GPRS_RLCMAC_DL_TBF ?
+ TBF_ST_ASSIGN : TBF_ST_FLOW);
+ break;
+ case TBF_EV_ASSIGN_ADD_PACCH:
+ mod_ass_type(ctx, GPRS_RLCMAC_FLAG_PACCH, true);
+ tbf_fsm_state_chg(fi, TBF_ST_ASSIGN);
+ break;
+ default:
+ OSMO_ASSERT(0);
+ }
+}
+
+static void st_assign(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv;
+ switch (event) {
+ case TBF_EV_ASSIGN_ADD_CCCH:
+ mod_ass_type(ctx, GPRS_RLCMAC_FLAG_CCCH, true);
+ break;
+ case TBF_EV_ASSIGN_ADD_PACCH:
+ mod_ass_type(ctx, GPRS_RLCMAC_FLAG_PACCH, true);
+ break;
+ default:
+ OSMO_ASSERT(0);
+ }
+}
+
static void tbf_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
{
/* TODO: needed ?
@@ -64,24 +139,25 @@ static int tbf_fsm_timer_cb(struct osmo_fsm_inst *fi)
static struct osmo_fsm_state tbf_fsm_states[] = {
[TBF_ST_NULL] = {
.in_event_mask =
- 0,
+ X(TBF_EV_ASSIGN_ADD_CCCH) |
+ X(TBF_EV_ASSIGN_ADD_PACCH),
.out_state_mask =
X(TBF_ST_ASSIGN) |
X(TBF_ST_FLOW) |
X(TBF_ST_RELEASING),
.name = "NULL",
- //.action = st_null,
+ .action = st_null,
},
[TBF_ST_ASSIGN] = {
.in_event_mask =
- 0,
+ X(TBF_EV_ASSIGN_ADD_CCCH) |
+ X(TBF_EV_ASSIGN_ADD_PACCH),
.out_state_mask =
X(TBF_ST_FLOW) |
X(TBF_ST_FINISHED) |
X(TBF_ST_RELEASING),
.name = "ASSIGN",
- //.onenter = st_assign_on_enter,
- //.action = st_assign,
+ .action = st_assign,
},
[TBF_ST_FLOW] = {
.in_event_mask =
@@ -91,8 +167,6 @@ static struct osmo_fsm_state tbf_fsm_states[] = {
X(TBF_ST_WAIT_RELEASE) |
X(TBF_ST_RELEASING),
.name = "FLOW",
- //.onenter = st_flow_on_enter,
- //.action = st_flow,
},
[TBF_ST_FINISHED] = {
.in_event_mask =
@@ -100,8 +174,6 @@ static struct osmo_fsm_state tbf_fsm_states[] = {
.out_state_mask =
X(TBF_ST_WAIT_RELEASE),
.name = "FINISHED",
- //.onenter = st_finished_on_enter,
- //.action = st_finished,
},
[TBF_ST_WAIT_RELEASE] = {
.in_event_mask =
@@ -109,7 +181,6 @@ static struct osmo_fsm_state tbf_fsm_states[] = {
.out_state_mask =
X(TBF_ST_RELEASING),
.name = "WAIT_RELEASE",
- //.action = st_wait_release,
},
[TBF_ST_RELEASING] = {
.in_event_mask =
@@ -117,10 +188,21 @@ static struct osmo_fsm_state tbf_fsm_states[] = {
.out_state_mask =
0,
.name = "RELEASING",
- //.action = st_releasing,
},
};
+void tbf_fsm_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv;
+ switch (event) {
+ case TBF_EV_ASSIGN_DEL_CCCH:
+ mod_ass_type(ctx, GPRS_RLCMAC_FLAG_CCCH, false);
+ break;
+ default:
+ OSMO_ASSERT(0);
+ }
+}
+
struct osmo_fsm tbf_fsm = {
.name = "TBF",
.states = tbf_fsm_states,
@@ -129,6 +211,8 @@ struct osmo_fsm tbf_fsm = {
.cleanup = tbf_fsm_cleanup,
.log_subsys = DTBF,
.event_names = tbf_fsm_event_names,
+ .allstate_action = tbf_fsm_allstate_action,
+ .allstate_event_mask = X(TBF_EV_ASSIGN_DEL_CCCH),
};
static __attribute__((constructor)) void tbf_fsm_init(void)
diff --git a/src/tbf_fsm.h b/src/tbf_fsm.h
index 84bb4373..ed025ca5 100644
--- a/src/tbf_fsm.h
+++ b/src/tbf_fsm.h
@@ -27,7 +27,9 @@
struct gprs_rlcmac_tbf;
enum tbf_fsm_event {
- TBF_EV_FOOBAR,
+ TBF_EV_ASSIGN_ADD_CCCH, /* An assignment is sent over CCCH and confirmation from MS is pending */
+ TBF_EV_ASSIGN_ADD_PACCH, /* An assignment is sent over PACCH and confirmation from MS is pending */
+ TBF_EV_ASSIGN_DEL_CCCH, /* An assignment previously sent over CCCH has been confirmed by MS */
};
enum tbf_fsm_states {
@@ -42,6 +44,7 @@ enum tbf_fsm_states {
struct tbf_fsm_ctx {
struct osmo_fsm_inst *fi;
struct gprs_rlcmac_tbf* tbf; /* back pointer */
+ uint32_t state_flags;
};
extern const struct osmo_tdef_state_timeout tbf_fsm_timeouts[32];
diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp
index 5ca02d95..2874fc63 100644
--- a/src/tbf_ul.cpp
+++ b/src/tbf_ul.cpp
@@ -154,7 +154,7 @@ gprs_rlcmac_ul_tbf *tbf_alloc_ul_pacch(struct gprs_rlcmac_bts *bts, GprsMs *ms,
return NULL;
}
tbf->m_contention_resolution_done = 1;
- TBF_SET_ASS_ON(tbf, GPRS_RLCMAC_FLAG_PACCH, false);
+ osmo_fsm_inst_dispatch(tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_PACCH, NULL);
tbf->update_ms(tlli, GPRS_RLCMAC_UL_TBF);
OSMO_ASSERT(tbf->ms());
@@ -172,8 +172,7 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_ccch(struct gprs_rlcmac_bts *bts, struct
/* Caller will most probably send a Imm Ass Reject after return */
return NULL;
}
- TBF_SET_STATE(tbf, TBF_ST_FLOW);
- TBF_ASS_TYPE_SET(tbf, GPRS_RLCMAC_FLAG_CCCH);
+ osmo_fsm_inst_dispatch(tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_CCCH, NULL);
tbf->contention_resolution_start();
OSMO_ASSERT(tbf->ms());
@@ -215,7 +214,7 @@ struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts,
ms_attach_tbf(ms, ul_tbf);
llist_add(tbf_trx_list((struct gprs_rlcmac_tbf *)ul_tbf), &trx->ul_tbfs);
bts_do_rate_ctr_inc(ul_tbf->bts, CTR_TBF_UL_ALLOCATED);
- TBF_SET_ASS_ON(ul_tbf, GPRS_RLCMAC_FLAG_PACCH, false);
+ osmo_fsm_inst_dispatch(ul_tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_PACCH, NULL);
TBF_SET_ASS_STATE_UL(ul_tbf, GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ);
return ul_tbf;
@@ -287,7 +286,7 @@ bool gprs_rlcmac_ul_tbf::ctrl_ack_to_toggle()
if (check_n_clear(GPRS_RLCMAC_FLAG_TO_UL_ACK))
return true; /* GPRS_RLCMAC_FLAG_TO_UL_ACK was set, now cleared */
- state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK);
+ state_fsm.state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK);
return false; /* GPRS_RLCMAC_FLAG_TO_UL_ACK was unset, now set */
}
@@ -398,7 +397,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(
const uint16_t ws = m_window.ws();
- this->state_flags |= (1 << GPRS_RLCMAC_FLAG_UL_DATA);
+ this->state_fsm.state_flags |= (1 << GPRS_RLCMAC_FLAG_UL_DATA);
LOGPTBFUL(this, LOGL_DEBUG, "UL DATA TFI=%d received (V(Q)=%d .. "
"V(R)=%d)\n", rlc->tfi, this->m_window.v_q(),