rlcmac: ul_tbf: Register UL ACK/NACK poll inside FSM

The poll is part of the FSM mechanism to get events to transit over the
different states. Register it from within the FSM to have more fine
grained control as well as have knowledge about the FN being reserved.

This knowledge will be used ina follow up patch for the UL TBF to wait
for the correct PKT CTRL ACK BLOCk.conf.

Change-Id: Iaa8ad8052b9f3b52b05af2b7fc9cb8172f1b6bb7
This commit is contained in:
Pau Espin 2024-02-02 14:17:10 +01:00
parent 31b298dfa5
commit d4c441f431
6 changed files with 51 additions and 27 deletions

View File

@ -71,7 +71,7 @@ struct msgb *gprs_rlcmac_ul_tbf_data_create(struct gprs_rlcmac_ul_tbf *ul_tbf, c
struct msgb *gprs_rlcmac_ul_tbf_dummy_create(struct gprs_rlcmac_ul_tbf *ul_tbf);
int gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(struct gprs_rlcmac_ul_tbf *ul_tbf,
const RlcMacDownlink_t *dl_block);
const struct gprs_rlcmac_dl_block_ind *dlbi);
int gprs_rlcmac_ul_tbf_handle_pkt_ul_ass(struct gprs_rlcmac_ul_tbf *ul_tbf,
const struct gprs_rlcmac_dl_block_ind *dlbi);

View File

@ -42,8 +42,7 @@ enum tbf_ul_fsm_event {
};
struct tbf_ul_ass_ev_rx_ul_ack_nack {
bool final_ack;
bool tbf_est;
const struct gprs_rlcmac_dl_block_ind *dlbi;
};
int gprs_rlcmac_tbf_ul_fsm_init(void);

View File

@ -710,16 +710,7 @@ static int gprs_rlcmac_handle_pkt_ul_ack_nack(const struct gprs_rlcmac_dl_block_
dlbi->ts_nr, dlbi->fn, pkt_ul_ack->UPLINK_TFI);
return -ENOENT;
}
rc = gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(ul_tbf, &dlbi->dl_block);
/* If RRBP contains valid data, schedule a response (PKT CONTROL ACK or PKT RESOURCE REQ). */
if (dlbi->dl_block.SP) {
uint32_t poll_fn = rrbp2fn(dlbi->fn, dlbi->dl_block.RRBP);
gprs_rlcmac_pdch_ulc_reserve(g_rlcmac_ctx->sched.ulc[dlbi->ts_nr], poll_fn,
GPRS_RLCMAC_PDCH_ULC_POLL_UL_ACK,
ul_tbf_as_tbf(ul_tbf));
}
rc = gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(ul_tbf, dlbi);
return rc;
}

View File

