Change in osmo-bts[master]: scheduler_trx: fix RSSI calculation for SUB frames

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

dexter gerrit-no-reply at lists.osmocom.org
Mon May 4 18:55:19 UTC 2020


dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/18035 )


Change subject: scheduler_trx: fix RSSI calculation for SUB frames
......................................................................

scheduler_trx: fix RSSI calculation for SUB frames

Currently the RSSI value of the burst that concludes a block is passed
up to the higher layer. However, this also means that the RSSI values of
the other bursts are skipped. Lets keep record of all RSSI values and
average the values before we pass them up to the higher layers.

Also lets make sure that we pick the correct RSSI measurements when we
calculate the RSSI values for the AMR SID frames (SUB frames).

Change-Id: I902bb47d68742d2589156f61099b67a0edbaf40b
Related: OS#2978
---
M include/osmo-bts/scheduler.h
M src/osmo-bts-trx/scheduler_trx.c
2 files changed, 179 insertions(+), 10 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/35/18035/1

diff --git a/include/osmo-bts/scheduler.h b/include/osmo-bts/scheduler.h
index c026411..4462566 100644
--- a/include/osmo-bts/scheduler.h
+++ b/include/osmo-bts/scheduler.h
@@ -76,6 +76,7 @@
 	ubit_t			*dl_bursts;	/* burst buffer for TX */
 	enum trx_burst_type	dl_burst_type;  /* GMSK or 8PSK burst type */
 	sbit_t			*ul_bursts;	/* burst buffer for RX */
+	int8_t			ul_rssi[8];	/* rssi meas buffer for RX */
 	uint32_t		ul_first_fn;	/* fn of first burst */
 	uint8_t			ul_mask;	/* mask of received bursts */
 
diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c
index 8c3dd64..09b00bc 100644
--- a/src/osmo-bts-trx/scheduler_trx.c
+++ b/src/osmo-bts-trx/scheduler_trx.c
@@ -1120,6 +1120,98 @@
 					  PRES_INFO_BOTH);
 }
 
+/* Modes that can be used with function calc_rssi_avg() */
+enum rssi_calc_mode {
+	RSSI_FR_LOWER_FOUR,
+	RSSI_FR_HIGHER_FOUR,
+	RSSI_HR_ALL,
+	RSSI_HR_LOWER_TWO,
+	RSSI_HR_MID_TWO,
+};
+
+/* A handy function to calculate the RSSI for received bursts in various
+ * different modes. */
+static int8_t calc_rssi_avg(int8_t * rssi_values, enum rssi_calc_mode mode,
+			    struct gsm_lchan *lchan)
+{
+	int rssi_sum = 0;
+	int rssi_count = 0;
+	int8_t rc;
+	unsigned int i;
+	int8_t *r = rssi_values;
+
+	switch (mode) {
+	case RSSI_FR_LOWER_FOUR:
+		rssi_count = 4;
+		break;
+	case RSSI_FR_HIGHER_FOUR:
+		rssi_count = 4;
+		rssi_values += 4;
+		break;
+	case RSSI_HR_ALL:
+		rssi_count = 6;
+		break;
+	case RSSI_HR_LOWER_TWO:
+		rssi_count = 2;
+		break;
+	case RSSI_HR_MID_TWO:
+		rssi_count = 2;
+		rssi_values += 2;
+		break;
+	default:
+		OSMO_ASSERT(false);
+		break;
+	}
+
+	for (i = 0; i < rssi_count; i++) {
+		if (rssi_values[i] == 0)
+			rssi_sum += -127;
+		else
+			rssi_sum += rssi_values[i];
+	}
+
+	rc = rssi_sum / rssi_count;
+
+	/* Debug output: */
+	switch (mode) {
+	case RSSI_FR_LOWER_FOUR:
+		LOGP(DL1P, LOGL_INFO,
+		     "%s calculating rssi: [%02i %02i %02i %02i] %02i %02i %02i %02i => %i\n",
+		     gsm_lchan_name(lchan), r[0], r[1], r[2], r[3], r[4], r[5],
+		     r[6], r[7], rc);
+		break;
+	case RSSI_FR_HIGHER_FOUR:
+		LOGP(DL1P, LOGL_INFO,
+		     "%s calculating rssi: %02i %02i %02i %02i [%02i %02i %02i %02i] => %i\n",
+		     gsm_lchan_name(lchan), r[0], r[1], r[2], r[3], r[4], r[5],
+		     r[6], r[7], rc);
+		break;
+	case RSSI_HR_ALL:
+		LOGP(DL1P, LOGL_INFO,
+		     "%s calculating rssi: [%02i %02i %02i %02i %02i %02i] => %i\n",
+		     gsm_lchan_name(lchan), r[0], r[1], r[2], r[3], r[4], r[5],
+		     rc);
+		break;
+	case RSSI_HR_LOWER_TWO:
+		LOGP(DL1P, LOGL_INFO,
+		     "%s calculating rssi: [%02i %02i] %02i %02i %02i %02i => %i\n",
+		     gsm_lchan_name(lchan), r[0], r[1], r[2], r[3], r[4], r[5],
+		     rc);
+		break;
+	case RSSI_HR_MID_TWO:
+		LOGP(DL1P, LOGL_INFO,
+		     "%s calculating rssi: %02i %02i [%02i %02i] %02i %02i => %i\n",
+		     gsm_lchan_name(lchan), r[0], r[1], r[2], r[3], r[4], r[5],
+		     rc);
+		break;
+	default:
+		OSMO_ASSERT(false);
+		break;
+	}
+
+	return rc;
+}
+
 /*! \brief a single TCH/F burst was received by the PHY, process it */
 int rx_tchf_fn(struct l1sched_trx *l1t, enum trx_chan_type chan,
 	       uint8_t bid, const struct trx_ul_burst_ind *bi)
