fixeria has uploaded this change for review.

View Change

[WIP] l1gprs: implement queueing of Uplink blocks

Change-Id: If9638a670f97f602c922ea8d3375674d03c15f53
Related: OS#5500
---
M include/l1ctl_proto.h
M include/l1gprs.h
M src/host/layer23/include/osmocom/bb/common/l1ctl.h
M src/host/layer23/src/common/l1ctl.c
M src/host/layer23/src/modem/rlcmac.c
M src/host/trxcon/src/l1ctl.c
M src/host/trxcon/src/trxcon_fsm.c
M src/host/virt_phy/src/virt_prim_pdch.c
M src/shared/l1gprs.c
9 files changed, 187 insertions(+), 100 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/04/32504/1
diff --git a/include/l1ctl_proto.h b/include/l1ctl_proto.h
index 3512424..b1f59f9 100644
--- a/include/l1ctl_proto.h
+++ b/include/l1ctl_proto.h
@@ -345,19 +345,15 @@
uint8_t data[0];
} __attribute__((packed));

-/* payload of L1CTL_GPRS_UL_TBF_CFG_REQ */
-struct l1ctl_gprs_ul_tbf_cfg_req {
+/* payload of L1CTL_GPRS_{UL,DL}_TBF_CFG_REQ */
+struct l1ctl_gprs_tbf_cfg_req {
uint8_t tbf_ref;
uint8_t slotmask;
uint8_t padding[2];
-} __attribute__((packed));
-
-/* payload of L1CTL_GPRS_DL_TBF_CFG_REQ */
-struct l1ctl_gprs_dl_tbf_cfg_req {
- uint8_t tbf_ref;
- uint8_t slotmask;
- uint8_t dl_tfi;
- uint8_t padding[1];
+ union {
+ uint8_t ul_usf[8];
+ uint8_t dl_tfi;
+ } __attribute__((packed));
} __attribute__((packed));

/* part of L1CTL_GPRS_{UL,DL}_BLOCK_{REQ,IND} */
@@ -370,6 +366,7 @@
/* payload of L1CTL_GPRS_UL_BLOCK_REQ */
struct l1ctl_gprs_ul_block_req {
struct l1ctl_gprs_block_hdr hdr;
+ uint8_t tbf_ref;
uint8_t data[0];
} __attribute__((packed));

diff --git a/include/l1gprs.h b/include/l1gprs.h
index bbd654d..f7f49c2 100644
--- a/include/l1gprs.h
+++ b/include/l1gprs.h
@@ -4,6 +4,13 @@
#include <stdbool.h>

#include <osmocom/core/linuxlist.h>
+#include <osmocom/gsm/gsm0502.h>
+
+/* Calculate TDMA Fn of the next block from TDMA Fn of the current block.
+ * Every fn % 13 == 12 we have either a PTCCH or an IDLE slot, thus
+ * every fn % 13 == 8 we add 5 frames, or 4 frames othrwise. */
+#define L1GPRS_NEXT_BLOCK_FN(fn) \
+ GSM_TDMA_FN_SUM(fn, (fn % 13 == 8) ? 5 : 4)

struct l1gprs_state;
struct msgb;
@@ -17,8 +24,13 @@
uint8_t tbf_ref;
/*! PDCH timeslots used by this TBF */
uint8_t slotmask;
- /*! (Downlink only) DL TFI (Temporary Flow Indentity): 0..31 */
- uint8_t dl_tfi;
+ /*! UL/DL specific parameters */
+ union {
+ /*! USF for each PDCH indicated in the slotmask */
+ uint8_t ul_usf[8];
+ /*! DL TFI for all PDCHs indicated in the slotmask */
+ uint8_t dl_tfi;
+ };
};

struct l1gprs_pdch {
@@ -32,6 +44,12 @@
uint8_t dl_tbf_count;
/*! DL TFI mask */
uint32_t dl_tfi_mask;
+ /*! last USF received on this PDCH */
+ uint8_t last_usf;
+ /*! Tx block queue: blocks sent whenever USF matches */
+ struct llist_head tx_queue_usf;
+ /*! Tx block queue: blocks with TDMA Fn, sorted */
+ struct llist_head tx_queue_abs;
};

struct l1gprs_state {
@@ -74,8 +92,7 @@
const uint8_t *data;
};

