Revert "trx_toolkit/transceiver.py: implement the transmit burst queue"

This reverts commit 6e1c82d298.
Unfortunately, solving one problem it introduced even more regressions.

Change-Id: If29b4f6718cbc8af18fe18a5e3eca3912e8af01e
Related: OS#4658
This commit is contained in:
Vadim Yanitskiy 2020-07-21 16:12:02 +07:00
parent 7eb355ab3e
commit d4ed09df57
2 changed files with 4 additions and 74 deletions

View File

@ -388,8 +388,6 @@ class Application(ApplicationBase):
# Init shared clock generator
self.clck_gen = CLCKGen([])
# This method will be called on each TDMA frame
self.clck_gen.clck_handler = self.clck_handler
# Power measurement emulation
# Noise: -120 .. -105
@ -458,18 +456,14 @@ class Application(ApplicationBase):
for trx in self.trx_list.trx_list:
# DATA interface
if trx.data_if.sock in r_event:
trx.recv_data_msg()
msg = trx.recv_data_msg()
if msg is not None:
self.burst_fwd.forward_msg(trx, msg)
# CTRL interface
if trx.ctrl_if.sock in r_event:
trx.ctrl_if.handle_rx()
# This method will be called by the clock thread
def clck_handler(self, fn):
# We assume that this list is immutable at run-time
for trx in self.trx_list.trx_list:
trx.clck_tick(self.burst_fwd, fn)
def shutdown(self):
log.info("Shutting down...")

View File

@ -23,7 +23,6 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import logging as log
import threading
from ctrl_if_trx import CTRLInterfaceTRX
from data_if import DATAInterface
@ -123,37 +122,6 @@ class Transceiver:
Transceiver and all its timeslots, so using in for the BTS side
does not make any sense (imagine BCCH hopping together with DCCH).
== The transmit burst queue
According to 3GPP 45.002, the time difference between Uplink and
Downlink corresponds to three TDMA timeslot periods. However,
in general the L1 implementations (such as osmo-bts-trx and trxcon)
never schedule to be transmitted bursts for the current TDMA frame
immediately. Instead, they are being scheduled prematurely.
The rationale is that both transceiver and the L1 implementation
are separete processes that are not perfectly synchronized in time.
Moreover, the transceiver needs some time to prepare a burst for
transmission. This is why the time difference between Uplink and
Downlink is actually much higher on practice (20 TDMA frame periods
by default, at the moment of writing this patch).
In order to reflect that delay in a virtual environment, this
implementation, just like a normal transceiver (e.g. osmo-trx),
queues all to be transmitted (L12TRX) bursts, so hey remain in
the transmit queue until the appropriate time of transmission.
The API user is supposed to call recv_data_msg() in order to obtain
a L12TRX message on the TRXD (data) inteface, so it gets queued by
this function. Then, to ensure the timeous transmission, the user
of this implementation needs to call clck_tick() on each TDMA
frame. Both functions are thread-safe (queue mutex).
In a multi-trx configuration, the use of queue additionally ensures
proper burst aggregation on multiple TRXD connections, so all L12TRX
messages are guaranteed to be sent in the right order, i.e. with
monolithically-increasing TDMA frame numbers.
"""
def __init__(self, bind_addr, remote_addr, base_port, name = None,
@ -209,10 +177,6 @@ class Transceiver:
# List of child transceivers
self.child_trx_list = TRXList()
# Tx (L12TRX) burst queue and mutex
self._tx_queue_lock = threading.Lock()
self._tx_queue = []
def __str__(self):
desc = "%s:%d" % (self.remote_addr, self.base_port)
if self.child_idx > 0:
@ -269,12 +233,10 @@ class Transceiver:
trx.running = True
elif event == "POWEROFF":
trx.running = False
trx.tx_queue_clear()
trx.disable_fh()
# Reset frequency hopping parameters, clear the queue
# Reset frequency hopping parameters
if event == "POWEROFF":
self.tx_queue_clear()
self.disable_fh()
# Trigger clock generator if required
@ -312,34 +274,8 @@ class Transceiver:
"configured => dropping..." % (self, msg.desc_hdr()))
return None
# Enque the message, it will be sent later
self.tx_queue_append(msg)
return msg
def handle_data_msg(self, msg):
# TODO: make legacy mode configurable (via argv?)
self.data_if.send_msg(msg, legacy = True)
def tx_queue_append(self, msg):
with self._tx_queue_lock:
self._tx_queue.append(msg)
def tx_queue_clear(self):
with self._tx_queue_lock:
self._tx_queue.clear()
def clck_tick(self, fwd, fn):
if not self.running:
return
self._tx_queue_lock.acquire()
for msg in self._tx_queue:
if msg.fn == fn:
fwd.forward_msg(self, msg)
elif msg.fn < fn:
log.warning("(%s) Stale TRXD message (fn=%u): %s"
% (self, fn, msg.desc_hdr()))
self._tx_queue = [msg for msg in self._tx_queue if msg.fn > fn]
self._tx_queue_lock.release()