diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-07-04 16:46:36 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-07-05 13:49:20 +0200 |
commit | cabca879215f45a770255b2ef2bba63902cec408 (patch) | |
tree | 5dbfb3c9aaa9b160f6509bce0fe8f44f0482c55f | |
parent | 5dc23ea408c7066fe235240d2e3e69444e9082e9 (diff) |
rlcmac: tbf_dl: Implement T3192
Related: OS#5500
Change-Id: I49c9068d1819d6189103908f6f92ce05952b74e6
-rw-r--r-- | include/osmocom/gprs/rlcmac/tbf_dl.h | 1 | ||||
-rw-r--r-- | src/rlcmac/rlcmac.c | 26 | ||||
-rw-r--r-- | src/rlcmac/tbf_dl.c | 33 | ||||
-rw-r--r-- | src/rlcmac/tbf_dl_fsm.c | 2 | ||||
-rw-r--r-- | tests/rlcmac/rlcmac_prim_test.err | 2 |
5 files changed, 58 insertions, 6 deletions
diff --git a/include/osmocom/gprs/rlcmac/tbf_dl.h b/include/osmocom/gprs/rlcmac/tbf_dl.h index 7fb3c9e..104b6e6 100644 --- a/include/osmocom/gprs/rlcmac/tbf_dl.h +++ b/include/osmocom/gprs/rlcmac/tbf_dl.h @@ -35,6 +35,7 @@ struct gprs_rlcmac_dl_tbf { }; struct osmo_timer_list t3190; + struct osmo_timer_list t3192; }; struct gprs_rlcmac_dl_tbf *gprs_rlcmac_dl_tbf_alloc(struct gprs_rlcmac_entity *gre); diff --git a/src/rlcmac/rlcmac.c b/src/rlcmac/rlcmac.c index f9281fb..f35c04d 100644 --- a/src/rlcmac/rlcmac.c +++ b/src/rlcmac/rlcmac.c @@ -50,6 +50,7 @@ static struct osmo_tdef T_defs_rlcmac[] = { { .T=3168, .default_val=5000, .unit = OSMO_TDEF_MS, .desc="Wait for PACKET UPLINK ASSIGNMENT (updated by BCCH SI13) (ms)" }, { .T=3182, .default_val=5, .unit = OSMO_TDEF_S, .desc="Wait for Acknowledgement (s)" }, { .T=3190, .default_val=5, .unit = OSMO_TDEF_S, .desc="Wait for Valid Downlink Data Received from the Network (s)" }, + { .T=3192, .default_val=0, .unit = OSMO_TDEF_MS, .desc="Wait for release of the TBF after reception of the final block (ms)" }, { 0 } /* empty item at the end */ }; @@ -571,9 +572,18 @@ int gprs_rlcmac_handle_ccch_pag_req2(const struct gsm48_paging2 *pag) return rc; } +/* Decode T3192. 3GPP TS 44.060 Table 12.24.2: GPRS Cell Options information element details */ +static unsigned int gprs_rlcmac_decode_t3192(unsigned int t3192_encoded) +{ + static const unsigned int decode_t3192_tbl[8] = {500, 1000, 1500, 0, 80, 120, 160, 200}; + OSMO_ASSERT(t3192_encoded <= 7); + return decode_t3192_tbl[t3192_encoded]; +} + int gprs_rlcmac_handle_bcch_si13(const struct gsm48_system_information_type_13 *si13) { int rc; + unsigned int t3192; LOGRLCMAC(LOGL_DEBUG, "Rx SI13 from lower layers\n"); memcpy(g_rlcmac_ctx->si13, si13, GSM_MACBLOCK_LEN); @@ -594,9 +604,9 @@ int gprs_rlcmac_handle_bcch_si13(const struct gsm48_system_information_type_13 * (g_rlcmac_ctx->si13ro.u.PBCCH_Not_present.GPRS_Cell_Options.T3168 + 1) * 500, OSMO_TDEF_MS); - /* TODO: Update tdef for T3192 as per TS 44.060 Table 12.24.2 - * osmo_tdef_set(g_rlcmac_ctx->T_defs, 3192, si13ro.u.PBCCH_Not_present.GPRS_Cell_Options.T3192, enum osmo_tdef_unit val_unit); - */ + /* Update tdef for T3192 as per TS 44.060 Table 12.24.2 */ + t3192 = gprs_rlcmac_decode_t3192(g_rlcmac_ctx->si13ro.u.PBCCH_Not_present.GPRS_Cell_Options.T3192); + osmo_tdef_set(g_rlcmac_ctx->T_defs, 3192, t3192, OSMO_TDEF_MS); return rc; } @@ -674,6 +684,16 @@ static int gprs_rlcmac_handle_pkt_dl_ass(const struct osmo_gprs_rlcmac_prim *rlc GPRS_RLCMAC_PDCH_ULC_POLL_DL_ASS, gre); } + + /* 9.3.2.6 Release of downlink Temporary Block Flow: + * If the MS, [...] receives a PACKET DOWNLINK ASSIGNMENT with the Control Ack bit + * set to '1' [...] while its timer T3192 is running, the MS shall stop timer T3192, + * consider this downlink TBF released and act upon the new assignments. + */ + if (dlass->CONTROL_ACK && gre->dl_tbf) { + if (osmo_timer_pending(&gre->dl_tbf->t3192)) + gprs_rlcmac_dl_tbf_free(gre->dl_tbf); + } return rc; } diff --git a/src/rlcmac/tbf_dl.c b/src/rlcmac/tbf_dl.c index c6205c3..a7f0ea9 100644 --- a/src/rlcmac/tbf_dl.c +++ b/src/rlcmac/tbf_dl.c @@ -28,6 +28,7 @@ #include <osmocom/gprs/rlcmac/pdch_ul_controller.h> static void gprs_rlcmac_dl_tbf_t3190_timer_cb(void *data); +static void gprs_rlcmac_dl_tbf_t3192_timer_cb(void *data); struct gprs_rlcmac_dl_tbf *gprs_rlcmac_dl_tbf_alloc(struct gprs_rlcmac_entity *gre) { @@ -54,6 +55,7 @@ struct gprs_rlcmac_dl_tbf *gprs_rlcmac_dl_tbf_alloc(struct gprs_rlcmac_entity *g OSMO_ASSERT(dl_tbf->blkst); osmo_timer_setup(&dl_tbf->t3190, gprs_rlcmac_dl_tbf_t3190_timer_cb, dl_tbf); + osmo_timer_setup(&dl_tbf->t3192, gprs_rlcmac_dl_tbf_t3192_timer_cb, dl_tbf); return dl_tbf; @@ -75,6 +77,7 @@ void gprs_rlcmac_dl_tbf_free(struct gprs_rlcmac_dl_tbf *dl_tbf) gre = tbf->gre; osmo_timer_del(&dl_tbf->t3190); + osmo_timer_del(&dl_tbf->t3192); msgb_free(dl_tbf->llc_rx_msg); dl_tbf->llc_rx_msg = NULL; @@ -109,6 +112,29 @@ void gprs_rlcmac_dl_tbf_t3190_start(struct gprs_rlcmac_dl_tbf *dl_tbf) osmo_timer_schedule(&dl_tbf->t3190, val_sec, 0); } +/* This timer is used on the mobile station side when the mobile station has + * received all of the RLC data blocks. When timer T3192 expires the mobile station + * shall release the resources associated with the TBF (e.g. TFI) and begin to + * monitor its paging channel. */ +static void gprs_rlcmac_dl_tbf_t3192_timer_cb(void *data) +{ + struct gprs_rlcmac_dl_tbf *dl_tbf = data; + + LOGPTBFDL(dl_tbf, LOGL_INFO, "Timeout of T3192\n"); + + gprs_rlcmac_dl_tbf_free(dl_tbf); +} + +void gprs_rlcmac_dl_tbf_t3192_start(struct gprs_rlcmac_dl_tbf *dl_tbf) +{ + unsigned long val_msec; + val_msec = osmo_tdef_get(g_rlcmac_ctx->T_defs, 3192, OSMO_TDEF_MS, -1); + + LOGPTBFDL(dl_tbf, LOGL_INFO, "Starting T3192 (%lu ms)\n", val_msec); + OSMO_ASSERT(gprs_rlcmac_tbf_dl_state(dl_tbf) == GPRS_RLCMAC_TBF_DL_ST_FINISHED); + osmo_timer_schedule(&dl_tbf->t3192, val_msec / 1000, (val_msec % 1000) * 1000); +} + static uint8_t dl_tbf_dl_slotmask(struct gprs_rlcmac_dl_tbf *dl_tbf) { uint8_t dl_slotmask = 0; @@ -161,10 +187,11 @@ struct msgb *gprs_rlcmac_dl_tbf_create_pkt_dl_ack_nack(struct gprs_rlcmac_dl_tbf goto free_ret; } - /* Stop T3190 if transmitting final Downlink Ack/Nack */ - if (gprs_rlcmac_tbf_dl_state(dl_tbf) == GPRS_RLCMAC_TBF_DL_ST_FINISHED) + /* Transmitting final Downlink Ack/Nack: Stop T3190 (if still armed), re-arm T3192 */ + if (gprs_rlcmac_tbf_dl_state(dl_tbf) == GPRS_RLCMAC_TBF_DL_ST_FINISHED) { osmo_timer_del(&dl_tbf->t3190); - + gprs_rlcmac_dl_tbf_t3192_start(dl_tbf); + } return msg; free_ret: diff --git a/src/rlcmac/tbf_dl_fsm.c b/src/rlcmac/tbf_dl_fsm.c index 342256f..158b802 100644 --- a/src/rlcmac/tbf_dl_fsm.c +++ b/src/rlcmac/tbf_dl_fsm.c @@ -80,6 +80,8 @@ 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) { + /* Wait to be freed by T3190/T3192. */ + //struct gprs_rlcmac_tbf_dl_fsm_ctx *ctx = (struct gprs_rlcmac_tbf_dl_fsm_ctx *)fi->priv; switch (event) { case GPRS_RLCMAC_TBF_DL_EV_LAST_DL_DATA_RECVD: diff --git a/tests/rlcmac/rlcmac_prim_test.err b/tests/rlcmac/rlcmac_prim_test.err index 087e371..c6a7a73 100644 --- a/tests/rlcmac/rlcmac_prim_test.err +++ b/tests/rlcmac/rlcmac_prim_test.err @@ -911,6 +911,7 @@ DLGLOBAL DEBUG Register POLL (TS=7 FN=21, reason=DL_ACK) DLGLOBAL DEBUG Rx from lower layers: L1CTL-PDCH_RTS.indication DLGLOBAL DEBUG (ts=7,fn=21,usf=0) Tx DL ACK/NACK FinalAck=1 DLGLOBAL DEBUG TBF(DL:NR-0:TLLI-00000001) - V(N): "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR" R=Received I=Invalid +DLGLOBAL INFO TBF(DL:NR-0:TLLI-00000001) Starting T3192 (0 ms) DLGLOBAL DEBUG Tx to lower layers: L1CTL-PDCH_DATA.request DLGLOBAL INFO DL_TBF_ASS{IDLE}: Deallocated DLGLOBAL INFO DL_TBF{FINISHED}: Deallocated @@ -955,6 +956,7 @@ DLGLOBAL INFO UL_TBF_ASS{IDLE}: Received Event START_FROM_DL_TBF DLGLOBAL INFO UL_TBF{NEW}: Received Event UL_ASS_START DLGLOBAL INFO UL_TBF{NEW}: state_chg to ASSIGN DLGLOBAL INFO UL_TBF_ASS{IDLE}: state_chg to WAIT_PKT_UL_ASS +DLGLOBAL INFO TBF(DL:NR-0:TLLI-00000001) Starting T3192 (0 ms) DLGLOBAL DEBUG Tx to lower layers: L1CTL-PDCH_DATA.request DLGLOBAL DEBUG Rx from lower layers: L1CTL-PDCH_DATA.indication DLGLOBAL INFO TS=7 FN=26 Rx Pkt UL ASS |