-int l1gprs_handle_ul_block_req(struct l1gprs_state *gprs,
- struct l1gprs_prim_ul_block_req *req,
- const struct msgb *msg);
+int l1gprs_handle_ul_block_req(struct l1gprs_state *gprs, struct msgb *msg);
struct msgb *l1gprs_handle_dl_block_ind(struct l1gprs_state *gprs,
const struct l1gprs_prim_dl_block_ind *ind);
+struct msgb *l1gprs_pull_ul_block(struct l1gprs_state *gprs, uint32_t fn, uint8_t tn);
diff --git a/src/host/layer23/include/osmocom/bb/common/l1ctl.h b/src/host/layer23/include/osmocom/bb/common/l1ctl.h
index 25bc6e8..2ad19e7 100644
--- a/src/host/layer23/include/osmocom/bb/common/l1ctl.h
+++ b/src/host/layer23/include/osmocom/bb/common/l1ctl.h
@@ -81,7 +81,7 @@

/* Transmit L1CTL_GPRS_UL_TBF_CFG_REQ */
int l1ctl_tx_gprs_ul_tbf_cfg_req(struct osmocom_ms *ms, uint8_t tbf_ref,
- uint8_t slotmask);
+ uint8_t slotmask, const uint8_t usf[8]);

/* Transmit L1CTL_GPRS_DL_TBF_CFG_REQ */
int l1ctl_tx_gprs_dl_tbf_cfg_req(struct osmocom_ms *ms, uint8_t tbf_ref,
diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c
index 8e55b7b..affb80d 100644
--- a/src/host/layer23/src/common/l1ctl.c
+++ b/src/host/layer23/src/common/l1ctl.c
@@ -1009,34 +1009,11 @@
return 0;
}

