tbf_fsm: Move osmo_fsm_inst fi out of struct tbf_fsm_ctx

This is a preparatory step towards splitting tbf_fsm.c into tbf_ul_fsm.c
and tbf_dl_fsm.c.
In order to accomplish it, the struct tbf_fsm_ctx will also be
duplicated (and each one will contain a explicit ul_tbf/dl_tbf pointer).
Hence, a DL_TBF will have a struct tbf_dl_fsm_ctx and a UL_TBF will have
a struct tbf_ul_fsm_ctx, since those hold implementation specific
state. However, the FSM interface will be partly shared (events,
states), and hence we want to keep the "fi" pointer into the "tbf"
parent class so that it can be used regardless of the tbf direction
type.

Change-Id: I03e691ccf6a94431caa55653349158f5b85db017
This commit is contained in:
Pau Espin 2022-11-17 20:18:46 +01:00
parent 06abd3ea19
commit f197f15b2d
9 changed files with 39 additions and 38 deletions

View File

@ -707,7 +707,7 @@ int bts_rcv_imm_ass_cnf(struct gprs_rlcmac_bts *bts, const uint8_t *data, uint32
}
LOGPTBFDL(dl_tbf, LOGL_DEBUG, "FN=%u Got IMM.ASS confirm\n", fn);
osmo_fsm_inst_dispatch(dl_tbf->state_fsm.fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
osmo_fsm_inst_dispatch(dl_tbf->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
return 0;
}

View File

@ -387,7 +387,7 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet,
osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_RX_CTRL_ACK, NULL);
/* We only set polling on final UL ACK/NACK, something is wrong... */
if (tbf_state(tbf) == TBF_ST_FINISHED)
osmo_fsm_inst_dispatch(ul_tbf->state_fsm.fi, TBF_EV_FINAL_UL_ACK_CONFIRMED, (void*)false);
osmo_fsm_inst_dispatch(ul_tbf->state_fi, TBF_EV_FINAL_UL_ACK_CONFIRMED, (void*)false);
/* ul_tbf is freed here! */
else
LOGPTBFUL(ul_tbf, LOGL_ERROR, "Received POLL_UL_ACK for UL TBF in unexpected state!\n");
@ -416,7 +416,7 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet,
tbf->direction == new_tbf->direction)
tbf_free(tbf);
osmo_fsm_inst_dispatch(new_tbf->state_fsm.fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);
osmo_fsm_inst_dispatch(new_tbf->state_fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);
/* there might be LLC packets waiting in the queue, but the DL
* TBF might have been released while the UL TBF has been
* established */
@ -447,7 +447,7 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet,
tbf->direction == new_tbf->direction)
tbf_free(tbf);
osmo_fsm_inst_dispatch(new_tbf->state_fsm.fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);
osmo_fsm_inst_dispatch(new_tbf->state_fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);
return;
case PDCH_ULC_POLL_CELL_CHG_CONTINUE:
@ -735,7 +735,7 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request,
"block of final UL ACK/NACK\n", fn);
ul_tbf->n_reset(N3103);
pdch_ulc_release_node(ulc, item);
rc = osmo_fsm_inst_dispatch(ul_tbf->state_fsm.fi, TBF_EV_FINAL_UL_ACK_CONFIRMED, (void*)true);
rc = osmo_fsm_inst_dispatch(ul_tbf->state_fi, TBF_EV_FINAL_UL_ACK_CONFIRMED, (void*)true);
if (rc) {
/* FSM failed handling, get rid of previous finished UL TBF before providing a new one */
LOGPTBFUL(ul_tbf, LOGL_NOTICE,

View File

@ -117,8 +117,8 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_
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);
OSMO_ASSERT(state_fsm.fi);
state_fi = osmo_fsm_inst_alloc(&tbf_fsm, this, &state_fsm, LOGL_INFO, NULL);
OSMO_ASSERT(state_fi);
memset(&ul_ass_fsm, 0, sizeof(ul_ass_fsm));
ul_ass_fsm.tbf = this;
@ -140,8 +140,8 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_
gprs_rlcmac_tbf::~gprs_rlcmac_tbf()
{
osmo_fsm_inst_free(state_fsm.fi);
state_fsm.fi = NULL;
osmo_fsm_inst_free(state_fi);
state_fi = NULL;
osmo_fsm_inst_free(ul_ass_fsm.fi);
ul_ass_fsm.fi = NULL;
@ -538,7 +538,7 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_
if (state_is(TBF_ST_FINISHED)) {
if (ul_tbf->n_inc(N3103)) {
bts_do_rate_ctr_inc(bts, CTR_PUAN_POLL_FAILED);
osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_MAX_N3103, NULL);
osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_MAX_N3103, NULL);
return;
}
}
@ -555,7 +555,7 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_
bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_PUA_POLL_TIMEDOUT);
if (n_inc(N3105)) {
osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_MAX_N3105, NULL);
osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_MAX_N3105, NULL);
bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_FAILED);
bts_do_rate_ctr_inc(bts, CTR_PUA_POLL_FAILED);
return;
@ -574,7 +574,7 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_
bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_PDA_POLL_TIMEDOUT);
if (n_inc(N3105)) {
osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_MAX_N3105, NULL);
osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_MAX_N3105, NULL);
bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_FAILED);
bts_do_rate_ctr_inc(bts, CTR_PDA_POLL_FAILED);
return;
@ -610,13 +610,13 @@ void gprs_rlcmac_tbf::poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_
bts_do_rate_ctr_inc(bts, CTR_PDAN_POLL_TIMEDOUT);
}
if (dl_tbf->n_inc(N3105)) {
osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_MAX_N3105, NULL);
osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_MAX_N3105, NULL);
bts_do_rate_ctr_inc(bts, CTR_PDAN_POLL_FAILED);
bts_do_rate_ctr_inc(bts, CTR_RLC_ACK_FAILED);
return;
}
/* resend IMM.ASS on CCCH on timeout */
osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_DL_ACKNACK_MISS, NULL);
osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_DL_ACKNACK_MISS, NULL);
break;
default:
@ -700,7 +700,7 @@ void tbf_update_state_fsm_name(struct gprs_rlcmac_tbf *tbf)
{
const char *buf = tbf->name(false);
osmo_fsm_inst_update_id(tbf->state_fsm.fi, buf);
osmo_fsm_inst_update_id(tbf->state_fi, buf);
osmo_fsm_inst_update_id(tbf->ul_ass_fsm.fi, buf);
osmo_fsm_inst_update_id(tbf->dl_ass_fsm.fi, buf);
@ -782,12 +782,12 @@ void gprs_rlcmac_tbf::enable_egprs()
/* C API */
enum tbf_fsm_states tbf_state(const struct gprs_rlcmac_tbf *tbf)
{
return (enum tbf_fsm_states)tbf->state_fsm.fi->state;
return (enum tbf_fsm_states)tbf->state_fi->state;
}
struct osmo_fsm_inst *tbf_state_fi(const struct gprs_rlcmac_tbf *tbf)
{
return tbf->state_fsm.fi;
return tbf->state_fi;
}
struct osmo_fsm_inst *tbf_ul_ass_fi(const struct gprs_rlcmac_tbf *tbf)

View File

@ -257,6 +257,7 @@ struct gprs_rlcmac_tbf {
time_t m_created_ts;
struct rate_ctr_group *m_ctrs;
struct osmo_fsm_inst *state_fi;
struct tbf_fsm_ctx state_fsm;
struct tbf_ul_ass_fsm_ctx ul_ass_fsm;
struct tbf_ul_ass_fsm_ctx dl_ass_fsm;
@ -302,7 +303,7 @@ inline bool gprs_rlcmac_tbf::state_is_not(enum tbf_fsm_states rhs) const
inline const char *gprs_rlcmac_tbf::state_name() const
{
return osmo_fsm_inst_state_name(state_fsm.fi);
return osmo_fsm_inst_state_name(state_fi);
}
inline bool gprs_rlcmac_tbf::check_n_clear(uint8_t state_flag)
@ -329,9 +330,9 @@ inline bool gprs_rlcmac_tbf::is_tfi_assigned() const
{
/* The TBF is established or has been assigned by a IMM.ASS for
* download */
return state_fsm.fi->state > TBF_ST_ASSIGN ||
return state_fi->state > TBF_ST_ASSIGN ||
(direction == GPRS_RLCMAC_DL_TBF &&
state_fsm.fi->state == TBF_ST_ASSIGN &&
state_fi->state == TBF_ST_ASSIGN &&
(state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)));
}

View File

@ -422,7 +422,7 @@ void dl_tbf_trigger_ass_on_pacch(struct gprs_rlcmac_dl_tbf *tbf, struct gprs_rlc
osmo_fsm_inst_dispatch(old_tbf->dl_ass_fsm.fi, TBF_DL_ASS_EV_SCHED_ASS, NULL);
/* change state */
osmo_fsm_inst_dispatch(tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_PACCH, NULL);
osmo_fsm_inst_dispatch(tbf->state_fi, TBF_EV_ASSIGN_ADD_PACCH, NULL);
}
@ -436,7 +436,7 @@ void dl_tbf_trigger_ass_on_pch(struct gprs_rlcmac_dl_tbf *tbf)
LOGPTBFDL(tbf, LOGL_DEBUG, "Send downlink assignment on PCH, no TBF exist (IMSI=%s)\n", ms_imsi(ms));
/* change state */
osmo_fsm_inst_dispatch(tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_CCCH, NULL);
osmo_fsm_inst_dispatch(tbf->state_fi, TBF_EV_ASSIGN_ADD_CCCH, NULL);
/* send immediate assignment */
bts_snd_dl_ass(ms->bts, tbf);
@ -528,7 +528,7 @@ int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, enum CodingScheme cs)
is_final = llc_queue_size(llc_queue()) == 0 && !keep_open(fn);
if (is_final) {
rdbi->cv = 0;
osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_LAST_DL_DATA_SENT, NULL);
osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_LAST_DL_DATA_SENT, NULL);
}
if (mcs_is_edge(cs)) {
@ -573,7 +573,7 @@ int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, enum CodingScheme cs)
if (is_final) {
request_dl_ack();
osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_LAST_DL_DATA_SENT, NULL);
osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_LAST_DL_DATA_SENT, NULL);
}
/* dequeue next LLC frame, if any */
@ -962,7 +962,7 @@ int gprs_rlcmac_dl_tbf::rcvd_dl_final_ack()
uint16_t received;
int rc = 0;
osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_FINAL_ACK_RECVD, NULL);
osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_FINAL_ACK_RECVD, NULL);
/* range V(A)..V(S)-1 */
received = m_window.count_unacked();