@@ -1142,6 +1234,7 @@
 	uint16_t ber10k;
 	uint8_t is_sub = 0;
 	uint8_t ft;
+	int8_t rssi;
 
 	/* handle rach, if handover rach detection is turned on */
 	if (chan_state->ho_rach_detect == 1)
@@ -1175,10 +1268,18 @@
 	} else
 		memset(burst, 0, 116);
 
+	/* keep record of the rssi values for each burst */
+	chan_state->ul_rssi[bid + 4] = bi->rssi;
+
 	/* wait until complete set of bursts */
 	if (bid != 3)
 		return 0;
 
+	/* Precalculate the RSSI value for a regular TCH burst, this calucation
+	 * will be valid for the most situation, however, FACCH and AMR-DTX
+	 * frames require a different calculation mode. */
+	rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_FR_LOWER_FOUR, lchan);
+
 	/* check for complete set of bursts */
 	if ((*mask & 0xf) != 0xf) {
 		LOGL1S(DL1P, LOGL_NOTICE, l1t, bi->tn, chan, bi->fn,
@@ -1226,7 +1327,7 @@
 		/* Tag all frames that are not regular AMR voice frames as
 		 * SUB-Frames */
 		if (chan_state->amr_last_dtx != AMR_OTHER) {
-			LOGL1S(DL1P, LOGL_DEBUG, l1t, bi->tn, chan, bi->fn,
+			LOGL1S(DL1P, LOGL_INFO, l1t, bi->tn, chan, bi->fn,
 			       "Received AMR SID frame: %s\n",
 			       gsm0503_amr_dtx_frame_name(chan_state->amr_last_dtx));
 			is_sub = 1;
@@ -1246,6 +1347,23 @@
 			break;
 		}
 
+		switch (chan_state->amr_last_dtx) {
+		case AFS_SID_FIRST:
+			rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_FR_LOWER_FOUR, lchan);
+			break;
+		case AFS_SID_UPDATE:
+			rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_FR_HIGHER_FOUR, lchan);
+			break;
+		case AFS_SID_UPDATE_CN:
+			rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_FR_LOWER_FOUR, lchan);
+			break;
+		case AFS_ONSET:
+			rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_FR_HIGHER_FOUR, lchan);
+			break;
+		default:
+			break;
+		}
+
 		if (rc)
 			trx_loop_amr_input(l1t,
 				trx_chan_desc[chan].chan_nr | bi->tn, chan_state,
@@ -1270,8 +1388,14 @@
 			tch_mode);
 		return -EINVAL;
 	}
