fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-trx/+/43612?usp=email )
Change subject: proxy: queue BURST.req and dispatch per TDMA frame tick ......................................................................
proxy: queue BURST.req and dispatch per TDMA frame tick
Enqueue incoming BURST.req per endpoint instead of forwarding immediately, and drain the queue on each TDMA clock tick: forward entries whose fn is due, drop late ones, keep the rest waiting.
Change-Id: Ib147983e97638d2a2e487ccf76184912caf0941d Related: OS#6672 --- M proxy/Makefile.am A proxy/include/osmocom/proxy/burst_fwd.h M proxy/include/osmocom/proxy/trx.h M proxy/src/burst_fwd.c M proxy/src/clck_gen.c M proxy/src/trx.c 6 files changed, 78 insertions(+), 10 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/12/43612/1
diff --git a/proxy/Makefile.am b/proxy/Makefile.am index 909c698..c560391 100644 --- a/proxy/Makefile.am +++ b/proxy/Makefile.am @@ -3,6 +3,7 @@ $(NULL)
noinst_HEADERS = \ + include/osmocom/proxy/burst_fwd.h \ include/osmocom/proxy/clck_gen.h \ include/osmocom/proxy/logging.h \ include/osmocom/proxy/path_sim.h \ diff --git a/proxy/include/osmocom/proxy/burst_fwd.h b/proxy/include/osmocom/proxy/burst_fwd.h new file mode 100644 index 0000000..1f60c76 --- /dev/null +++ b/proxy/include/osmocom/proxy/burst_fwd.h @@ -0,0 +1,9 @@ +#pragma once + +#include <stdint.h> + +/*! Dispatch every queued BURST.req (see struct proxy_trx::burst_queue) whose + * TDMA frame number is due: forward those with fn == fn, drop those with + * fn < fn (arrived too late), and leave the rest queued. Call once per + * TDMA frame tick from the clock generator (clck_gen.c). */ +void burst_fwd_dispatch_queue(uint32_t fn); diff --git a/proxy/include/osmocom/proxy/trx.h b/proxy/include/osmocom/proxy/trx.h index e47a41f..a046653 100644 --- a/proxy/include/osmocom/proxy/trx.h +++ b/proxy/include/osmocom/proxy/trx.h @@ -7,6 +7,7 @@ #include <osmocom/core/logging.h>
#include <osmocom/trx/trxc.h> +#include <osmocom/trx/trxd.h>
#include <osmocom/proxy/path_sim.h>
@@ -52,6 +53,15 @@ struct proxy_trx_fh *fh; /*!< frequency hopping config (SETFH), NULL if disabled */ };
+/*! One BURST.req awaiting its TDMA frame tick, queued to model real + * transceivers, where L1 typically submits bursts a few frames ahead of + * their actual air time (see burst_fwd.c). */ +struct proxy_trx_burst_queue_entry { + struct llist_head list; + unsigned int chan; + struct osmo_trxd_burst_req br; +}; + /*! One virtual transceiver endpoint */ struct proxy_trx { struct llist_head list; @@ -61,6 +71,7 @@ int tx_power; /*!< dBm, nominal Tx power (path_sim_state::tx_power) */ unsigned int num_chans; /*!< mirrors osmo_trx_ep_get_num_chans(ep) */ struct proxy_trx_chan *chans; /*!< array of num_chans entries, allocated on open */ + struct llist_head burst_queue; /*!< struct proxy_trx_burst_queue_entry::list */ };
#define LOGP_TRX(trx, ss, level, fmt, args...) \ diff --git a/proxy/src/burst_fwd.c b/proxy/src/burst_fwd.c index de057b6..62c5b14 100644 --- a/proxy/src/burst_fwd.c +++ b/proxy/src/burst_fwd.c @@ -26,6 +26,7 @@ #include <string.h>
#include <osmocom/core/bits.h> +#include <osmocom/core/talloc.h> #include <osmocom/core/linuxlist.h>
#include <osmocom/trx/ep.h> @@ -33,6 +34,7 @@ #include <osmocom/proxy/proxy.h> #include <osmocom/proxy/trx.h> #include <osmocom/proxy/path_sim.h> +#include <osmocom/proxy/burst_fwd.h> #include <osmocom/proxy/logging.h>
#define OSMO_TRXD_F_COMMON_MASK ( \ @@ -68,19 +70,12 @@ /*! Forward a Tx burst request to every powered-on endpoint/channel * whose Rx frequency matches the source channel's Tx frequency (resolved * per TDMA frame number if frequency hopping (SETFH) is configured). */ -void osmo_trx_ep_rx_burst_req(struct osmo_trx_ep *ep, unsigned int chan, - const struct osmo_trxd_burst_req *br) +static void burst_fwd_burst_req(struct proxy_trx *src, unsigned int chan, + const struct osmo_trxd_burst_req *br) { - struct proxy_trx *src = osmo_trx_ep_get_priv(ep); struct proxy_trx *dst = NULL; uint32_t tx_freq;
- if (!src->powered) { - LOGP_TRXCH(src, chan, DTRXD, LOGL_NOTICE, - "Rx BURST.req while not powered on, dropping\n"); - return; - } - if (src->chans[chan].fh != NULL) proxy_trx_fh_resolve(src->chans[chan].fh, br->fn, NULL, &tx_freq); else @@ -107,3 +102,53 @@ } } } + +/*! Enqueue a Tx burst request for later dispatch by the TDMA clock + * generator: real transceivers typically receive bursts a few frames ahead + * of their actual air time, so forwarding must happen at the matching TDMA + * frame tick, not immediately upon receipt (see burst_fwd_dispatch_queue()). */ +void osmo_trx_ep_rx_burst_req(struct osmo_trx_ep *ep, unsigned int chan, + const struct osmo_trxd_burst_req *br) +{ + struct proxy_trx *src = osmo_trx_ep_get_priv(ep); + struct proxy_trx_burst_queue_entry *entry; + + if (!src->powered) { + LOGP_TRXCH(src, chan, DTRXD, LOGL_NOTICE, + "Rx BURST.req while not powered on, dropping\n"); + return; + } + + entry = talloc_zero(src, struct proxy_trx_burst_queue_entry); + OSMO_ASSERT(entry != NULL); + entry->chan = chan; + entry->br = *br; + + llist_add_tail(&entry->list, &src->burst_queue); +} + +void burst_fwd_dispatch_queue(uint32_t fn) +{ + struct proxy_trx *trx; + + llist_for_each_entry(trx, &g_proxy_ctx->trx_list, list) { + struct proxy_trx_burst_queue_entry *entry, *entry2; + + llist_for_each_entry_safe(entry, entry2, &trx->burst_queue, list) { + if (entry->br.fn > fn) /* XXX */ + continue; + + llist_del(&entry->list); + + if (entry->br.fn < fn) { /* XXX */ + LOGP_TRXCH(trx, entry->chan, DTRXD, LOGL_ERROR, + "Rx BURST.req for fn=%u too late (now fn=%u), " + "dropping\n", entry->br.fn, fn); + } else { + burst_fwd_burst_req(trx, entry->chan, &entry->br); + } + + talloc_free(entry); + } + } +} diff --git a/proxy/src/clck_gen.c b/proxy/src/clck_gen.c index dc70dbb..390ef60 100644 --- a/proxy/src/clck_gen.c +++ b/proxy/src/clck_gen.c @@ -35,6 +35,7 @@ #include <osmocom/proxy/proxy.h> #include <osmocom/proxy/trx.h> #include <osmocom/proxy/clck_gen.h> +#include <osmocom/proxy/burst_fwd.h> #include <osmocom/proxy/logging.h>
/*! Send "IND CLOCK" every N frames (matches fake_trx.py's CLCKGen default) */ @@ -66,7 +67,7 @@ } }
- /* TODO: drive per-frame burst forwarding (burst_queue/burst_fwd) */ + burst_fwd_dispatch_queue(gen->fn);
GSM_TDMA_FN_INC(gen->fn); } diff --git a/proxy/src/trx.c b/proxy/src/trx.c index 737a7ce..a748306 100644 --- a/proxy/src/trx.c +++ b/proxy/src/trx.c @@ -52,6 +52,7 @@
trx->name = talloc_strdup(trx, name); trx->tx_power = PROXY_TRX_DEFAULT_TX_POWER; + INIT_LLIST_HEAD(&trx->burst_queue); trx->ep = osmo_trx_ep_alloc(trx, num_chans); if (trx->ep == NULL) { talloc_free(trx);