View File

@ -417,20 +417,21 @@ static void st_releasing(struct osmo_fsm_inst *fi, uint32_t event, void *data)
}
}
static void handle_timeout_X2002(struct tbf_fsm_ctx *ctx)
static void handle_timeout_X2002(struct osmo_fsm_inst *fi)
{
struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv;
struct gprs_rlcmac_dl_tbf *dl_tbf = tbf_as_dl_tbf(ctx->tbf);
/* X2002 is used only for DL TBF */
OSMO_ASSERT(dl_tbf);
if (ctx->fi->state == TBF_ST_ASSIGN) {
if (fi->state == TBF_ST_ASSIGN) {
tbf_assign_control_ts(ctx->tbf);
if (!tbf_can_upgrade_to_multislot(ctx->tbf)) {
/* change state to FLOW, so scheduler
* will start transmission */
osmo_fsm_inst_dispatch(ctx->fi, TBF_EV_ASSIGN_READY_CCCH, NULL);
osmo_fsm_inst_dispatch(fi, TBF_EV_ASSIGN_READY_CCCH, NULL);
return;
}
@ -453,7 +454,7 @@ static int tbf_fsm_timer_cb(struct osmo_fsm_inst *fi)
struct tbf_fsm_ctx *ctx = (struct tbf_fsm_ctx *)fi->priv;
switch (fi->T) {
case -2002:
handle_timeout_X2002(ctx);
handle_timeout_X2002(fi);
break;
case -2001:
LOGPTBF(ctx->tbf, LOGL_NOTICE, "releasing due to PACCH assignment timeout.\n");

View File

@ -50,7 +50,6 @@ enum tbf_fsm_states {
};
struct tbf_fsm_ctx {
struct osmo_fsm_inst *fi;
struct gprs_rlcmac_tbf* tbf; /* back pointer */
uint32_t state_flags;
unsigned int T_release; /* Timer to be used to end release: T3169 or T3195 */

View File

@ -186,7 +186,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);
osmo_fsm_inst_dispatch(ul_tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_PACCH, NULL);
osmo_fsm_inst_dispatch(ul_tbf->state_fi, TBF_EV_ASSIGN_ADD_PACCH, NULL);
osmo_fsm_inst_dispatch(ul_tbf->ul_ass_fsm.fi, TBF_UL_ASS_EV_SCHED_ASS_REJ, NULL);
return ul_tbf;
@ -402,7 +402,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(
"Decoded premier TLLI=0x%08x of UL DATA TFI=%d.\n",
new_tlli, rlc->tfi);
ms_update_announced_tlli(ms(), new_tlli);
osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_FIRST_UL_DATA_RECVD, NULL);
osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_FIRST_UL_DATA_RECVD, NULL);
} else if (new_tlli != GSM_RESERVED_TMSI && new_tlli != tlli()) {
LOGPTBFUL(this, LOGL_NOTICE,
"Decoded TLLI=%08x mismatch on UL DATA TFI=%d. (Ignoring due to contention resolution)\n",
@ -444,7 +444,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(
rdbi->bsn, rdbi->cv);
if (rdbi->cv == 0) {
LOGPTBFUL(this, LOGL_DEBUG, "Finished with UL TBF\n");
osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_LAST_UL_DATA_RECVD, NULL);
osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_LAST_UL_DATA_RECVD, NULL);
/* Reset N3103 counter. */
this->n_reset(N3103);
}
@ -718,7 +718,7 @@ gprs_rlc_window *gprs_rlcmac_ul_tbf::window()
void gprs_rlcmac_ul_tbf::usf_timeout()
{
if (n_inc(N3101))
osmo_fsm_inst_dispatch(this->state_fsm.fi, TBF_EV_MAX_N3101, NULL);
osmo_fsm_inst_dispatch(this->state_fi, TBF_EV_MAX_N3101, NULL);
}
struct gprs_rlcmac_ul_tbf *tbf_as_ul_tbf(struct gprs_rlcmac_tbf *tbf)

View File

@ -91,7 +91,7 @@ static void check_tbf(gprs_rlcmac_tbf *tbf)
{
OSMO_ASSERT(tbf);
if (tbf->state_is(TBF_ST_WAIT_RELEASE))
OSMO_ASSERT(tbf->timers_pending(T3191) || osmo_timer_pending(&tbf->state_fsm.fi->timer));
OSMO_ASSERT(tbf->timers_pending(T3191) || osmo_timer_pending(&tbf->state_fi->timer));
if (tbf->state_is(TBF_ST_RELEASING))
OSMO_ASSERT(tbf->timers_pending(T_MAX));
}
@ -216,8 +216,8 @@ static gprs_rlcmac_dl_tbf *create_dl_tbf(struct gprs_rlcmac_bts *bts, uint8_t ms
/* "Establish" the DL TBF */
osmo_fsm_inst_dispatch(dl_tbf->dl_ass_fsm.fi, TBF_DL_ASS_EV_SCHED_ASS, NULL);
osmo_fsm_inst_dispatch(dl_tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_CCCH, NULL);
osmo_fsm_inst_dispatch(dl_tbf->state_fsm.fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);
osmo_fsm_inst_dispatch(dl_tbf->state_fi, TBF_EV_ASSIGN_ADD_CCCH, NULL);
osmo_fsm_inst_dispatch(dl_tbf->state_fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);
check_tbf(dl_tbf);
*trx_no_ = trx_no;
@ -593,7 +593,7 @@ static void test_tbf_dl_llc_loss()
* moves it to FLOW state. We set X2002 timeout to 0 here to get
* immediate trigger through osmo_select_main() */
OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0);
osmo_fsm_inst_dispatch(ms_dl_tbf(ms)->state_fsm.fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
osmo_fsm_inst_dispatch(ms_dl_tbf(ms)->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL);
osmo_select_main(0);
OSMO_ASSERT(ms_dl_tbf(ms)->state_is(TBF_ST_FLOW));