+
+	/* copy bursts to the beginning of the buffer since they are needed in
+	 * the lower half of the buffer for the next run (diagonal interleaving) */
 	memcpy(*bursts_p, *bursts_p + 464, 464);
 
+	/* also move measurement values */
+	memcpy(chan_state->ul_rssi, chan_state->ul_rssi + 4, 4);
+
 	/* Check if the frame is bad */
 	if (rc < 0) {
 		LOGL1S(DL1P, LOGL_NOTICE, l1t, bi->tn, chan, bi->fn,
@@ -1297,8 +1421,8 @@
 		fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_FACCH_F);
 		_sched_compose_ph_data_ind(l1t, bi->tn, fn_begin, chan,
 			tch_data + amr, GSM_MACBLOCK_LEN,
-			/* FIXME: AVG RSSI and ToA256 */
-			bi->rssi, bi->toa256,
+			/* FIXME: AVG ToA256 */
+			rssi, bi->toa256,
 			0 /* FIXME: AVG C/I */,
 			ber10k, PRES_INFO_UNKNOWN);
 bfi:
@@ -1356,7 +1480,7 @@
 compose_l1sap:
 	fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_TCH_F);
 	return _sched_compose_tch_ind(l1t, bi->tn, fn_begin, chan,
-				      tch_data, rc, bi->toa256, ber10k, bi->rssi, is_sub);
+				      tch_data, rc, bi->toa256, ber10k, rssi, is_sub);
 }
 
 /*! \brief a single TCH/H burst was received by the PHY, process it */
@@ -1386,6 +1510,7 @@
 	uint16_t ber10k;
 	uint8_t is_sub = 0;
 	uint8_t ft;
+	int8_t rssi;
 
 	/* handle RACH, if handover RACH detection is turned on */
 	if (chan_state->ho_rach_detect == 1)
@@ -1411,7 +1536,9 @@
 	/* update mask */
 	*mask |= (1 << bid);
 
-	/* copy burst to end of buffer of 6 bursts */
+	/* copy burst to end of buffer of 6 bursts, even though a normal TCH
+	 * frame requires only 4 bursts. However, we will need 6 bursts to
+	 * decode the FACCH channel (diagonal interleaving). */
 	burst = *bursts_p + bid * 116 + 464;
 	if (bi->burst_len > 0) {
 		memcpy(burst, bi->burst + 3, 58);
@@ -1419,10 +1546,18 @@
 	} else
 		memset(burst, 0, 116);
 
+	/* keep record of the rssi values for each burst */
+	chan_state->ul_rssi[bid + 4] = bi->rssi;
+
 	/* wait until complete set of bursts */
 	if (bid != 1)
 		return 0;
 