-/* Transmit L1CTL_GPRS_UL_BLOCK_REQ */
-int l1ctl_tx_gprs_ul_block_req(struct osmocom_ms *ms, uint32_t fn, uint8_t tn,
- const uint8_t *data, size_t data_len)
-{
- struct l1ctl_gprs_ul_block_req *req;
- struct msgb *msg;
-
- msg = osmo_l1_alloc(L1CTL_GPRS_UL_BLOCK_REQ);
- if (!msg)
- return -ENOMEM;
-
- req = (void *)msgb_put(msg, sizeof(*req));
- req->hdr.fn = htonl(fn);
- req->hdr.tn = tn;
- if (data_len > 0)
- memcpy(msgb_put(msg, data_len), data, data_len);
-
- DEBUGP(DL1C, "Tx GPRS UL block (fn=%u, tn=%u, len=%zu): %s\n",
- fn, tn, data_len, osmo_hexdump(data, data_len));
-
- return osmo_send_l1(ms, msg);
-}
-
/* Transmit L1CTL_GPRS_UL_TBF_CFG_REQ */
int l1ctl_tx_gprs_ul_tbf_cfg_req(struct osmocom_ms *ms, uint8_t tbf_ref,
- uint8_t slotmask)
+ uint8_t slotmask, const uint8_t usf[8])
{
- struct l1ctl_gprs_ul_tbf_cfg_req *req;
+ struct l1ctl_gprs_tbf_cfg_req *req;
struct msgb *msg;

msg = osmo_l1_alloc(L1CTL_GPRS_UL_TBF_CFG_REQ);
@@ -1044,13 +1021,12 @@
return -ENOMEM;

req = (void *)msgb_put(msg, sizeof(*req));
- *req = (struct l1ctl_gprs_ul_tbf_cfg_req) {
- .tbf_ref = tbf_ref,
- .slotmask = slotmask,
- };
+ req->tbf_ref = tbf_ref;
+ req->slotmask = slotmask;
+ memcpy(&req->ul_usf[0], &usf[0], sizeof(req->ul_usf));

- DEBUGP(DL1C, "Tx GPRS UL TBF CFG (tbf_ref=%u, slotmask=0x%02x)\n",
- tbf_ref, slotmask);
+ DEBUGP(DL1C, "Tx GPRS UL TBF CFG (tbf_ref=%u, slotmask=0x%02x): %s\n",
+ tbf_ref, slotmask, osmo_hexdump(&req->ul_usf[0], sizeof(req->ul_usf)));

return osmo_send_l1(ms, msg);
}
@@ -1059,7 +1035,7 @@
int l1ctl_tx_gprs_dl_tbf_cfg_req(struct osmocom_ms *ms, uint8_t tbf_ref,
uint8_t slotmask, uint8_t dl_tfi)
{
- struct l1ctl_gprs_dl_tbf_cfg_req *req;
+ struct l1ctl_gprs_tbf_cfg_req *req;
struct msgb *msg;

msg = osmo_l1_alloc(L1CTL_GPRS_DL_TBF_CFG_REQ);
@@ -1067,11 +1043,9 @@
return -ENOMEM;

req = (void *)msgb_put(msg, sizeof(*req));
- *req = (struct l1ctl_gprs_dl_tbf_cfg_req) {
- .tbf_ref = tbf_ref,
- .slotmask = slotmask,
- .dl_tfi = dl_tfi,
- };
+ req->tbf_ref = tbf_ref;
+ req->slotmask = slotmask;
+ req->dl_tfi = dl_tfi;

DEBUGP(DL1C, "Tx GPRS DL TBF CFG (tbf_ref=%u, slotmask=0x%02x, dl_tfi=%u)\n",
tbf_ref, slotmask, dl_tfi);
diff --git a/src/host/layer23/src/modem/rlcmac.c b/src/host/layer23/src/modem/rlcmac.c
index deb366a..68d3c43 100644
--- a/src/host/layer23/src/modem/rlcmac.c
+++ b/src/host/layer23/src/modem/rlcmac.c
@@ -143,6 +143,7 @@
return modem_grr_tx_chan_req(ms, lp->rach_req.ra);
case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_PDCH_DATA, PRIM_OP_REQUEST):
return l1ctl_tx_gprs_ul_block_req(ms,
+ 0, /* XXX: lp->pdch_data_req.tbf_ref, */
lp->pdch_data_req.fn,
lp->pdch_data_req.ts_nr,
lp->pdch_data_req.data,
@@ -150,7 +151,8 @@
case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_CFG_UL_TBF, PRIM_OP_REQUEST):
return l1ctl_tx_gprs_ul_tbf_cfg_req(ms,
lp->cfg_ul_tbf_req.ul_tbf_nr,
- lp->cfg_ul_tbf_req.ul_slotmask);
+ lp->cfg_ul_tbf_req.ul_slotmask,
+ lp->cfg_ul_tbf_req.ul_usf);
case OSMO_PRIM(OSMO_GPRS_RLCMAC_L1CTL_CFG_DL_TBF, PRIM_OP_REQUEST):
return l1ctl_tx_gprs_dl_tbf_cfg_req(ms,
lp->cfg_dl_tbf_req.dl_tbf_nr,
diff --git a/src/host/trxcon/src/l1ctl.c b/src/host/trxcon/src/l1ctl.c
index a45bc2c..5ddb5b2 100644
--- a/src/host/trxcon/src/l1ctl.c
+++ b/src/host/trxcon/src/l1ctl.c
@@ -828,8 +828,10 @@
msgb_free(msg);
return rc;
case L1CTL_GPRS_UL_BLOCK_REQ:
+ /* pass ownership of the msgb to trxcon_fsm/l1gprs */
rc = osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_GPRS_UL_BLOCK_REQ, msg);
- msgb_free(msg);
+ if (rc != 0)
+ msgb_free(msg);
return rc;
/* Not (yet) handled messages */
case L1CTL_NEIGH_PM_REQ:
diff --git a/src/host/trxcon/src/trxcon_fsm.c b/src/host/trxcon/src/trxcon_fsm.c
index 219f0c0..83f971a 100644
--- a/src/host/trxcon/src/trxcon_fsm.c
+++ b/src/host/trxcon/src/trxcon_fsm.c
@@ -29,7 +29,6 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/logging.h>
#include <osmocom/gsm/gsm0502.h>
-#include <osmocom/gsm/protocol/gsm_08_58.h>

