aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2023-07-04 16:46:36 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2023-07-05 13:49:20 +0200
commitcabca879215f45a770255b2ef2bba63902cec408 (patch)
tree5dbfb3c9aaa9b160f6509bce0fe8f44f0482c55f
parent5dc23ea408c7066fe235240d2e3e69444e9082e9 (diff)
rlcmac: tbf_dl: Implement T3192
-rw-r--r--include/osmocom/gprs/rlcmac/tbf_dl.h1
-rw-r--r--src/rlcmac/rlcmac.c26
-rw-r--r--src/rlcmac/tbf_dl.c33
-rw-r--r--src/rlcmac/tbf_dl_fsm.c2
-rw-r--r--tests/rlcmac/rlcmac_prim_test.err2
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