fixeria has uploaded this change for review.
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);
To view, visit change 43612. To unsubscribe, or for help writing mail filters, visit settings.