#include <osmocom/bb/trxcon/trxcon.h>
#include <osmocom/bb/trxcon/trxcon_fsm.h>
@@ -556,31 +555,17 @@
break;
case TRXCON_EV_GPRS_UL_BLOCK_REQ:
{
- struct l1gprs_prim_ul_block_req block_req;
- struct l1sched_prim *prim;
struct msgb *msg = data;

- if (l1gprs_handle_ul_block_req(trxcon->gprs, &block_req, msg) != 0)
- return;
-
- msg = l1sched_prim_alloc(L1SCHED_PRIM_T_DATA, PRIM_OP_REQUEST, block_req.data_len);
- OSMO_ASSERT(msg != NULL);
-
- prim = l1sched_prim_from_msgb(msg);
- prim->data_req = (struct l1sched_prim_chdr) {
- .frame_nr = block_req.hdr.fn,
- .chan_nr = RSL_CHAN_OSMO_PDCH | block_req.hdr.tn,
- .link_id = 0x00,
- };
-
- memcpy(msgb_put(msg, block_req.data_len), block_req.data, block_req.data_len);
- l1sched_prim_from_user(trxcon->sched, msg);
+ if (l1gprs_handle_ul_block_req(trxcon->gprs, msg) != 0)
+ msgb_free(msg);
break;
}
case TRXCON_EV_RX_DATA_IND:
{
const struct trxcon_param_rx_data_ind *ind = data;
struct l1gprs_prim_dl_block_ind block_ind;
+ struct l1sched_prim *prim;
struct msgb *msg;

block_ind = (struct l1gprs_prim_dl_block_ind) {
@@ -602,9 +587,27 @@
else
block_ind.meas.ber10k = 10000 * ind->n_errors / ind->n_bits_total;

+ /* feed l1gprs with the received data */
msg = l1gprs_handle_dl_block_ind(trxcon->gprs, &block_ind);
- if (msg != NULL)
+ if (msg != NULL) /* pass ownership of msgb to l1ctl */
trxcon_l1ctl_send(trxcon, msg);
+
+ /* pull an Uplink block from l1gprs */
+ const uint32_t next_block_fn = L1GPRS_NEXT_BLOCK_FN(ind->frame_nr);
+ msg = l1gprs_pull_ul_block(trxcon->gprs, next_block_fn, ind->chan_nr & 0x07);
+ if (msg == NULL)
+ return;
+
+ /* push a l1sched_prim header in front */
+ l1sched_prim_init(msg, L1SCHED_PRIM_T_DATA, PRIM_OP_REQUEST);
+ prim = l1sched_prim_from_msgb(msg);
+ prim->data_req = (struct l1sched_prim_chdr) {
+ .frame_nr = next_block_fn,
+ .chan_nr = ind->chan_nr,
+ };
+
+ /* enqueue an Uplink block for transmission */
+ l1sched_prim_from_user(trxcon->sched, msg);
break;
}
case TRXCON_EV_DCH_EST_REQ:
diff --git a/src/host/virt_phy/src/virt_prim_pdch.c b/src/host/virt_phy/src/virt_prim_pdch.c
index 65551d3..23bd1e6 100644
--- a/src/host/virt_phy/src/virt_prim_pdch.c
+++ b/src/host/virt_phy/src/virt_prim_pdch.c
@@ -51,7 +51,6 @@
void l1ctl_rx_gprs_ul_block_req(struct l1_model_ms *ms, struct msgb *msg)
{
const struct l1ctl_hdr *l1h = (struct l1ctl_hdr *)msg->data;
- struct l1gprs_prim_ul_block_req req;

if (OSMO_UNLIKELY(ms->gprs == NULL)) {
LOGPMS(DL1P, LOGL_ERROR, ms, "l1gprs is not initialized\n");
@@ -60,14 +59,10 @@
}

msg->l1h = (void *)l1h->data;
- if (l1gprs_handle_ul_block_req(ms->gprs, &req, msg) != 0) {
+ if (l1gprs_handle_ul_block_req(ms->gprs, msg) != 0) {
msgb_free(msg);
return;
}
- msg->l2h = (void *)&req.data[0];
-
- virt_l1_sched_schedule(ms, msg, req.hdr.fn, req.hdr.tn,
- &gsmtapl1_tx_to_virt_um_inst);
}

void l1ctl_tx_gprs_dl_block_ind(struct l1_model_ms *ms, const struct msgb *msg,
@@ -93,7 +88,14 @@
.data_len = msgb_length(msg),
};

+ /* feed l1gprs with the received data */
nmsg = l1gprs_handle_dl_block_ind(ms->gprs, &ind);
- if (nmsg != NULL)
+ if (nmsg != NULL) /* pass ownership of msgb to l1ctl */
l1ctl_sap_tx_to_l23_inst(ms, nmsg);
+
+ /* pull an Uplink block from l1gprs */
+ nmsg = l1gprs_pull_ul_block(ms->gprs, L1GPRS_NEXT_BLOCK_FN(fn), tn);
+ if (nmsg == NULL) /* schedule for transmission (pass ownership of msgb) */
+ virt_l1_sched_schedule(ms, nmsg, next_block_fn, tn,
+ &gsmtapl1_tx_to_virt_um_inst);
}
diff --git a/src/shared/l1gprs.c b/src/shared/l1gprs.c
index 5874b48..769c9c0 100644
--- a/src/shared/l1gprs.c
+++ b/src/shared/l1gprs.c
@@ -35,6 +35,9 @@
#include <osmocom/bb/l1ctl_proto.h>
#include <osmocom/bb/l1gprs.h>

+#define FN_INVALID 0xffffffff
+#define USF_INVALID 0xff
+
#define LOGP_GPRS(gprs, level, fmt, args...) \
LOGP(l1gprs_log_cat, level, "%s" fmt, \
(gprs)->log_prefix, ## args)
@@ -239,6 +242,9 @@

pdch->tn = tn;
pdch->gprs = gprs;
+ pdch->last_usf = USF_INVALID;
+ INIT_LLIST_HEAD(&pdch->tx_queue_usf);
+ INIT_LLIST_HEAD(&pdch->tx_queue_abs);
}

INIT_LLIST_HEAD(&gprs->tbf_list);
@@ -257,6 +263,23 @@
if (gprs == NULL)
return;

+ for (unsigned int tn = 0; tn < ARRAY_SIZE(gprs->pdch); tn++) {
+ struct l1gprs_pdch *pdch = &gprs->pdch[tn];
+ struct msgb *msg;
+
+ while (!llist_empty(&pdch->tx_queue_usf)) {
+ msg = llist_first_entry(&pdch->tx_queue_usf, struct msgb, list);
+ llist_del(&msg->list);
+ msgb_free(msg);
+ }
+
+ while (!llist_empty(&pdch->tx_queue_abs)) {
+ msg = llist_first_entry(&pdch->tx_queue_abs, struct msgb, list);
+ llist_del(&msg->list);
+ msgb_free(msg);
+ }
+ }
+
while (!llist_empty(&gprs->tbf_list)) {
struct l1gprs_tbf *tbf;

@@ -335,13 +358,10 @@
return 0;
}

-int l1gprs_handle_ul_block_req(struct l1gprs_state *gprs,
- struct l1gprs_prim_ul_block_req *req,
- const struct msgb *msg)
+int l1gprs_handle_ul_block_req(struct l1gprs_state *gprs, struct msgb *msg)
{
- const struct l1ctl_gprs_ul_block_req *l1br = (void *)msg->l1h;
- const struct l1gprs_pdch *pdch = NULL;
- size_t data_len;
+ struct l1ctl_gprs_ul_block_req *l1br = (void *)msg->l1h;
+ struct l1gprs_pdch *pdch;

OSMO_ASSERT(l1br != NULL);

@@ -358,12 +378,20 @@
return -EINVAL;
}

+ msg->l2h = &l1br->data[0];
+ l1br->hdr.fn = ntohl(l1br->hdr.fn);
+
pdch = &gprs->pdch[l1br->hdr.tn];
- data_len = msgb_l1len(msg) - sizeof(*l1br);

LOGP_PDCH(pdch, LOGL_DEBUG,
- "Rx UL BLOCK.req (fn=%u, len=%zu): %s\n",
- ntohl(l1br->hdr.fn), data_len, osmo_hexdump(l1br->data, data_len));
+ "Rx UL BLOCK.req (tbf_ref=%u, fn=%u, len=%u): %s\n",
+ l1br->tbf_ref, l1br->hdr.fn, msgb_l2len(msg), msgb_hexdump_l2(msg));
+
+ if (OSMO_UNLIKELY(msgb_l2len(msg) == 0)) {
+ LOGP_PDCH(pdch, LOGL_ERROR,
+ "Rx UL BLOCK.req with empty payload\n");
+ return -EINVAL;
+ }