+	/* Precalculate the RSSI value for a regular TCH burst, this calucation
+	 * will be valid for the most situation, however, FACCH and AMR-DTX
+	 * frames require a different calculation mode. */
+	rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_HR_MID_TWO, lchan);
+
 	/* check for complete set of bursts */
 	if ((*mask & 0x3) != 0x3) {
 		LOGL1S(DL1P, LOGL_NOTICE, l1t, bi->tn, chan, bi->fn,
@@ -1479,7 +1614,7 @@
 		/* Tag all frames that are not regular AMR voice frames
 		   as SUB-Frames */
 		if (chan_state->amr_last_dtx != AMR_OTHER) {
-			LOGL1S(DL1P, LOGL_DEBUG, l1t, bi->tn, chan, bi->fn,
+			LOGL1S(DL1P, LOGL_INFO, l1t, bi->tn, chan, bi->fn,
 			       "Received AMR SID frame: %s\n",
 			       gsm0503_amr_dtx_frame_name(chan_state->amr_last_dtx));
 			is_sub = 1;
@@ -1496,6 +1631,30 @@
 			break;
 		}
 
+		switch (chan_state->amr_last_dtx) {
+		case AHS_SID_FIRST_P1:
+			rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_HR_LOWER_TWO, lchan);
+			break;
+		case AHS_SID_FIRST_P2:
+			rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_HR_LOWER_TWO, lchan);
+			break;
+		case AHS_SID_UPDATE:
+			rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_HR_LOWER_TWO, lchan);
+			break;
+		case AHS_SID_UPDATE_CN:
+			rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_HR_LOWER_TWO, lchan);
+			break;
+		case AHS_ONSET:
+			rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_HR_MID_TWO, lchan);
+			break;
+		case AHS_SID_FIRST_INH:
+			rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_HR_LOWER_TWO, lchan);
+			break;
+		case AHS_SID_UPDATE_INH:
+			rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_HR_LOWER_TWO, lchan);
+			break;
+		}
+
 		if (rc)
 			trx_loop_amr_input(l1t,
 				trx_chan_desc[chan].chan_nr | bi->tn, chan_state,
@@ -1521,10 +1680,17 @@
 			tch_mode);
 		return -EINVAL;
 	}
+
+	/* copy bursts to the beginning of the buffer since they are needed in
+	 * the lower half of the buffer for the next run (diagonal interleaving) */
 	memcpy(*bursts_p, *bursts_p + 232, 232);
 	memcpy(*bursts_p + 232, *bursts_p + 464, 232);
-	ber10k = compute_ber10k(n_bits_total, n_errors);
 
+	/* also move measurement values */
+	memcpy(chan_state->ul_rssi, chan_state->ul_rssi + 2, 2);
+	memcpy(chan_state->ul_rssi + 2, chan_state->ul_rssi + 4, 2);
+
+	ber10k = compute_ber10k(n_bits_total, n_errors);
 
 	/* Check if the frame is bad */
 	if (rc < 0) {
@@ -1547,6 +1713,7 @@
 
 	/* FACCH */
 	if (rc == GSM_MACBLOCK_LEN) {
+		rssi = calc_rssi_avg(chan_state->ul_rssi, RSSI_HR_ALL, lchan);
 		chan_state->ul_ongoing_facch = 1;
 		uint16_t ber10k = compute_ber10k(n_bits_total, n_errors);
 		if (lchan->nr == 0)
@@ -1555,10 +1722,11 @@
 			fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_FACCH_H1);
 		_sched_compose_ph_data_ind(l1t, bi->tn, fn_begin, chan,
 			tch_data + amr, GSM_MACBLOCK_LEN,
-			/* FIXME: AVG both RSSI and ToA */
-			bi->rssi, bi->toa256,
+			/* FIXME: AVG ToA */
+			rssi, bi->toa256,
 			0 /* FIXME: AVG C/I */,
 			ber10k, PRES_INFO_UNKNOWN);
+
 bfi:
 		/* FIXME: a FACCH/H frame replaces two speech frames,
 		 * so we actually need to send two bad frame indications! */
@@ -1619,7 +1787,7 @@
 	else
 		fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_TCH_H1);
 	return _sched_compose_tch_ind(l1t, bi->tn, fn_begin, chan,
-				      tch_data, rc, bi->toa256, ber10k, bi->rssi, is_sub);
+				      tch_data, rc, bi->toa256, ber10k, rssi, is_sub);
 }
 
 /* schedule all frames of all TRX for given FN */

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/18035
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: I902bb47d68742d2589156f61099b67a0edbaf40b
Gerrit-Change-Number: 18035
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200504/7174dfeb/attachment.htm>


More information about the gerrit-log mailing list