<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/10476">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
Harald Welte: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">measurement: substitue missing measurements<br><br>At the moment the measurement calculation of osmo-bts works by<br>collecting the measurement reports the phy emits during a measurement<br>interval. Normally one would expect a well defind fixed number here, but<br>some phys will not emit a measurement report for lost blocks. Also<br>blocks and their reports may get lost because of cpu overload etc.<br><br>The computation that is executed at the end of the measurement interval<br>computes over all received measurement. This evenutally means that<br>missing measurements will not taken into account and the result will<br>look better than it is in reality.<br><br>To fix this, the interval must be of a defined size and in cases where<br>less measurements as expected were collected, the algorithm must assume<br>they have been received with a 100%BER and take that into account.<br>However, all RSSI and TA/TOA related computations should continue to<br>rely on actual measurement data.<br><br>- make sure the algorithm works over a fixed interval<br>- replace missing measurements with 100%BER<br>- fix and extend unit-tests<br><br>Change-Id: Idd30fc07603ad7d042c1fb416e247c3bf7d35c8b<br>Related: OS#2987<br>---<br>M src/common/measurement.c<br>M tests/meas/meas_test.c<br>M tests/meas/meas_test.ok<br>M tests/meas/meas_testcases.h<br>4 files changed, 859 insertions(+), 96 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/common/measurement.c b/src/common/measurement.c</span><br><span>index d7580e6..59f5d83 100644</span><br><span>--- a/src/common/measurement.c</span><br><span>+++ b/src/common/measurement.c</span><br><span>@@ -16,6 +16,21 @@</span><br><span> static const uint8_t ts45008_83_tch_hs0[] = { 0, 2, 4, 6, 52, 54, 56, 58 };</span><br><span> static const uint8_t ts45008_83_tch_hs1[] = { 14, 16, 18, 20, 66, 68, 70, 72 };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* In cases where we less measurements than we expect we must assume that we</span><br><span style="color: hsl(120, 100%, 40%);">+ * just did not receive the block because it was lost due to bad channel</span><br><span style="color: hsl(120, 100%, 40%);">+ * conditions. We set up a dummy measurement result here that reflects the</span><br><span style="color: hsl(120, 100%, 40%);">+ * worst possible result. In our* calculation we will use this dummy to replace</span><br><span style="color: hsl(120, 100%, 40%);">+ * the missing measurements */</span><br><span style="color: hsl(120, 100%, 40%);">+#define MEASUREMENT_DUMMY_BER 10000 /* 100% BER */</span><br><span style="color: hsl(120, 100%, 40%);">+#define MEASUREMENT_DUMMY_IRSSI 109 /* noise floor in -dBm */</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct bts_ul_meas measurement_dummy = (struct bts_ul_meas) {</span><br><span style="color: hsl(120, 100%, 40%);">+ .ber10k = MEASUREMENT_DUMMY_BER,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ta_offs_256bits = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .c_i = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .is_sub = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .inv_rssi = MEASUREMENT_DUMMY_IRSSI</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* find out if an array contains a given key as element */</span><br><span> #define ARRAY_CONTAINS(arr, val) array_contains(arr, ARRAY_SIZE(arr), val)</span><br><span> static bool array_contains(const uint8_t *arr, unsigned int len, uint8_t val) {</span><br><span>@@ -468,6 +483,64 @@</span><br><span> return 7;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Get the number of measurements that we expect for a specific lchan.</span><br><span style="color: hsl(120, 100%, 40%);">+ * (This is a static number that is defined by the specific slot layout of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the channel) */</span><br><span style="color: hsl(120, 100%, 40%);">+static unsigned int lchan_meas_num_expected(const struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pchan) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_TCH_F:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 24 for TCH + 1 for SACCH */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 25;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_TCH_H:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 24 half-blocks for TCH + 1 for SACCH */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 25;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_SDCCH8_SACCH8C:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 2 for SDCCH + 1 for SACCH */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 3;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_CCCH_SDCCH4:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_CCCH_SDCCH4_CBCH:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 2 for SDCCH + 1 for SACCH */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 3;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ return lchan->meas.num_ul_meas;</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 style="color: hsl(120, 100%, 40%);">+/* In DTX a subset of blocks must always be transmitted</span><br><span style="color: hsl(120, 100%, 40%);">+ * See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX) */</span><br><span style="color: hsl(120, 100%, 40%);">+static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* AMR is using a more elaborated model with a dymanic amount of</span><br><span style="color: hsl(120, 100%, 40%);">+ * DTX blocks so this function is not applicable to determine the</span><br><span style="color: hsl(120, 100%, 40%);">+ * amount of expected SUB Measurements when AMR is used */</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(lchan->tch_mode != GSM48_CMODE_SPEECH_AMR)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pchan) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_TCH_F:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 1 block SDCCH, 2 blocks TCH */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 3;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_TCH_H:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 1 block SDCCH, 4 half-blocks TCH */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 5;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_SDCCH8_SACCH8C:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* no DTX here, all blocks must be present! */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 3;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_CCCH_SDCCH4:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_CCCH_SDCCH4_CBCH:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* no DTX here, all blocks must be present! */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 3;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</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> /* if we clip the TOA value to 12 bits, i.e. toa256=3200,</span><br><span> * -> the maximum deviation can be 2*3200 = 6400</span><br><span> * -> the maximum squared deviation can be 6400^2 = 40960000</span><br><span>@@ -482,6 +555,10 @@</span><br><span> /* compute Osmocom extended measurements for the given lchan */</span><br><span> static void lchan_meas_compute_extended(struct gsm_lchan *lchan)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_ul_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_ul_meas_excess = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_ul_meas_expect;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* we assume that lchan_meas_check_compute() has already computed the mean value</span><br><span> * and we can compute the min/max/variance/stddev from this */</span><br><span> int i;</span><br><span>@@ -489,19 +566,47 @@</span><br><span> /* each measurement is an int32_t, so the squared difference value must fit in 32bits */</span><br><span> /* the sum of the squared values (each up to 32bit) can very easily exceed 32 bits */</span><br><span> u_int64_t sq_diff_sum = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* In case we do not have any measurement values collected there is no</span><br><span style="color: hsl(120, 100%, 40%);">+ * computation possible. We just skip the whole computation here, the</span><br><span style="color: hsl(120, 100%, 40%);">+ * lchan->meas.flags will not get the LC_UL_M_F_OSMO_EXT_VALID flag set</span><br><span style="color: hsl(120, 100%, 40%);">+ * so no extended measurement results will be reported back via RSL.</span><br><span style="color: hsl(120, 100%, 40%);">+ * this is ok, since we have nothing to report anyway and apart of that</span><br><span style="color: hsl(120, 100%, 40%);">+ * we also just lost the signal (otherwise we would have at least some</span><br><span style="color: hsl(120, 100%, 40%);">+ * measurements). */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!lchan->meas.num_ul_meas)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* initialize min/max values with their counterpart */</span><br><span> lchan->meas.ext.toa256_min = INT16_MAX;</span><br><span> lchan->meas.ext.toa256_max = INT16_MIN;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(lchan->meas.num_ul_meas);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Determine the number of measurement values we need to take into the</span><br><span style="color: hsl(120, 100%, 40%);">+ * computation. In this case we only compute over the measurements we</span><br><span style="color: hsl(120, 100%, 40%);">+ * have indeed received. Since this computation is about timing</span><br><span style="color: hsl(120, 100%, 40%);">+ * information it does not make sense to approach missing measurement</span><br><span style="color: hsl(120, 100%, 40%);">+ * samples the TOA with 0. This would bend the average towards 0. What</span><br><span style="color: hsl(120, 100%, 40%);">+ * counts is the average TOA of the properly received blocks so that</span><br><span style="color: hsl(120, 100%, 40%);">+ * the TA logic can make a proper decision. */</span><br><span style="color: hsl(120, 100%, 40%);">+ num_ul_meas_expect = lchan_meas_num_expected(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->meas.num_ul_meas > num_ul_meas_expect) {</span><br><span style="color: hsl(120, 100%, 40%);">+ num_ul_meas = num_ul_meas_expect;</span><br><span style="color: hsl(120, 100%, 40%);">+ num_ul_meas_excess = lchan->meas.num_ul_meas - num_ul_meas_expect;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ num_ul_meas = lchan->meas.num_ul_meas;</span><br><span> </span><br><span> /* all computations are done on the relative arrival time of the burst, relative to the</span><br><span> * beginning of its slot. This is of course excluding the TA value that the MS has already</span><br><span> * compensated/pre-empted its transmission */</span><br><span> </span><br><span> /* step 1: compute the sum of the squared difference of each value to mean */</span><br><span style="color: hsl(0, 100%, 40%);">- for (i = 0; i < lchan->meas.num_ul_meas; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">- struct bts_ul_meas *m = &lchan->meas.uplink[i];</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < num_ul_meas; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct bts_ul_meas *m;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(i < lchan->meas.num_ul_meas);</span><br><span style="color: hsl(120, 100%, 40%);">+ m = &lchan->meas.uplink[i+num_ul_meas_excess];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int32_t diff = (int32_t)m->ta_offs_256bits - (int32_t)lchan->meas.ms_toa256;</span><br><span> /* diff can now be any value of +65535 to -65535, so we can safely square it,</span><br><span> * but only in unsigned math. As squaring looses the sign, we can simply drop</span><br><span>@@ -517,7 +622,7 @@</span><br><span> lchan->meas.ext.toa256_min = m->ta_offs_256bits;</span><br><span> }</span><br><span> /* step 2: compute the variance (mean of sum of squared differences) */</span><br><span style="color: hsl(0, 100%, 40%);">- sq_diff_sum = sq_diff_sum / lchan->meas.num_ul_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+ sq_diff_sum = sq_diff_sum / num_ul_meas;</span><br><span> /* as the individual summed values can each not exceed 2^32, and we're</span><br><span> * dividing by the number of summands, the resulting value can also not exceed 2^32 */</span><br><span> OSMO_ASSERT(sq_diff_sum <= UINT32_MAX);</span><br><span>@@ -535,54 +640,137 @@</span><br><span> uint32_t irssi_sub_sum = 0;</span><br><span> int32_t ta256b_sum = 0;</span><br><span> unsigned int num_meas_sub = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_meas_sub_actual = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_meas_sub_subst = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_meas_sub_expect;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_ul_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_ul_meas_actual = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_ul_meas_subst = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_ul_meas_expect;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_ul_meas_excess = 0;</span><br><span> int i;</span><br><span> </span><br><span> /* if measurement period is not complete, abort */</span><br><span> if (!is_meas_complete(lchan, fn))</span><br><span> return 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* if there are no measurements, skip computation */</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan->meas.num_ul_meas == 0)</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMEAS, LOGL_DEBUG, "%s Calculating measurement results for physical channel:%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm_lchan_name(lchan), gsm_pchan_name(ts_pchan(lchan->ts)));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* compute the actual measurements */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Note: Some phys will send no measurement indication at all</span><br><span style="color: hsl(120, 100%, 40%);">+ * when a block is lost. Also in DTX mode blocks are left out</span><br><span style="color: hsl(120, 100%, 40%);">+ * intentionally to save energy. It is not necessarly an error</span><br><span style="color: hsl(120, 100%, 40%);">+ * when we get less measurements as we expect. */</span><br><span style="color: hsl(120, 100%, 40%);">+ num_ul_meas_expect = lchan_meas_num_expected(lchan);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* step 1: add up */</span><br><span style="color: hsl(0, 100%, 40%);">- for (i = 0; i < lchan->meas.num_ul_meas; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">- struct bts_ul_meas *m = &lchan->meas.uplink[i];</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR)</span><br><span style="color: hsl(120, 100%, 40%);">+ num_meas_sub_expect = lchan_meas_sub_num_expected(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+ else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: the amount of SUB Measurements is a dynamic parameter</span><br><span style="color: hsl(120, 100%, 40%);">+ * in AMR and can not be determined by using a lookup table.</span><br><span style="color: hsl(120, 100%, 40%);">+ * See also: OS#2978 */</span><br><span style="color: hsl(120, 100%, 40%);">+ num_meas_sub_expect = 0;</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%);">+ if (lchan->meas.num_ul_meas > num_ul_meas_expect)</span><br><span style="color: hsl(120, 100%, 40%);">+ num_ul_meas_excess = lchan->meas.num_ul_meas - num_ul_meas_expect;</span><br><span style="color: hsl(120, 100%, 40%);">+ num_ul_meas = num_ul_meas_expect;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMEAS, LOGL_DEBUG, "%s received %u UL measurements, expected %u\n", gsm_lchan_name(lchan),</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->meas.num_ul_meas, num_ul_meas_expect);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (num_ul_meas_excess)</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMEAS, LOGL_DEBUG, "%s received %u excess UL measurements\n", gsm_lchan_name(lchan),</span><br><span style="color: hsl(120, 100%, 40%);">+ num_ul_meas_excess);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Measurement computation step 1: add up */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < num_ul_meas; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct bts_ul_meas *m;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool is_sub = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Note: We will always compute over a full measurement,</span><br><span style="color: hsl(120, 100%, 40%);">+ * interval even when not enough measurement samples are in</span><br><span style="color: hsl(120, 100%, 40%);">+ * the buffer. As soon as we run out of measurement values</span><br><span style="color: hsl(120, 100%, 40%);">+ * we continue the calculation using dummy values. This works</span><br><span style="color: hsl(120, 100%, 40%);">+ * well for the BER, since there we can safely assume 100%</span><br><span style="color: hsl(120, 100%, 40%);">+ * since a missing measurement means that the data (block)</span><br><span style="color: hsl(120, 100%, 40%);">+ * is lost as well (some phys do not give us measurement</span><br><span style="color: hsl(120, 100%, 40%);">+ * reports for lost blocks or blocks that are spaced out for</span><br><span style="color: hsl(120, 100%, 40%);">+ * DTX). However, for RSSI and TA this does not work since</span><br><span style="color: hsl(120, 100%, 40%);">+ * there we would distort the calculation if we would replace</span><br><span style="color: hsl(120, 100%, 40%);">+ * them with a made up number. This means for those values we</span><br><span style="color: hsl(120, 100%, 40%);">+ * only compute over the data we have actually received. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (i < lchan->meas.num_ul_meas) {</span><br><span style="color: hsl(120, 100%, 40%);">+ m = &lchan->meas.uplink[i + num_ul_meas_excess];</span><br><span style="color: hsl(120, 100%, 40%);">+ if (m->is_sub) {</span><br><span style="color: hsl(120, 100%, 40%);">+ irssi_sub_sum += m->inv_rssi;</span><br><span style="color: hsl(120, 100%, 40%);">+ num_meas_sub_actual++;</span><br><span style="color: hsl(120, 100%, 40%);">+ is_sub = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ irssi_full_sum += m->inv_rssi;</span><br><span style="color: hsl(120, 100%, 40%);">+ ta256b_sum += m->ta_offs_256bits;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ num_ul_meas_actual++;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ m = &measurement_dummy;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (num_ul_meas_expect - i <= num_meas_sub_expect - num_meas_sub) {</span><br><span style="color: hsl(120, 100%, 40%);">+ num_meas_sub_subst++;</span><br><span style="color: hsl(120, 100%, 40%);">+ is_sub = true;</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%);">+ num_ul_meas_subst++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span> ber_full_sum += m->ber10k;</span><br><span style="color: hsl(0, 100%, 40%);">- irssi_full_sum += m->inv_rssi;</span><br><span style="color: hsl(0, 100%, 40%);">- ta256b_sum += m->ta_offs_256bits;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (m->is_sub) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (is_sub) {</span><br><span> num_meas_sub++;</span><br><span> ber_sub_sum += m->ber10k;</span><br><span style="color: hsl(0, 100%, 40%);">- irssi_sub_sum += m->inv_rssi;</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* step 2: divide */</span><br><span style="color: hsl(0, 100%, 40%);">- ber_full_sum = ber_full_sum / lchan->meas.num_ul_meas;</span><br><span style="color: hsl(0, 100%, 40%);">- irssi_full_sum = irssi_full_sum / lchan->meas.num_ul_meas;</span><br><span style="color: hsl(0, 100%, 40%);">- ta256b_sum = ta256b_sum / lchan->meas.num_ul_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMEAS, LOGL_DEBUG, "%s received UL measurements contain %u SUB measurements, expected %u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm_lchan_name(lchan), num_meas_sub_actual, num_meas_sub_expect);</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMEAS, LOGL_DEBUG, "%s replaced %u measurements with dummy values, from which %u were SUB measurements\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm_lchan_name(lchan), num_ul_meas_subst, num_meas_sub_subst);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (num_meas_sub) {</span><br><span style="color: hsl(0, 100%, 40%);">- ber_sub_sum = ber_sub_sum / num_meas_sub;</span><br><span style="color: hsl(0, 100%, 40%);">- irssi_sub_sum = irssi_sub_sum / num_meas_sub;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DMEAS, LOGL_ERROR, "%s No measurements for SUB!!!\n", gsm_lchan_name(lchan));</span><br><span style="color: hsl(0, 100%, 40%);">- /* The only situation in which this can occur is if the related uplink burst/block was</span><br><span style="color: hsl(0, 100%, 40%);">- * missing, so let's set BER to 100% and level to lowest possible. */</span><br><span style="color: hsl(0, 100%, 40%);">- ber_sub_sum = 10000; /* 100% */</span><br><span style="color: hsl(0, 100%, 40%);">- irssi_sub_sum = 120; /* -120 dBm */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (num_meas_sub != num_meas_sub_expect) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMEAS, LOGL_ERROR, "%s Incorrect number of SUB measurements detected!\n", gsm_lchan_name(lchan));</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Normally the logic above should make sure that there is</span><br><span style="color: hsl(120, 100%, 40%);">+ * always the exact amount of SUB measurements taken into</span><br><span style="color: hsl(120, 100%, 40%);">+ * account. If not then the logic that decides tags the received</span><br><span style="color: hsl(120, 100%, 40%);">+ * measurements as is_sub works incorrectly. Since the logic</span><br><span style="color: hsl(120, 100%, 40%);">+ * above only adds missing measurements during the calculation</span><br><span style="color: hsl(120, 100%, 40%);">+ * it can not remove excess SUB measurements or add missing SUB</span><br><span style="color: hsl(120, 100%, 40%);">+ * measurements when there is no more room in the interval. */</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Measurement computation step 2: divide */</span><br><span style="color: hsl(120, 100%, 40%);">+ ber_full_sum = ber_full_sum / num_ul_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!irssi_full_sum)</span><br><span style="color: hsl(120, 100%, 40%);">+ ber_full_sum = MEASUREMENT_DUMMY_IRSSI;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ irssi_full_sum = irssi_full_sum / num_ul_meas_actual;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!num_ul_meas_actual)</span><br><span style="color: hsl(120, 100%, 40%);">+ ta256b_sum = lchan->meas.ms_toa256;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ ta256b_sum = ta256b_sum / num_ul_meas_actual;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!num_meas_sub)</span><br><span style="color: hsl(120, 100%, 40%);">+ ber_sub_sum = MEASUREMENT_DUMMY_BER;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ ber_sub_sum = ber_sub_sum / num_meas_sub;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!num_meas_sub_actual)</span><br><span style="color: hsl(120, 100%, 40%);">+ irssi_sub_sum = MEASUREMENT_DUMMY_IRSSI;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ irssi_sub_sum = irssi_sub_sum / num_meas_sub_actual;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> LOGP(DMEAS, LOGL_INFO, "%s Computed TA256(% 4d) BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), "</span><br><span style="color: hsl(0, 100%, 40%);">- "BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm)\n", gsm_lchan_name(lchan),</span><br><span style="color: hsl(0, 100%, 40%);">- ta256b_sum, ber_full_sum/100,</span><br><span style="color: hsl(0, 100%, 40%);">- ber_full_sum%100, irssi_full_sum, ber_sub_sum/100, ber_sub_sum%100,</span><br><span style="color: hsl(0, 100%, 40%);">- irssi_sub_sum);</span><br><span style="color: hsl(120, 100%, 40%);">+ "BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm)\n", gsm_lchan_name(lchan),</span><br><span style="color: hsl(120, 100%, 40%);">+ ta256b_sum, ber_full_sum / 100,</span><br><span style="color: hsl(120, 100%, 40%);">+ ber_full_sum % 100, irssi_full_sum, ber_sub_sum / 100, ber_sub_sum % 100, irssi_sub_sum);</span><br><span> </span><br><span> /* store results */</span><br><span> mru = &lchan->meas.ul_res;</span><br><span>@@ -593,20 +781,18 @@</span><br><span> lchan->meas.ms_toa256 = ta256b_sum;</span><br><span> </span><br><span> LOGP(DMEAS, LOGL_INFO, "%s UL MEAS RXLEV_FULL(%u), RXLEV_SUB(%u),"</span><br><span style="color: hsl(0, 100%, 40%);">- "RXQUAL_FULL(%u), RXQUAL_SUB(%u), num_meas_sub(%u), num_ul_meas(%u) \n",</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_lchan_name(lchan),</span><br><span style="color: hsl(0, 100%, 40%);">- mru->full.rx_lev,</span><br><span style="color: hsl(0, 100%, 40%);">- mru->sub.rx_lev,</span><br><span style="color: hsl(0, 100%, 40%);">- mru->full.rx_qual,</span><br><span style="color: hsl(0, 100%, 40%);">- mru->sub.rx_qual, num_meas_sub, lchan->meas.num_ul_meas);</span><br><span style="color: hsl(120, 100%, 40%);">+ "RXQUAL_FULL(%u), RXQUAL_SUB(%u), num_meas_sub(%u), num_ul_meas(%u) \n",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm_lchan_name(lchan),</span><br><span style="color: hsl(120, 100%, 40%);">+ mru->full.rx_lev, mru->sub.rx_lev, mru->full.rx_qual, mru->sub.rx_qual, num_meas_sub, num_ul_meas_expect);</span><br><span> </span><br><span> lchan->meas.flags |= LC_UL_M_F_RES_VALID;</span><br><span> </span><br><span> lchan_meas_compute_extended(lchan);</span><br><span> </span><br><span> lchan->meas.num_ul_meas = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- /* send a signal indicating computation is complete */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* return 1 to indicte that the computation has been done and the next</span><br><span style="color: hsl(120, 100%, 40%);">+ * interval begins. */</span><br><span> return 1;</span><br><span> }</span><br><span> </span><br><span>diff --git a/tests/meas/meas_test.c b/tests/meas/meas_test.c</span><br><span>index b90227a..c397ddd 100644</span><br><span>--- a/tests/meas/meas_test.c</span><br><span>+++ b/tests/meas/meas_test.c</span><br><span>@@ -24,6 +24,7 @@</span><br><span> #include "sysmobts_fr_samples.h"</span><br><span> #include "meas_testcases.h"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void test_fn_sample(struct fn_sample *s, unsigned int len, uint8_t pchan, uint8_t tsmap)</span><br><span> {</span><br><span> int rc;</span><br><span>@@ -73,13 +74,16 @@</span><br><span> </span><br><span> static void test_meas_compute(const struct meas_testcase *mtc)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm_lchan *lchan = &trx->ts[1].lchan[0];</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_lchan *lchan;</span><br><span> unsigned int i;</span><br><span> unsigned int fn = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- printf("\nMeasurement Compute Test %s\n", mtc->name);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("\n\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("===========================================================\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Measurement Compute Test: %s\n", mtc->name);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- lchan->ts->pchan = GSM_PCHAN_TCH_F;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan = &trx->ts[mtc->ts].lchan[0];</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->ts->pchan = mtc->pchan;</span><br><span> reset_lchan_meas(lchan);</span><br><span> </span><br><span> /* feed uplink measurements into the code */</span><br><span>@@ -94,6 +98,8 @@</span><br><span> OSMO_ASSERT(!(lchan->meas.flags & LC_UL_M_F_RES_VALID));</span><br><span> } else {</span><br><span> OSMO_ASSERT(lchan->meas.flags & (LC_UL_M_F_RES_VALID|LC_UL_M_F_OSMO_EXT_VALID));</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("number of measurements: %u\n", mtc->ulm_count);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("parameter | actual | expected\n");</span><br><span> printf("meas.ext.toa256_min | %6d | %6d\n",</span><br><span> lchan->meas.ext.toa256_min, mtc->res.toa256_min);</span><br><span> printf("meas.ext.toa256_max | %6d | %6d\n",</span><br><span>@@ -113,6 +119,7 @@</span><br><span> (lchan->meas.ext.toa256_std_dev != mtc->res.toa256_std_dev) ||</span><br><span> (lchan->meas.ul_res.full.rx_lev != mtc->res.rx_lev_full)) {</span><br><span> fprintf(stderr, "%s: Unexpected measurement result!\n", mtc->name);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(false);</span><br><span> }</span><br><span> }</span><br><span> </span><br><span>@@ -1121,6 +1128,15 @@</span><br><span> test_meas_compute(&mtc3);</span><br><span> test_meas_compute(&mtc4);</span><br><span> test_meas_compute(&mtc5);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc_tch_f_complete);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc_tch_f_dtx_with_lost_subs);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc_tch_f_dtx);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc_tch_h_complete);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc_tch_h_dtx_with_lost_subs);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc_tch_h_dtx);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc_overrun);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc_sdcch4_complete);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc_sdcch8_complete);</span><br><span> </span><br><span> printf("\n");</span><br><span> printf("***************************************************\n");</span><br><span>diff --git a/tests/meas/meas_test.ok b/tests/meas/meas_test.ok</span><br><span>index 58e527a..86d8d87 100644</span><br><span>--- a/tests/meas/meas_test.ok</span><br><span>+++ b/tests/meas/meas_test.ok</span><br><span>@@ -540,33 +540,167 @@</span><br><span> Testing: ts[7]->lchan[0], fn=15170=>015170/11/12/23/14, fn%104=90, rc=1, delta=91</span><br><span> Testing: ts[7]->lchan[1], fn=15183=>015183/11/25/36/27, fn%104=103, rc=1, delta=13</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-Measurement Compute Test TOA256 Min-Max negative/positive</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%);">+Measurement Compute Test: TOA256 Min-Max negative/positive</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 3</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span> meas.ext.toa256_min | -256 | -256</span><br><span> meas.ext.toa256_max | 256 | 256</span><br><span> meas.ms_toa256 | 0 | 0</span><br><span> meas.ext.toa256_std_dev | 209 | 209</span><br><span> meas.ul_res.full.rx_lev | 20 | 20</span><br><span style="color: hsl(0, 100%, 40%);">-meas.ul_res.full.rx_qual | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 7 | 0</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-Measurement Compute Test TOA256 small jitter around 256</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%);">+Measurement Compute Test: TOA256 small jitter around 256</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 25</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span> meas.ext.toa256_min | 254 | 254</span><br><span> meas.ext.toa256_max | 258 | 258</span><br><span> meas.ms_toa256 | 256 | 256</span><br><span> meas.ext.toa256_std_dev | 1 | 1</span><br><span> meas.ul_res.full.rx_lev | 20 | 20</span><br><span style="color: hsl(0, 100%, 40%);">-meas.ul_res.full.rx_qual | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 0 | 7</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-Measurement Compute Test RxLEv averaging</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%);">+Measurement Compute Test: RxLEv averaging</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 5</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span> meas.ext.toa256_min | 0 | 0</span><br><span> meas.ext.toa256_max | 0 | 0</span><br><span> meas.ms_toa256 | 0 | 0</span><br><span> meas.ext.toa256_std_dev | 0 | 0</span><br><span> meas.ul_res.full.rx_lev | 20 | 20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 7 | 0</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 style="color: hsl(120, 100%, 40%);">+Measurement Compute Test: Empty measurements</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 0</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256 | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev | 63 | 63</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 3 | 3</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 style="color: hsl(120, 100%, 40%);">+Measurement Compute Test: TOA256 26 blocks with max TOA256</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 26</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256 | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev | 20 | 20</span><br><span> meas.ul_res.full.rx_qual | 0 | 0</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-Measurement Compute Test Empty measurements</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-Measurement Compute Test TOA256 26 blocks with max TOA256</span><br><span style="color: hsl(120, 100%, 40%);">+===========================================================</span><br><span style="color: hsl(120, 100%, 40%);">+Measurement Compute Test: Complete TCH/F measurement period (26 measurements, 3 sub-frames)</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 25</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256 | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev | 20 | 20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 0 | 0</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 style="color: hsl(120, 100%, 40%);">+Measurement Compute Test: Incomplete TCH/F measurement period (16 measurements, 1 sub-frame)</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 16</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256 | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev | 20 | 20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 7 | 7</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 style="color: hsl(120, 100%, 40%);">+Measurement Compute Test: Incomplete but normal TCH/F measurement period (16 measurements, 3 sub-frames)</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 16</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256 | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev | 20 | 20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 7 | 7</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 style="color: hsl(120, 100%, 40%);">+Measurement Compute Test: Complete TCH/H measurement period (26 measurements, 5 sub-frames)</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 25</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256 | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev | 20 | 20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 0 | 0</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 style="color: hsl(120, 100%, 40%);">+Measurement Compute Test: Incomplete TCH/H measurement period (14 measurements, 3 sub-frames)</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 14</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256 | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev | 20 | 20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 7 | 7</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 style="color: hsl(120, 100%, 40%);">+Measurement Compute Test: Incomplete but normal TCH/F measurement period (16 measurements, 5 sub-frames)</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 16</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256 | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev | 20 | 20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 7 | 7</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 style="color: hsl(120, 100%, 40%);">+Measurement Compute Test: TCH/F measurement period with too much measurement values (overrun)</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 59</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256 | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev | 20 | 20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 0 | 0</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 style="color: hsl(120, 100%, 40%);">+Measurement Compute Test: Complete SDCCH4 measurement period (3 measurements)</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 3</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256 | 16384 | 16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev | 0 | 0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev | 20 | 20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual | 0 | 0</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 style="color: hsl(120, 100%, 40%);">+Measurement Compute Test: Complete SDCCH8 measurement period (3 measurements)</span><br><span style="color: hsl(120, 100%, 40%);">+number of measurements: 3</span><br><span style="color: hsl(120, 100%, 40%);">+parameter | actual | expected</span><br><span> meas.ext.toa256_min | 16384 | 16384</span><br><span> meas.ext.toa256_max | 16384 | 16384</span><br><span> meas.ms_toa256 | 16384 | 16384</span><br><span>diff --git a/tests/meas/meas_testcases.h b/tests/meas/meas_testcases.h</span><br><span>index ff74a20..fefa34f 100644</span><br><span>--- a/tests/meas/meas_testcases.h</span><br><span>+++ b/tests/meas/meas_testcases.h</span><br><span>@@ -1,5 +1,5 @@</span><br><span style="color: hsl(0, 100%, 40%);">-#define ULM(ber, ta, neg_rssi) \</span><br><span style="color: hsl(0, 100%, 40%);">- { .ber10k = (ber), .ta_offs_256bits = (ta), .c_i = 1.0, .is_sub = 0, .inv_rssi = (neg_rssi) }</span><br><span style="color: hsl(120, 100%, 40%);">+#define ULM(ber, ta, sub, neg_rssi) \</span><br><span style="color: hsl(120, 100%, 40%);">+ { .ber10k = (ber), .ta_offs_256bits = (ta), .c_i = 1.0, .is_sub = sub, .inv_rssi = (neg_rssi) }</span><br><span> </span><br><span> struct meas_testcase {</span><br><span> const char *name;</span><br><span>@@ -7,6 +7,8 @@</span><br><span> const struct bts_ul_meas *ulm;</span><br><span> unsigned int ulm_count;</span><br><span> uint32_t final_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t ts;</span><br><span style="color: hsl(120, 100%, 40%);">+ enum gsm_phys_chan_config pchan;</span><br><span> /* results */</span><br><span> struct {</span><br><span> int success;</span><br><span>@@ -20,15 +22,21 @@</span><br><span> };</span><br><span> </span><br><span> static struct bts_ul_meas ulm1[] = {</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 0, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, -256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Note: The assumptions about the frame number and the subset</span><br><span style="color: hsl(120, 100%, 40%);">+ * allegiance is random since for the calculation only the amount</span><br><span style="color: hsl(120, 100%, 40%);">+ * is of relevance. This is true for all following testcases */</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 0, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, -256, 0, 90),</span><br><span> };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static const struct meas_testcase mtc1 = {</span><br><span> .name = "TOA256 Min-Max negative/positive",</span><br><span> .ulm = ulm1,</span><br><span> .ulm_count = ARRAY_SIZE(ulm1),</span><br><span> .final_fn = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_F,</span><br><span> .res = {</span><br><span> .success = 1,</span><br><span> .rx_lev_full = 110-90,</span><br><span>@@ -41,22 +49,44 @@</span><br><span> };</span><br><span> </span><br><span> static struct bts_ul_meas ulm2[] = {</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 258, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 254, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 258, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 254, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 258, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 254, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 258, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 254, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 258, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 254, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 258, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 254, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 258, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 254, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 258, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 254, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 258, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 254, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 258, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 254, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 256, 0, 90),</span><br><span> };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static const struct meas_testcase mtc2 = {</span><br><span> .name = "TOA256 small jitter around 256",</span><br><span> .ulm = ulm2,</span><br><span> .ulm_count = ARRAY_SIZE(ulm2),</span><br><span> .final_fn = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_F,</span><br><span> .res = {</span><br><span> .success = 1,</span><br><span> .rx_lev_full = 110-90,</span><br><span style="color: hsl(0, 100%, 40%);">- .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_qual_full = 7,</span><br><span> .toa256_mean = 256,</span><br><span> .toa256_max = 258,</span><br><span> .toa256_min = 254,</span><br><span>@@ -65,17 +95,20 @@</span><br><span> };</span><br><span> </span><br><span> static struct bts_ul_meas ulm3[] = {</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 0, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 0, 80),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 0, 80),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 0, 100),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 0, 100),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 0, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 0, 0, 80),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 0, 0, 80),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 0, 0, 100),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 0, 0, 100),</span><br><span> };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static const struct meas_testcase mtc3 = {</span><br><span> .name = "RxLEv averaging",</span><br><span> .ulm = ulm3,</span><br><span> .ulm_count = ARRAY_SIZE(ulm3),</span><br><span> .final_fn = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_F,</span><br><span> .res = {</span><br><span> .success = 1,</span><br><span> .rx_lev_full = 110-90,</span><br><span>@@ -88,15 +121,18 @@</span><br><span> };</span><br><span> </span><br><span> static struct bts_ul_meas ulm4[] = {};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static const struct meas_testcase mtc4 = {</span><br><span> .name = "Empty measurements",</span><br><span> .ulm = ulm4,</span><br><span> .ulm_count = ARRAY_SIZE(ulm4),</span><br><span> .final_fn = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_F,</span><br><span> .res = {</span><br><span style="color: hsl(0, 100%, 40%);">- .success = 0,</span><br><span style="color: hsl(0, 100%, 40%);">- .rx_lev_full = 0,</span><br><span style="color: hsl(0, 100%, 40%);">- .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_lev_full = 63,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_qual_full = 3,</span><br><span> .toa256_mean = 0,</span><br><span> .toa256_max = 0,</span><br><span> .toa256_min = 0,</span><br><span>@@ -107,38 +143,41 @@</span><br><span> static struct bts_ul_meas ulm5[] = {</span><br><span> /* one 104 multiframe can at max contain 26 blocks (TCH/F),</span><br><span> * each of which can at maximum be 64 bits in advance (TA range) */</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(0, 100%, 40%);">- ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span> };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static const struct meas_testcase mtc5 = {</span><br><span> .name = "TOA256 26 blocks with max TOA256",</span><br><span> .ulm = ulm5,</span><br><span> .ulm_count = ARRAY_SIZE(ulm5),</span><br><span> .final_fn = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_F,</span><br><span> .res = {</span><br><span> .success = 1,</span><br><span> .rx_lev_full = 110-90,</span><br><span>@@ -149,3 +188,391 @@</span><br><span> .toa256_std_dev = 0,</span><br><span> },</span><br><span> };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* This testcase models a good case as we can see it when all TCH</span><br><span style="color: hsl(120, 100%, 40%);">+ * and SACCH blocks are received */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm_tch_f_complete[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</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%);">+static const struct meas_testcase mtc_tch_f_complete = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "Complete TCH/F measurement period (26 measurements, 3 sub-frames)",</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm = ulm_tch_f_complete,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm_count = ARRAY_SIZE(ulm_tch_f_complete),</span><br><span style="color: hsl(120, 100%, 40%);">+ .final_fn = 38,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_F,</span><br><span style="color: hsl(120, 100%, 40%);">+ .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_lev_full = 20,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_mean = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_max = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_min = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_std_dev = 0,</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 style="color: hsl(120, 100%, 40%);">+/* This testcase models an error case where two of 3 expected sub measurements</span><br><span style="color: hsl(120, 100%, 40%);">+ * are lost. The calculation logic must detect this and replace those</span><br><span style="color: hsl(120, 100%, 40%);">+ * measurements. Note that this example also lacks some blocks due to DTX,</span><br><span style="color: hsl(120, 100%, 40%);">+ * which is normal. */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm_tch_f_dtx_with_lost_subs[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</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%);">+static const struct meas_testcase mtc_tch_f_dtx_with_lost_subs = {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* This testcase models a good case as we can see it when all TCH</span><br><span style="color: hsl(120, 100%, 40%);">+ * and SACCH blocks are received */</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "Incomplete TCH/F measurement period (16 measurements, 1 sub-frame)",</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm = ulm_tch_f_dtx_with_lost_subs,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm_count = ARRAY_SIZE(ulm_tch_f_dtx_with_lost_subs),</span><br><span style="color: hsl(120, 100%, 40%);">+ .final_fn = 38,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_F,</span><br><span style="color: hsl(120, 100%, 40%);">+ .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_lev_full = 20,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_qual_full = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_mean = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_max = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_min = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_std_dev = 0,</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 style="color: hsl(120, 100%, 40%);">+/* This testcase models a good-case with DTX. Some measurements are missing</span><br><span style="color: hsl(120, 100%, 40%);">+ * because no block was transmitted, all sub measurements are there. */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm_tch_f_dtx[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</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%);">+static const struct meas_testcase mtc_tch_f_dtx = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "Incomplete but normal TCH/F measurement period (16 measurements, 3 sub-frames)",</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm = ulm_tch_f_dtx,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm_count = ARRAY_SIZE(ulm_tch_f_dtx),</span><br><span style="color: hsl(120, 100%, 40%);">+ .final_fn = 38,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_F,</span><br><span style="color: hsl(120, 100%, 40%);">+ .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_lev_full = 20,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_qual_full = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_mean = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_max = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_min = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_std_dev = 0,</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 style="color: hsl(120, 100%, 40%);">+/* This testcase models a good case as we can see it when all TCH</span><br><span style="color: hsl(120, 100%, 40%);">+ * and SACCH blocks are received */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm_tch_h_complete[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</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%);">+static const struct meas_testcase mtc_tch_h_complete = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "Complete TCH/H measurement period (26 measurements, 5 sub-frames)",</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm = ulm_tch_h_complete,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm_count = ARRAY_SIZE(ulm_tch_h_complete),</span><br><span style="color: hsl(120, 100%, 40%);">+ .final_fn = 38,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_H,</span><br><span style="color: hsl(120, 100%, 40%);">+ .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_lev_full = 110 - 90,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_mean = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_max = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_min = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_std_dev = 0,</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 style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm_tch_h_dtx_with_lost_subs[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</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%);">+static const struct meas_testcase mtc_tch_h_dtx_with_lost_subs = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "Incomplete TCH/H measurement period (14 measurements, 3 sub-frames)",</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm = ulm_tch_h_dtx_with_lost_subs,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm_count = ARRAY_SIZE(ulm_tch_h_dtx_with_lost_subs),</span><br><span style="color: hsl(120, 100%, 40%);">+ .final_fn = 38,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_H,</span><br><span style="color: hsl(120, 100%, 40%);">+ .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_lev_full = 20,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_qual_full = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_mean = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_max = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_min = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_std_dev = 0,</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 style="color: hsl(120, 100%, 40%);">+/* This testcase models a good-case with DTX. Some measurements are missing</span><br><span style="color: hsl(120, 100%, 40%);">+ * because no block was transmitted, all sub measurements are there. */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm_tch_h_dtx[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</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%);">+static const struct meas_testcase mtc_tch_h_dtx = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "Incomplete but normal TCH/F measurement period (16 measurements, 5 sub-frames)",</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm = ulm_tch_h_dtx,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm_count = ARRAY_SIZE(ulm_tch_h_dtx),</span><br><span style="color: hsl(120, 100%, 40%);">+ .final_fn = 38,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_H,</span><br><span style="color: hsl(120, 100%, 40%);">+ .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_lev_full = 20,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_qual_full = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_mean = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_max = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_min = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_std_dev = 0,</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 style="color: hsl(120, 100%, 40%);">+/* This testcase assumes that too many measurements were collected. This can</span><br><span style="color: hsl(120, 100%, 40%);">+ * happen when the measurement calculation for a previous cycle were not</span><br><span style="color: hsl(120, 100%, 40%);">+ * executed. In this case the older part of the excess data must be discarded.</span><br><span style="color: hsl(120, 100%, 40%);">+ * the calculation algorithm must make sure that the calculation only takes</span><br><span style="color: hsl(120, 100%, 40%);">+ * place on the last measurement interval */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm_overrun[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ /* All measurements above must be discarded */</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 0, 90),</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%);">+static const struct meas_testcase mtc_overrun = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "TCH/F measurement period with too much measurement values (overrun)",</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm = ulm_overrun,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm_count = ARRAY_SIZE(ulm_overrun),</span><br><span style="color: hsl(120, 100%, 40%);">+ .final_fn = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_TCH_F,</span><br><span style="color: hsl(120, 100%, 40%);">+ .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_lev_full = 110 - 90,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_mean = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_max = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_min = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_std_dev = 0,</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 style="color: hsl(120, 100%, 40%);">+/* Test SDCCH4 with all frames received */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm_sdcch4_complete[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</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%);">+static const struct meas_testcase mtc_sdcch4_complete = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "Complete SDCCH4 measurement period (3 measurements)",</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm = ulm_sdcch4_complete,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm_count = ARRAY_SIZE(ulm_sdcch4_complete),</span><br><span style="color: hsl(120, 100%, 40%);">+ .final_fn = 88,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_CCCH_SDCCH4,</span><br><span style="color: hsl(120, 100%, 40%);">+ .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_lev_full = 20,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_mean = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_max = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_min = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_std_dev = 0,</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 style="color: hsl(120, 100%, 40%);">+/* Test SDCCH8 with all frames received */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm_sdcch8_complete[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+ ULM(0, 64*256, 1, 90),</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%);">+static const struct meas_testcase mtc_sdcch8_complete = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "Complete SDCCH8 measurement period (3 measurements)",</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm = ulm_sdcch8_complete,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm_count = ARRAY_SIZE(ulm_sdcch8_complete),</span><br><span style="color: hsl(120, 100%, 40%);">+ .final_fn = 66,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ts = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pchan = GSM_PCHAN_SDCCH8_SACCH8C,</span><br><span style="color: hsl(120, 100%, 40%);">+ .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_lev_full = 20,</span><br><span style="color: hsl(120, 100%, 40%);">+ .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_mean = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_max = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_min = 16384,</span><br><span style="color: hsl(120, 100%, 40%);">+ .toa256_std_dev = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10476">change 10476</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/10476"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-bts </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Idd30fc07603ad7d042c1fb416e247c3bf7d35c8b </div>
<div style="display:none"> Gerrit-Change-Number: 10476 </div>
<div style="display:none"> Gerrit-PatchSet: 7 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: dexter <pmaier@sysmocom.de> </div>