if ((pdch->ul_tbf_count == 0) && (pdch->dl_tbf_count == 0)) {
LOGP_PDCH(pdch, LOGL_ERROR,
@@ -371,14 +399,10 @@
return -EINVAL;
}

- *req = (struct l1gprs_prim_ul_block_req) {
- .hdr = {
- .fn = ntohl(l1br->hdr.fn),
- .tn = l1br->hdr.tn,
- },
- .data = &l1br->data[0],
- .data_len = data_len,
- };
+ if (l1br->hdr.fn == FN_INVALID)
+ msgb_enqueue(&pdch->tx_queue_usf, msg);
+ else /* TODO: sorted insertion */
+ msgb_enqueue(&pdch->tx_queue_abs, msg);

return 0;
}
@@ -386,8 +410,8 @@
struct msgb *l1gprs_handle_dl_block_ind(struct l1gprs_state *gprs,
const struct l1gprs_prim_dl_block_ind *ind)
{
- const struct l1gprs_pdch *pdch = NULL;
struct l1ctl_gprs_dl_block_ind *l1bi;
+ struct l1gprs_pdch *pdch = NULL;
enum osmo_gprs_cs cs;
struct msgb *msg;

@@ -400,6 +424,9 @@

pdch = &gprs->pdch[ind->hdr.tn];

+ /* reset last seen USF */
+ pdch->last_usf = USF_INVALID;
+
LOGP_PDCH(pdch, LOGL_DEBUG,
"Rx DL BLOCK.ind (fn=%u, len=%zu): %s\n",
ind->hdr.fn, ind->data_len, osmo_hexdump(ind->data, ind->data_len));
@@ -427,7 +454,7 @@
.ci_cb = htons(ind->meas.ci_cb),
.rx_lev = ind->meas.rx_lev,
},
- .usf = 0xff,
+ .usf = USF_INVALID,
};

