fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/33223 )
Change subject: [WIP] l1gprs: implement TBF starting time support ......................................................................
[WIP] l1gprs: implement TBF starting time support
Change-Id: I174e3c43d2f4c828a528710b284e62c9bb794122 Related: OS#5500 --- M include/l1gprs.h M src/shared/l1gprs.c 2 files changed, 65 insertions(+), 12 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/23/33223/1
diff --git a/include/l1gprs.h b/include/l1gprs.h index bbd654d..82c05d0 100644 --- a/include/l1gprs.h +++ b/include/l1gprs.h @@ -17,6 +17,8 @@ uint8_t tbf_ref; /*! PDCH timeslots used by this TBF */ uint8_t slotmask; + /*! TBF starting time (absolute TDMA Fn) */ + uint8_t start_fn; /*! (Downlink only) DL TFI (Temporary Flow Indentity): 0..31 */ uint8_t dl_tfi; }; @@ -37,8 +39,10 @@ struct l1gprs_state { /*! PDCH state for each timeslot */ struct l1gprs_pdch pdch[8]; - /*! Uplink and Downlink TBFs */ + /*! Uplink and Downlink TBFs (active) */ struct llist_head tbf_list; + /*! Uplink and Downlink TBFs (pending) */ + struct llist_head tbf_list_pending; /*! Logging context (used as prefix for messages) */ char *log_prefix; /*! Some private data for API user */ diff --git a/src/shared/l1gprs.c b/src/shared/l1gprs.c index fd18e4e..15d16ca 100644 --- a/src/shared/l1gprs.c +++ b/src/shared/l1gprs.c @@ -43,6 +43,10 @@ LOGP_GPRS((pdch)->gprs, level, "(PDCH-%u) " fmt, \ (pdch)->tn, ## args)
+#define LOG_TBF_CFG_REQ_FMT "tbf_ref=%u, slotmask=0x%02x, start_fn=%u" +#define LOG_TBF_CFG_REQ_ARGS(req) \ + (req)->tbf_ref, (req)->slotmask, ntohl((req)->start_fn) + #define LOG_TBF_FMT "%cL-TBF#%03d" #define LOG_TBF_ARGS(tbf) \ (tbf)->uplink ? 'U' : 'D', tbf->tbf_ref @@ -58,7 +62,7 @@
static struct l1gprs_tbf *l1gprs_tbf_alloc(struct l1gprs_state *gprs, bool uplink, uint8_t tbf_ref, - uint8_t slotmask) + uint8_t slotmask, uint32_t start_fn) { struct l1gprs_tbf *tbf;
@@ -68,6 +72,7 @@ tbf->uplink = uplink; tbf->tbf_ref = tbf_ref; tbf->slotmask = slotmask; + tbf->start_fn = start_fn;
return tbf; } @@ -80,12 +85,12 @@ talloc_free(tbf); }
-static struct l1gprs_tbf *l1gprs_find_tbf(struct l1gprs_state *gprs, +static struct l1gprs_tbf *l1gprs_find_tbf(const struct llist_head *tbf_list, bool uplink, uint8_t tbf_ref) { struct l1gprs_tbf *tbf;
- llist_for_each_entry(tbf, &gprs->tbf_list, list) { + llist_for_each_entry(tbf, tbf_list, list) { if (tbf->uplink != uplink) continue; if (tbf->tbf_ref != tbf_ref) @@ -101,6 +106,16 @@ { OSMO_ASSERT(tbf->slotmask != 0x00);
+ /* TBFs with specific starting time go to pending list */ + if (tbf->start_fn != 0xffffffff) { + llist_add_tail(&tbf->list, &gprs->tbf_list_pending); + + LOGP_GPRS(gprs, LOGL_INFO, + LOG_TBF_FMT " is registered as pending (fn=%u)\n", + LOG_TBF_ARGS(tbf), tbf->start_fn); + return; + } + /* Update the PDCH states */ for (unsigned int tn = 0; tn < ARRAY_SIZE(gprs->pdch); tn++) { struct l1gprs_pdch *pdch = &gprs->pdch[tn]; @@ -123,7 +138,7 @@ llist_add_tail(&tbf->list, &gprs->tbf_list);
LOGP_GPRS(gprs, LOGL_INFO, - LOG_TBF_FMT " is registered\n", + LOG_TBF_FMT " is registered as active\n", LOG_TBF_ARGS(tbf)); }
@@ -132,7 +147,9 @@ { struct l1gprs_tbf *tbf;
- tbf = l1gprs_find_tbf(gprs, uplink, tbf_ref); + tbf = l1gprs_find_tbf(&gprs->tbf_list, uplink, tbf_ref); + if (tbf == NULL) + tbf = l1gprs_find_tbf(&gprs->tbf_list_pending, uplink, tbf_ref); if (tbf == NULL) { LOGP_GPRS(gprs, LOGL_ERROR, "%s(): " LOG_TBF_FMT " not found\n", @@ -168,6 +185,24 @@ l1gprs_tbf_free(tbf); }
+/* Check the list of pending TBFs and move those with expired Fn to the active list */ +static void l1gprs_check_pending_tbfs(struct l1gprs_state *gprs, uint32_t fn) +{ + struct l1gprs_tbf *tbf, *tmp; + + llist_for_each_entry_safe(tbf, tmp, &gprs->tbf_list_pending, list) { + if (tbf->start_fn < fn) /* XXX: see 3GPP TS 44.018 section 10.5.2.38 */ + continue; + + LOGP_GPRS(gprs, LOGL_INFO, + LOG_TBF_FMT " becomes active\n", + LOG_TBF_ARGS(tbf)); + + tbf->start_fn = fn; + l1gprs_register_tbf(gprs, tbf); + } +} + #define L1GPRS_L1CTL_MSGB_SIZE 256 #define L1GPRS_L1CTL_MSGB_HEADROOM 32
@@ -286,11 +321,12 @@ }
LOGP_GPRS(gprs, LOGL_INFO, - "Rx Uplink TBF config: tbf_ref=%u, slotmask=0x%02x\n", - req->tbf_ref, req->slotmask); + "Rx UL TBF config: " LOG_TBF_CFG_REQ_FMT "\n", + LOG_TBF_CFG_REQ_ARGS(req));
if (req->slotmask != 0x00) { - tbf = l1gprs_tbf_alloc(gprs, true, req->tbf_ref, req->slotmask); + tbf = l1gprs_tbf_alloc(gprs, true, req->tbf_ref, + req->slotmask, ntohl(req->start_fn)); l1gprs_register_tbf(gprs, tbf); } else { l1gprs_unregister_tbf(gprs, true, req->tbf_ref); @@ -314,8 +350,8 @@ }
LOGP_GPRS(gprs, LOGL_INFO, - "Rx Downlink TBF config: tbf_ref=%u, slotmask=0x%02x, dl_tfi=%u\n", - req->tbf_ref, req->slotmask, req->dl_tfi); + "Rx DL TBF config: " LOG_TBF_CFG_REQ_FMT ", dl_tfi=%u\n", + LOG_TBF_CFG_REQ_ARGS(req), req->dl_tfi);
if (req->dl_tfi > 31) { LOGP_GPRS(gprs, LOGL_ERROR, @@ -325,7 +361,8 @@ }
if (req->slotmask != 0x00) { - tbf = l1gprs_tbf_alloc(gprs, false, req->tbf_ref, req->slotmask); + tbf = l1gprs_tbf_alloc(gprs, false, req->tbf_ref, + req->slotmask, ntohl(req->start_fn)); tbf->dl_tfi = req->dl_tfi; l1gprs_register_tbf(gprs, tbf); } else { @@ -409,6 +446,8 @@ BLOCK_IND_IS_PTCCH(ind) ? "PTCCH" : "PDTCH", ind->hdr.fn, ind->data_len, osmo_hexdump(ind->data, ind->data_len));
+ l1gprs_check_pending_tbfs(gprs, ind->hdr.fn); + if ((pdch->ul_tbf_count == 0) && (pdch->dl_tbf_count == 0)) { LOGP_PDCH(pdch, LOGL_ERROR, "Rx DL BLOCK.ind, but this PDCH has no configured TBFs\n");