@ -305,9 +305,9 @@ static void gprs_rlcmac_ul_tbf_update_tx_cs(struct gprs_rlcmac_ul_tbf *ul_tbf, e
}
int gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(struct gprs_rlcmac_ul_tbf *ul_tbf,
const RlcMacDownlink_t *dl_block)
const struct gprs_rlcmac_dl_block_ind *dlbi)
{
const Packet_Uplink_Ack_Nack_t *ack = &dl_block->u.Packet_Uplink_Ack_Nack;
const Packet_Uplink_Ack_Nack_t *ack = &dlbi->dl_block.u.Packet_Uplink_Ack_Nack;
const PU_AckNack_GPRS_t *gprs = &ack->u.PU_AckNack_GPRS_Struct;
const Ack_Nack_Description_t *ack_desc = &gprs->Ack_Nack_Description;
int bsn_begin, bsn_end;
@ -321,8 +321,7 @@ int gprs_rlcmac_ul_tbf_handle_pkt_ul_ack_nack(struct gprs_rlcmac_ul_tbf *ul_tbf,
};
int rc;
struct tbf_ul_ass_ev_rx_ul_ack_nack ev_ack = {
.final_ack = ack_desc->FINAL_ACK_INDICATION,
.tbf_est = (gprs->Exist_AdditionsR99 && gprs->AdditionsR99.TBF_EST),
.dlbi = dlbi,
};
num_blocks = gprs_rlcmac_decode_gprs_acknack_bits(

View File

@ -27,8 +27,11 @@
#include <osmocom/gprs/rlcmac/tbf_ul.h>
#include <osmocom/gprs/rlcmac/rlc_window_ul.h>
#include <osmocom/gprs/rlcmac/gre.h>
#include <osmocom/gprs/rlcmac/pdch_ul_controller.h>
#define X(s) (1 << (s))
#define LOGPFSMLDLBI(fi, dlbi, lvl, fmt, args...) \
LOGPFSML(fi, lvl, "(ts=%u,fn=%u) " fmt, (dlbi)->ts_nr, (dlbi)->fn, ## args)
static const struct value_string tbf_ul_fsm_event_names[] = {
{ GPRS_RLCMAC_TBF_UL_EV_UL_ASS_START, "UL_ASS_START" },
@ -198,12 +201,30 @@ static void st_flow(struct osmo_fsm_inst *fi, uint32_t event, void *data)
reinit_pkt_acces_procedure(ctx);
break;
case GPRS_RLCMAC_TBF_UL_EV_RX_UL_ACK_NACK:
{
struct tbf_ul_ass_ev_rx_ul_ack_nack *ctx_ul_ack_nack = (struct tbf_ul_ass_ev_rx_ul_ack_nack *)data;
const struct gprs_rlcmac_dl_block_ind *dlbi = ctx_ul_ack_nack->dlbi;
const Packet_Uplink_Ack_Nack_t *ack = &dlbi->dl_block.u.Packet_Uplink_Ack_Nack;
const PU_AckNack_GPRS_t *gprs = &ack->u.PU_AckNack_GPRS_Struct;
const Ack_Nack_Description_t *ack_desc = &gprs->Ack_Nack_Description;
if (gprs_rlcmac_ul_tbf_in_contention_resolution(ctx->ul_tbf)) {
_contention_resolution_succeeded(ctx);
}
/* If RRBP contains valid data, schedule a response (PKT CONTROL ACK or PKT RESOURCE REQ). */
if (dlbi->dl_block.SP) {
uint32_t poll_fn = rrbp2fn(dlbi->fn, dlbi->dl_block.RRBP);
gprs_rlcmac_pdch_ulc_reserve(g_rlcmac_ctx->sched.ulc[dlbi->ts_nr], poll_fn,
GPRS_RLCMAC_PDCH_ULC_POLL_UL_ACK,
ul_tbf_as_tbf(ctx->ul_tbf));
}
/* It's impossible we receive a correct final_ack here, since we didn't
* sent last data (FSM would be in FINISHED state then) */
if (ack_desc->FINAL_ACK_INDICATION)
LOGPFSMLDLBI(ctx->fi, dlbi, LOGL_INFO, "Rx unexpected final_ack while not finished sending blocks. Network bug!\n");
break;
}
case GPRS_RLCMAC_TBF_UL_EV_LAST_UL_DATA_SENT:
arm_T3182_if_needed(ctx);
tbf_ul_fsm_state_chg(fi, GPRS_RLCMAC_TBF_UL_ST_FINISHED);
@ -216,13 +237,18 @@ static void st_flow(struct osmo_fsm_inst *fi, uint32_t event, void *data)
static void st_finished(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct gprs_rlcmac_tbf_ul_fsm_ctx *ctx = (struct gprs_rlcmac_tbf_ul_fsm_ctx *)fi->priv;
struct tbf_ul_ass_ev_rx_ul_ack_nack *ctx_ul_ack_nack;
switch (event) {
case GPRS_RLCMAC_TBF_UL_EV_N3104_MAX:
reinit_pkt_acces_procedure(ctx);
break;
case GPRS_RLCMAC_TBF_UL_EV_RX_UL_ACK_NACK:
ctx_ul_ack_nack = (struct tbf_ul_ass_ev_rx_ul_ack_nack *)data;
{
struct tbf_ul_ass_ev_rx_ul_ack_nack *ctx_ul_ack_nack = (struct tbf_ul_ass_ev_rx_ul_ack_nack *)data;
const struct gprs_rlcmac_dl_block_ind *dlbi = ctx_ul_ack_nack->dlbi;
const Packet_Uplink_Ack_Nack_t *ack = &dlbi->dl_block.u.Packet_Uplink_Ack_Nack;
const PU_AckNack_GPRS_t *gprs = &ack->u.PU_AckNack_GPRS_Struct;
const Ack_Nack_Description_t *ack_desc = &gprs->Ack_Nack_Description;
if (gprs_rlcmac_ul_tbf_in_contention_resolution(ctx->ul_tbf)) {
_contention_resolution_succeeded(ctx);
} else if (fi->T == 3182 && osmo_timer_pending(&fi->timer)) {
@ -230,16 +256,25 @@ static void st_finished(struct osmo_fsm_inst *fi, uint32_t event, void *data)
* the mobile station shall stop timer T3182 for the TBF".
* In our case we only use T3128 once we are out of contention resolution (T3166)
*/
LOGPFSML(ctx->fi, LOGL_DEBUG, "Rx Pkt UL ACK/NACK, stop T3182\n");
LOGPFSMLDLBI(ctx->fi, dlbi, LOGL_DEBUG, "Rx Pkt UL ACK/NACK, stop T3182\n");
osmo_timer_del(&fi->timer);
fi->T = 0;
}
if (ctx_ul_ack_nack->final_ack) {
LOGPFSML(ctx->fi, LOGL_DEBUG, "Final ACK received\n");
ctx->rx_final_pkt_ul_ack_nack_has_tbf_est = ctx_ul_ack_nack->tbf_est;
/* If RRBP contains valid data, schedule a response (PKT CONTROL ACK or PKT RESOURCE REQ). */
if (dlbi->dl_block.SP) {
uint32_t poll_fn = rrbp2fn(dlbi->fn, dlbi->dl_block.RRBP);
gprs_rlcmac_pdch_ulc_reserve(g_rlcmac_ctx->sched.ulc[dlbi->ts_nr], poll_fn,
GPRS_RLCMAC_PDCH_ULC_POLL_UL_ACK,
ul_tbf_as_tbf(ctx->ul_tbf));
}
if (ack_desc->FINAL_ACK_INDICATION) {
bool tbf_est = (gprs->Exist_AdditionsR99 && gprs->AdditionsR99.TBF_EST);
LOGPFSMLDLBI(ctx->fi, dlbi, LOGL_DEBUG, "Final ACK received\n");
ctx->rx_final_pkt_ul_ack_nack_has_tbf_est = tbf_est;
tbf_ul_fsm_state_chg(fi, GPRS_RLCMAC_TBF_UL_ST_RELEASING);
}
break;
}
case GPRS_RLCMAC_TBF_UL_EV_LAST_UL_DATA_SENT:
/* If LAST_UL_DATA_SENT is received in this state, it means the UL TBF is retransmitting the block. */
ctx->last_data_block_retrans_attempts++;

View File

@ -61,9 +61,9 @@ DLGLOBAL DEBUG - got ack for BSN=1
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) V(B): (V(A)=2)""(V(S)-1=1) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid
DLGLOBAL INFO UL_TBF{FINISHED}: Received Event RX_UL_ACK_NACK
DLGLOBAL INFO UL_TBF{FINISHED}: Contention resolution succeeded, stop T3166
DLGLOBAL DEBUG UL_TBF{FINISHED}: Final ACK received
DLGLOBAL INFO UL_TBF{FINISHED}: state_chg to RELEASING
DLGLOBAL DEBUG Register POLL (TS=7 FN=21, reason=UL_ACK)
DLGLOBAL DEBUG UL_TBF{FINISHED}: (ts=7,fn=8) Final ACK received
DLGLOBAL INFO UL_TBF{FINISHED}: state_chg to RELEASING
DLGLOBAL DEBUG Rx from lower layers: L1CTL-PDCH_RTS.indication
DLGLOBAL DEBUG Rx RTS.ind (fn=21, ts=7, usf=0)
DLGLOBAL DEBUG (ts=7,fn=21,usf=0) Tx Pkt Control Ack (UL ACK/NACK poll)
@ -933,9 +933,9 @@ DLGLOBAL DEBUG - got ack for BSN=0
DLGLOBAL DEBUG TBF(UL:NR-0:TLLI-00002342) V(B): (V(A)=1)""(V(S)-1=0) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid
DLGLOBAL INFO UL_TBF{FINISHED}: Received Event RX_UL_ACK_NACK
DLGLOBAL INFO UL_TBF{FINISHED}: Contention resolution succeeded, stop T3166
DLGLOBAL DEBUG UL_TBF{FINISHED}: Final ACK received
DLGLOBAL INFO UL_TBF{FINISHED}: state_chg to RELEASING
DLGLOBAL DEBUG Register POLL (TS=7 FN=17, reason=UL_ACK)
DLGLOBAL DEBUG UL_TBF{FINISHED}: (ts=7,fn=4) Final ACK received
DLGLOBAL INFO UL_TBF{FINISHED}: state_chg to RELEASING
DLGLOBAL INFO Rx from upper layers: GRR-UNITDATA.request
DLGLOBAL DEBUG GRE(00002342) Enqueueing LLC-PDU len=14 SAPI=GMM radio_prio=1
DLGLOBAL DEBUG Rx from lower layers: L1CTL-PDCH_RTS.indication