pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/31352 )
Change subject: WIP: rlcmac: Implement N3104 ......................................................................
WIP: rlcmac: Implement N3104
TODO: Add unit test similar to test_ul_tbf_t3166_timeout but without advancing wall clock, sending lots of RTS
Change-Id: Ia8c35aad7a537ab76447187847f8cee8c379352c --- M include/osmocom/gprs/rlcmac/tbf_ul.h M include/osmocom/gprs/rlcmac/tbf_ul_fsm.h M src/rlcmac/tbf_ul.c M src/rlcmac/tbf_ul_fsm.c 4 files changed, 28 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-gprs refs/changes/52/31352/1
diff --git a/include/osmocom/gprs/rlcmac/tbf_ul.h b/include/osmocom/gprs/rlcmac/tbf_ul.h index f1b7128..c187938 100644 --- a/include/osmocom/gprs/rlcmac/tbf_ul.h +++ b/include/osmocom/gprs/rlcmac/tbf_ul.h @@ -46,7 +46,7 @@ void gprs_rlcmac_ul_tbf_free(struct gprs_rlcmac_ul_tbf *ul_tbf);
bool gprs_rlcmac_ul_tbf_in_contention_resolution(const struct gprs_rlcmac_ul_tbf *ul_tbf); - +unsigned int gprs_rlcmac_ul_tbf_n3104_max(const struct gprs_rlcmac_ul_tbf *ul_tbf); bool gprs_rlcmac_ul_tbf_data_rts(const struct gprs_rlcmac_ul_tbf *ul_tbf, const struct gprs_rlcmac_rts_block_ind *bi); bool gprs_rlcmac_ul_tbf_dummy_rts(const struct gprs_rlcmac_ul_tbf *ul_tbf, const struct gprs_rlcmac_rts_block_ind *bi);
diff --git a/include/osmocom/gprs/rlcmac/tbf_ul_fsm.h b/include/osmocom/gprs/rlcmac/tbf_ul_fsm.h index 6957992..8cadf69 100644 --- a/include/osmocom/gprs/rlcmac/tbf_ul_fsm.h +++ b/include/osmocom/gprs/rlcmac/tbf_ul_fsm.h @@ -28,6 +28,7 @@ GPRS_RLCMAC_TBF_UL_EV_UL_ASS_START, GPRS_RLCMAC_TBF_UL_EV_UL_ASS_COMPL, GPRS_RLCMAC_TBF_UL_EV_FIRST_UL_DATA_SENT, + GPRS_RLCMAC_TBF_UL_EV_N3104_MAX, GPRS_RLCMAC_TBF_UL_EV_CONTENTION_RESOLUTION_SUCCESS, GPRS_RLCMAC_TBF_UL_EV_LAST_UL_DATA_SENT, GPRS_RLCMAC_TBF_UL_EV_FINAL_ACK_RECVD, diff --git a/src/rlcmac/tbf_ul.c b/src/rlcmac/tbf_ul.c index 993f694..0569724 100644 --- a/src/rlcmac/tbf_ul.c +++ b/src/rlcmac/tbf_ul.c @@ -112,6 +112,16 @@ } }
+unsigned int gprs_rlcmac_ul_tbf_n3104_max(const struct gprs_rlcmac_ul_tbf *ul_tbf) +{ + /* 3GPP TS 44.060 13.3: + * N3104_MAX = 3 * (BS_CV_MAX + 3) * number of uplink timeslots assigned */ + /* If we didn't receive SI13 yet, use maximum value bs_cv_max in range 0..15 */ + uint8_t bs_cv_max = g_ctx->si13_available ? + g_ctx->si13_ro_decoded.cell_opts.bs_cv_max : 15; + return 3 * (bs_cv_max + 3) * ul_tbf->cur_alloc.num_ts; +} + /* Used by the scheduler to find out whether an Uplink Dummy Control Block can be transmitted. If * true, it will potentially call gprs_rlcmac_ul_tbf_dummy_create() to generate a new dummy message to transmit. */ bool gprs_rlcmac_ul_tbf_dummy_rts(const struct gprs_rlcmac_ul_tbf *ul_tbf, const struct gprs_rlcmac_rts_block_ind *bi) @@ -789,6 +799,13 @@ if (ul_tbf->n3104 == 0) osmo_fsm_inst_dispatch(ul_tbf->state_fsm.fi, GPRS_RLCMAC_TBF_UL_EV_FIRST_UL_DATA_SENT, NULL); ul_tbf->n3104++; + if (gprs_rlcmac_ul_tbf_in_contention_resolution(ul_tbf)) { + unsigned int n3104_max = gprs_rlcmac_ul_tbf_n3104_max(ul_tbf); + if (ul_tbf->n3104 >= n3104_max) { + LOGPTBFUL(ul_tbf, LOGL_NOTICE, "N3104_MAX (%u) reached\n", n3104_max); + osmo_fsm_inst_dispatch(ul_tbf->state_fsm.fi, GPRS_RLCMAC_TBF_UL_EV_N3104_MAX, NULL); + } + } return msg; }
diff --git a/src/rlcmac/tbf_ul_fsm.c b/src/rlcmac/tbf_ul_fsm.c index 19d352d..a84859d 100644 --- a/src/rlcmac/tbf_ul_fsm.c +++ b/src/rlcmac/tbf_ul_fsm.c @@ -34,6 +34,7 @@ { GPRS_RLCMAC_TBF_UL_EV_UL_ASS_START, "UL_ASS_START" }, { GPRS_RLCMAC_TBF_UL_EV_UL_ASS_COMPL, "UL_ASS_COMPL" }, { GPRS_RLCMAC_TBF_UL_EV_FIRST_UL_DATA_SENT, "FIRST_UL_DATA_SENT" }, + { GPRS_RLCMAC_TBF_UL_EV_N3104_MAX, "N3104_MAX" }, { GPRS_RLCMAC_TBF_UL_EV_CONTENTION_RESOLUTION_SUCCESS, "CONTENTION_RESOLUTION_SUCCESS" }, { GPRS_RLCMAC_TBF_UL_EV_LAST_UL_DATA_SENT, "LAST_UL_DATA_SENT" }, { GPRS_RLCMAC_TBF_UL_EV_FINAL_ACK_RECVD, "FINAL_ACK_RECVD" }, @@ -149,6 +150,9 @@ osmo_timer_schedule(&fi->timer, val_sec, 0); } break; + case GPRS_RLCMAC_TBF_UL_EV_N3104_MAX: + reinit_pkt_acces_procedure(ctx); + break; case GPRS_RLCMAC_TBF_UL_EV_CONTENTION_RESOLUTION_SUCCESS: LOGPFSML(ctx->fi, LOGL_INFO, "Contention resolution succeeded, stop T3166\n"); OSMO_ASSERT(ctx->ul_tbf->ul_ass_fsm.ass_type == GPRS_RLCMAC_TBF_UL_ASS_TYPE_1PHASE); @@ -168,6 +172,9 @@ { struct gprs_rlcmac_tbf_ul_fsm_ctx *ctx = (struct gprs_rlcmac_tbf_ul_fsm_ctx *)fi->priv; switch (event) { + case GPRS_RLCMAC_TBF_UL_EV_N3104_MAX: + reinit_pkt_acces_procedure(ctx); + break; case GPRS_RLCMAC_TBF_UL_EV_CONTENTION_RESOLUTION_SUCCESS: LOGPFSML(ctx->fi, LOGL_INFO, "Contention resolution succeeded, stop T3166\n"); OSMO_ASSERT(ctx->ul_tbf->ul_ass_fsm.ass_type == GPRS_RLCMAC_TBF_UL_ASS_TYPE_1PHASE); @@ -204,6 +211,7 @@ [GPRS_RLCMAC_TBF_UL_ST_FLOW] = { .in_event_mask = X(GPRS_RLCMAC_TBF_UL_EV_FIRST_UL_DATA_SENT) | + X(GPRS_RLCMAC_TBF_UL_EV_N3104_MAX) | X(GPRS_RLCMAC_TBF_UL_EV_CONTENTION_RESOLUTION_SUCCESS) | X(GPRS_RLCMAC_TBF_UL_EV_LAST_UL_DATA_SENT), .out_state_mask = @@ -214,6 +222,7 @@ }, [GPRS_RLCMAC_TBF_UL_ST_FINISHED] = { .in_event_mask = + X(GPRS_RLCMAC_TBF_UL_EV_N3104_MAX) | X(GPRS_RLCMAC_TBF_UL_EV_CONTENTION_RESOLUTION_SUCCESS) | X(GPRS_RLCMAC_TBF_UL_EV_FINAL_ACK_RECVD), .out_state_mask =