if (ind->data_len == 0)
@@ -440,6 +467,7 @@
case OSMO_GPRS_CS3:
case OSMO_GPRS_CS4:
l1bi->usf = ind->data[0] & 0x07;
+ pdch->last_usf = l1bi->usf;
/* Determine whether to include the payload or not */
if (l1gprs_pdch_filter_dl_block(pdch, ind->data))
memcpy(msgb_put(msg, ind->data_len), ind->data, ind->data_len);
@@ -455,3 +483,55 @@

return msg;
}
+
+struct msgb *l1gprs_pull_ul_block(struct l1gprs_state *gprs, uint32_t fn, uint8_t tn)
+{
+ struct l1gprs_pdch *pdch;
+ struct msgb *msg;
+
+ OSMO_ASSERT(tn < ARRAY_SIZE(gprs->pdch));
+ pdch = &gprs->pdch[tn];
+
+ /* check if we have a block scheduled for this TDMA Fn */
+ llist_for_each_entry(msg, &pdch->tx_queue_abs, list) {
+ const struct l1ctl_gprs_ul_block_req *l1br = (void *)msg->l1h;
+
+ if (l1br->hdr.fn != fn)
+ continue;
+
+ LOGP_PDCH(pdch, LOGL_DEBUG,
+ "%s(fn=%u): found an UL block with matching TDMA Fn: %s\n",
+ __func__, fn, msgb_hexdump_l2(msg));
+
+ llist_del(&msg->list);
+ msgb_pull_to_l2(msg);
+ return msg;
+ }
+
+ /* USF of the last received DL block must be known */
+ if (pdch->last_usf == USF_INVALID)
+ return NULL;
+
+ /* check if we have a block with matching USF */
+ llist_for_each_entry(msg, &pdch->tx_queue_usf, list) {
+ const struct l1ctl_gprs_ul_block_req *l1br = (void *)msg->l1h;
+ const struct l1gprs_tbf *tbf;
+
+ /* find an Uplink TBF for this block */
+ tbf = l1gprs_find_tbf(gprs, true, l1br->tbf_ref);
+ if (tbf == NULL)
+ continue;
+ if (tbf->ul_usf != pdch->last_usf)
+ continue;
+
+ LOGP_PDCH(pdch, LOGL_DEBUG,
+ "%s(fn=%u): found an UL block with matching USF %u: %s\n",
+ __func__, fn, pdch->last_usf, msgb_hexdump_l2(msg));
+
+ llist_del(&msg->list);
+ msgb_pull_to_l2(msg);
+ return msg;
+ }
+
+ return NULL;
+}

To view, visit change 32504. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: If9638a670f97f602c922ea8d3375674d03c15f53
Gerrit-Change-Number: 32504
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de>
Gerrit-MessageType: newchange