<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-trx/+/14989">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">lms: Drop rx_underruns rate ctr, add tx_drop_* rate ctr<br><br>After discussion in [1] and further look at the code, it became obvios<br>rx_underrun events are not happening in general for any SDR (don't<br>exist), so let's drop that counter. Instead, add Tx Dropped Packet counters,<br>which were not accounted prior to this commit.<br><br>[1] https://github.com/osmocom/osmo-trx/commit/bde55afd29fc9aae10eb11f6515821afa39b772d<br><br>Change-Id: Iff1535c219a4695a511d383d7c4b06ef6eff959d<br>---<br>M CommonLibs/osmo_signal.h<br>M CommonLibs/trx_rate_ctr.cpp<br>M CommonLibs/trx_rate_ctr.h<br>M CommonLibs/trx_vty.c<br>M Transceiver52M/device/lms/LMSDevice.cpp<br>M Transceiver52M/device/lms/LMSDevice.h<br>6 files changed, 80 insertions(+), 40 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/89/14989/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/CommonLibs/osmo_signal.h b/CommonLibs/osmo_signal.h</span><br><span>index ee7e2a4..ceb7d6f 100644</span><br><span>--- a/CommonLibs/osmo_signal.h</span><br><span>+++ b/CommonLibs/osmo_signal.h</span><br><span>@@ -48,9 +48,10 @@</span><br><span> /* signal cb for signal <SS_DEVICE,S_DEVICE_COUNTER_CHANGE> */</span><br><span> struct device_counters {</span><br><span> size_t chan;</span><br><span style="color: hsl(0, 100%, 40%);">- unsigned int rx_underruns;</span><br><span> unsigned int rx_overruns;</span><br><span> unsigned int tx_underruns;</span><br><span> unsigned int rx_dropped_events;</span><br><span> unsigned int rx_dropped_samples;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int tx_dropped_events;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int tx_dropped_samples;</span><br><span> };</span><br><span>diff --git a/CommonLibs/trx_rate_ctr.cpp b/CommonLibs/trx_rate_ctr.cpp</span><br><span>index 43e4189..a9ef88c 100644</span><br><span>--- a/CommonLibs/trx_rate_ctr.cpp</span><br><span>+++ b/CommonLibs/trx_rate_ctr.cpp</span><br><span>@@ -93,20 +93,22 @@</span><br><span> };</span><br><span> </span><br><span> const struct value_string trx_chan_ctr_names[] = {</span><br><span style="color: hsl(0, 100%, 40%);">- { TRX_CTR_RX_UNDERRUNS, "rx_underruns" },</span><br><span> { TRX_CTR_RX_OVERRUNS, "rx_overruns" },</span><br><span> { TRX_CTR_TX_UNDERRUNS, "tx_underruns" },</span><br><span> { TRX_CTR_RX_DROP_EV, "rx_drop_events" },</span><br><span> { TRX_CTR_RX_DROP_SMPL, "rx_drop_samples" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { TRX_CTR_TX_DROP_EV, "tx_drop_events" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { TRX_CTR_TX_DROP_SMPL, "tx_drop_samples" },</span><br><span> { 0, NULL }</span><br><span> };</span><br><span> </span><br><span> static const struct rate_ctr_desc trx_chan_ctr_desc[] = {</span><br><span style="color: hsl(0, 100%, 40%);">- [TRX_CTR_RX_UNDERRUNS] = { "device:rx_underruns", "Number of Rx underruns" },</span><br><span style="color: hsl(0, 100%, 40%);">- [TRX_CTR_RX_OVERRUNS] = { "device:rx_overruns", "Number of Rx overruns" },</span><br><span style="color: hsl(0, 100%, 40%);">- [TRX_CTR_TX_UNDERRUNS] = { "device:tx_underruns", "Number of Tx underruns" },</span><br><span style="color: hsl(120, 100%, 40%);">+ [TRX_CTR_RX_OVERRUNS] = { "device:rx_overruns", "Number of Rx overruns in FIFO queue" },</span><br><span style="color: hsl(120, 100%, 40%);">+ [TRX_CTR_TX_UNDERRUNS] = { "device:tx_underruns", "Number of Tx underruns in FIFO queue" },</span><br><span> [TRX_CTR_RX_DROP_EV] = { "device:rx_drop_events", "Number of times Rx samples were dropped by HW" },</span><br><span> [TRX_CTR_RX_DROP_SMPL] = { "device:rx_drop_samples", "Number of Rx samples dropped by HW" },</span><br><span style="color: hsl(120, 100%, 40%);">+ [TRX_CTR_TX_DROP_EV] = { "device:tx_drop_events", "Number of times Tx samples were dropped by HW" },</span><br><span style="color: hsl(120, 100%, 40%);">+ [TRX_CTR_TX_DROP_SMPL] = { "device:tx_drop_samples", "Number of Tx samples dropped by HW" }</span><br><span> };</span><br><span> </span><br><span> static const struct rate_ctr_group_desc trx_chan_ctr_group_desc = {</span><br><span>@@ -126,8 +128,6 @@</span><br><span> if (ctrs_pending[chan].chan == PENDING_CHAN_NONE)</span><br><span> continue;</span><br><span> LOGCHAN(chan, DMAIN, INFO) << "rate_ctr update";</span><br><span style="color: hsl(0, 100%, 40%);">- ctr = &rate_ctrs[chan]->ctr[TRX_CTR_RX_UNDERRUNS];</span><br><span style="color: hsl(0, 100%, 40%);">- rate_ctr_add(ctr, ctrs_pending[chan].rx_underruns - ctr->current);</span><br><span> ctr = &rate_ctrs[chan]->ctr[TRX_CTR_RX_OVERRUNS];</span><br><span> rate_ctr_add(ctr, ctrs_pending[chan].rx_overruns - ctr->current);</span><br><span> ctr = &rate_ctrs[chan]->ctr[TRX_CTR_TX_UNDERRUNS];</span><br><span>@@ -136,6 +136,10 @@</span><br><span> rate_ctr_add(ctr, ctrs_pending[chan].rx_dropped_events - ctr->current);</span><br><span> ctr = &rate_ctrs[chan]->ctr[TRX_CTR_RX_DROP_SMPL];</span><br><span> rate_ctr_add(ctr, ctrs_pending[chan].rx_dropped_samples - ctr->current);</span><br><span style="color: hsl(120, 100%, 40%);">+ ctr = &rate_ctrs[chan]->ctr[TRX_CTR_TX_DROP_EV];</span><br><span style="color: hsl(120, 100%, 40%);">+ rate_ctr_add(ctr, ctrs_pending[chan].tx_dropped_events - ctr->current);</span><br><span style="color: hsl(120, 100%, 40%);">+ ctr = &rate_ctrs[chan]->ctr[TRX_CTR_TX_DROP_SMPL];</span><br><span style="color: hsl(120, 100%, 40%);">+ rate_ctr_add(ctr, ctrs_pending[chan].tx_dropped_samples - ctr->current);</span><br><span> </span><br><span> /* Mark as done */</span><br><span> ctrs_pending[chan].chan = PENDING_CHAN_NONE;</span><br><span>diff --git a/CommonLibs/trx_rate_ctr.h b/CommonLibs/trx_rate_ctr.h</span><br><span>index 6e4fa4d..155f413 100644</span><br><span>--- a/CommonLibs/trx_rate_ctr.h</span><br><span>+++ b/CommonLibs/trx_rate_ctr.h</span><br><span>@@ -4,11 +4,12 @@</span><br><span> #include <osmocom/vty/command.h></span><br><span> </span><br><span> enum TrxCtr {</span><br><span style="color: hsl(0, 100%, 40%);">- TRX_CTR_RX_UNDERRUNS,</span><br><span> TRX_CTR_RX_OVERRUNS,</span><br><span> TRX_CTR_TX_UNDERRUNS,</span><br><span> TRX_CTR_RX_DROP_EV,</span><br><span> TRX_CTR_RX_DROP_SMPL,</span><br><span style="color: hsl(120, 100%, 40%);">+ TRX_CTR_TX_DROP_EV,</span><br><span style="color: hsl(120, 100%, 40%);">+ TRX_CTR_TX_DROP_SMPL,</span><br><span> };</span><br><span> </span><br><span> struct ctr_threshold {</span><br><span>diff --git a/CommonLibs/trx_vty.c b/CommonLibs/trx_vty.c</span><br><span>index e184f49..bac9653 100644</span><br><span>--- a/CommonLibs/trx_vty.c</span><br><span>+++ b/CommonLibs/trx_vty.c</span><br><span>@@ -384,14 +384,15 @@</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define THRESHOLD_ARGS "(rx_underruns|rx_overruns|tx_underruns|rx_drop_events|rx_drop_samples)"</span><br><span style="color: hsl(120, 100%, 40%);">+#define THRESHOLD_ARGS "(rx_overruns|tx_underruns|rx_drop_events|rx_drop_samples|tx_drop_events|tx_drop_samples)"</span><br><span> #define THRESHOLD_STR_VAL(s) "Set threshold value for rate_ctr device:" OSMO_STRINGIFY_VAL(s) "\n"</span><br><span> #define THRESHOLD_STRS \</span><br><span style="color: hsl(0, 100%, 40%);">- THRESHOLD_STR_VAL(rx_underruns) \</span><br><span> THRESHOLD_STR_VAL(rx_overruns) \</span><br><span> THRESHOLD_STR_VAL(tx_underruns) \</span><br><span> THRESHOLD_STR_VAL(rx_drop_events) \</span><br><span style="color: hsl(0, 100%, 40%);">- THRESHOLD_STR_VAL(rx_drop_samples)</span><br><span style="color: hsl(120, 100%, 40%);">+ THRESHOLD_STR_VAL(rx_drop_samples) \</span><br><span style="color: hsl(120, 100%, 40%);">+ THRESHOLD_STR_VAL(tx_drop_events) \</span><br><span style="color: hsl(120, 100%, 40%);">+ THRESHOLD_STR_VAL(tx_drop_samples)</span><br><span> #define INTV_ARGS "(per-second|per-minute|per-hour|per-day)"</span><br><span> #define INTV_STR_VAL(s) "Threshold value sampled " OSMO_STRINGIFY_VAL(s) "\n"</span><br><span> #define INTV_STRS \</span><br><span>diff --git a/Transceiver52M/device/lms/LMSDevice.cpp b/Transceiver52M/device/lms/LMSDevice.cpp</span><br><span>index 0eaf0a3..e027050 100644</span><br><span>--- a/Transceiver52M/device/lms/LMSDevice.cpp</span><br><span>+++ b/Transceiver52M/device/lms/LMSDevice.cpp</span><br><span>@@ -574,38 +574,37 @@</span><br><span> /* UNUSED on limesdr (only used on usrp1/2) */</span><br><span> return GSM::Time(0,0);</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void LMSDevice::update_stream_stats(size_t chan, bool * underrun, bool * overrun)</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * Issue tracking description of several events: https://github.com/myriadrf/LimeSuite/issues/265</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void LMSDevice::update_stream_stats_rx(size_t chan, bool *overrun)</span><br><span> {</span><br><span> lms_stream_status_t status;</span><br><span> bool changed = false;</span><br><span> </span><br><span> if (LMS_GetStreamStatus(&m_lms_stream_rx[chan], &status) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGCHAN(chan, DDEV, ERROR) << "LMS_GetStreamStatus failed";</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGCHAN(chan, DDEV, ERROR) << "Rx LMS_GetStreamStatus failed";</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (status.underrun) {</span><br><span style="color: hsl(0, 100%, 40%);">- changed = true;</span><br><span style="color: hsl(0, 100%, 40%);">- *underrun = true;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGCHAN(chan, DDEV, ERROR) << "recv Underrun! ("</span><br><span style="color: hsl(0, 100%, 40%);">- << m_ctr[chan].rx_underruns << " -> "</span><br><span style="color: hsl(0, 100%, 40%);">- << status.underrun << ")";</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- m_ctr[chan].rx_underruns += status.underrun;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIFO overrun is counted when Rx FIFO is full but new data comes from</span><br><span style="color: hsl(120, 100%, 40%);">+ the board and oldest samples in FIFO are overwritte. Value count</span><br><span style="color: hsl(120, 100%, 40%);">+ since the last call to LMS_GetStreamStatus(stream). */</span><br><span> if (status.overrun) {</span><br><span> changed = true;</span><br><span> *overrun = true;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGCHAN(chan, DDEV, ERROR) << "recv Overrun! ("</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGCHAN(chan, DDEV, ERROR) << "Rx Overrun! ("</span><br><span> << m_ctr[chan].rx_overruns << " -> "</span><br><span> << status.overrun << ")";</span><br><span> }</span><br><span> m_ctr[chan].rx_overruns += status.overrun;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Dropped packets in Rx are counted when gaps in Rx timestamps are</span><br><span style="color: hsl(120, 100%, 40%);">+ detected (likely because buffer oveflow in hardware). Value count</span><br><span style="color: hsl(120, 100%, 40%);">+ since the last call to LMS_GetStreamStatus(stream). */</span><br><span> if (status.droppedPackets) {</span><br><span> changed = true;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGCHAN(chan, DDEV, ERROR) << "recv Dropped packets by HW! ("</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGCHAN(chan, DDEV, ERROR) << "Rx Dropped packets by HW! ("</span><br><span> << m_ctr[chan].rx_dropped_samples << " -> "</span><br><span> << m_ctr[chan].rx_dropped_samples +</span><br><span> status.droppedPackets</span><br><span>@@ -653,7 +652,7 @@</span><br><span> while ((avail_smpls = rx_buffers[i]->avail_smpls(timestamp)) < len) {</span><br><span> thread_enable_cancel(false);</span><br><span> num_smpls = LMS_RecvStream(&m_lms_stream_rx[i], bufs[i], len - avail_smpls, &rx_metadata, 100);</span><br><span style="color: hsl(0, 100%, 40%);">- update_stream_stats(i, underrun, overrun);</span><br><span style="color: hsl(120, 100%, 40%);">+ update_stream_stats_rx(i, overrun);</span><br><span> thread_enable_cancel(true);</span><br><span> if (num_smpls <= 0) {</span><br><span> LOGCHAN(i, DDEV, ERROR) << "Device receive timed out (" << rc << " vs exp " << len << ").";</span><br><span>@@ -697,13 +696,53 @@</span><br><span> return len;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void LMSDevice::update_stream_stats_tx(size_t chan, bool *underrun)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ lms_stream_status_t status;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool changed = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (LMS_GetStreamStatus(&m_lms_stream_tx[chan], &status) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGCHAN(chan, DDEV, ERROR) << "Tx LMS_GetStreamStatus failed";</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIFO underrun is counted when Tx is running but FIFO is empty for</span><br><span style="color: hsl(120, 100%, 40%);">+ >100 ms (500ms in older versions). Value count since the last call to</span><br><span style="color: hsl(120, 100%, 40%);">+ LMS_GetStreamStatus(stream). */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (status.underrun) {</span><br><span style="color: hsl(120, 100%, 40%);">+ changed = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ *underrun = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGCHAN(chan, DDEV, ERROR) << "Tx Underrun! ("</span><br><span style="color: hsl(120, 100%, 40%);">+ << m_ctr[chan].tx_underruns << " -> "</span><br><span style="color: hsl(120, 100%, 40%);">+ << status.underrun << ")";</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ m_ctr[chan].tx_underruns += status.underrun;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Dropped packets in Tx are counted only when timestamps are enabled</span><br><span style="color: hsl(120, 100%, 40%);">+ and SDR drops packet because of late timestamp. Value count since the</span><br><span style="color: hsl(120, 100%, 40%);">+ last call to LMS_GetStreamStatus(stream). */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (status.droppedPackets) {</span><br><span style="color: hsl(120, 100%, 40%);">+ changed = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGCHAN(chan, DDEV, ERROR) << "Tx Dropped packets by HW! ("</span><br><span style="color: hsl(120, 100%, 40%);">+ << m_ctr[chan].tx_dropped_samples << " -> "</span><br><span style="color: hsl(120, 100%, 40%);">+ << m_ctr[chan].tx_dropped_samples +</span><br><span style="color: hsl(120, 100%, 40%);">+ status.droppedPackets</span><br><span style="color: hsl(120, 100%, 40%);">+ << ")";</span><br><span style="color: hsl(120, 100%, 40%);">+ m_ctr[chan].tx_dropped_events++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ m_ctr[chan].tx_dropped_samples += status.droppedPackets;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (changed)</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_signal_dispatch(SS_DEVICE, S_DEVICE_COUNTER_CHANGE, &m_ctr[chan]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int LMSDevice::writeSamples(std::vector < short *>&bufs, int len,</span><br><span> bool * underrun, unsigned long long timestamp,</span><br><span> bool isControl)</span><br><span> {</span><br><span> int rc = 0;</span><br><span> unsigned int i;</span><br><span style="color: hsl(0, 100%, 40%);">- lms_stream_status_t status;</span><br><span> lms_stream_meta_t tx_metadata = {};</span><br><span> tx_metadata.flushPartialPacket = false;</span><br><span> tx_metadata.waitForTimestamp = true;</span><br><span>@@ -725,19 +764,12 @@</span><br><span> LOGCHAN(i, DDEV, DEBUG) << "send buffer of len " << len << " timestamp " << std::hex << tx_metadata.timestamp;</span><br><span> thread_enable_cancel(false);</span><br><span> rc = LMS_SendStream(&m_lms_stream_tx[i], bufs[i], len, &tx_metadata, 100);</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc != len) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGCHAN(i, DDEV, ERROR) << "LMS: Device send timed out";</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (LMS_GetStreamStatus(&m_lms_stream_tx[i], &status) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (status.underrun > m_ctr[i].tx_underruns) {</span><br><span style="color: hsl(0, 100%, 40%);">- *underrun = true;</span><br><span style="color: hsl(0, 100%, 40%);">- m_ctr[i].tx_underruns = status.underrun;</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_signal_dispatch(SS_DEVICE, S_DEVICE_COUNTER_CHANGE, &m_ctr[i]);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(120, 100%, 40%);">+ update_stream_stats_rx(i, underrun);</span><br><span> thread_enable_cancel(true);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc != len) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGCHAN(i, DDEV, ERROR) << "LMS: Device Tx timed out (" << rc << " vs exp " << len << ").";</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> </span><br><span> return rc;</span><br><span>diff --git a/Transceiver52M/device/lms/LMSDevice.h b/Transceiver52M/device/lms/LMSDevice.h</span><br><span>index 906fbee..bc79f97 100644</span><br><span>--- a/Transceiver52M/device/lms/LMSDevice.h</span><br><span>+++ b/Transceiver52M/device/lms/LMSDevice.h</span><br><span>@@ -65,7 +65,8 @@</span><br><span> bool do_filters(size_t chan);</span><br><span> int get_ant_idx(const std::string & name, bool dir_tx, size_t chan);</span><br><span> bool flush_recv(size_t num_pkts);</span><br><span style="color: hsl(0, 100%, 40%);">- void update_stream_stats(size_t chan, bool * underrun, bool * overrun);</span><br><span style="color: hsl(120, 100%, 40%);">+ void update_stream_stats_rx(size_t chan, bool *overrun);</span><br><span style="color: hsl(120, 100%, 40%);">+ void update_stream_stats_tx(size_t chan, bool *underrun);</span><br><span> </span><br><span> public:</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-trx/+/14989">change 14989</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-trx/+/14989"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-trx </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Iff1535c219a4695a511d383d7c4b06ef6eff959d </div>
<div style="display:none"> Gerrit-Change-Number: 14989 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>