Change in osmo-bts[master]: osmo-bts-trx/scheduler: distinguish synch. sequence of RACH bursts
Vadim Yanitskiy
gerrit-no-reply at lists.osmocom.org
Sat Apr 20 22:59:48 UTC 2019
Vadim Yanitskiy has uploaded this change for review. ( https://gerrit.osmocom.org/13723
Change subject: osmo-bts-trx/scheduler: distinguish synch. sequence of RACH bursts
......................................................................
osmo-bts-trx/scheduler: distinguish synch. sequence of RACH bursts
WIP/TODO: add detailed description here (please read the code).
At least it makes both TC_rach_content and TC_rach_count TTCN-3
test cases pass again. There were some collisions between the
extended (11-bit) RACH bursts and the regular ones, since we
used to call gsm0503_rach_ext_decode_ber() first, regardless
of the burst type...
To be 100% sure, we need a similar TTCN-3 test case for the
extended (11-bit) RACH. This would require to do some little
changes in both trxcon and the L1CTL protocol.
Change-Id: Ibb6d27c6589965c8b59a6d2598a7c43fd860f284
---
M src/osmo-bts-trx/scheduler_trx.c
1 file changed, 124 insertions(+), 42 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/23/13723/1
diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c
index 32bdb98..81bb48d 100644
--- a/src/osmo-bts-trx/scheduler_trx.c
+++ b/src/osmo-bts-trx/scheduler_trx.c
@@ -709,72 +709,154 @@
* RX on uplink (indication to upper layer)
*/
+/* 3GPP TS 05.02, section 5.2.7 */
+#define RACH_EXT_TAIL_LEN 8
+#define RACH_SYNCH_SEQ_LEN 41
+
+enum rach_synch_seq_t {
+ RACH_SYNCH_SEQ_UNKNOWN = -1,
+ RACH_SYNCH_SEQ_TS0, /* GSM, GMSK (default) */
+ RACH_SYNCH_SEQ_TS1, /* EGPRS, 8-PSK */
+ RACH_SYNCH_SEQ_TS2, /* EGPRS, GMSK */
+ RACH_SYNCH_SEQ_NUM
+};
+
+static struct value_string rach_synch_seq_names[] = {
+ { RACH_SYNCH_SEQ_UNKNOWN, "UNKNOWN" },
+ { RACH_SYNCH_SEQ_TS0, "TS0: GSM, GMSK" },
+ { RACH_SYNCH_SEQ_TS1, "TS1: EGPRS, 8-PSK" },
+ { RACH_SYNCH_SEQ_TS2, "TS2: EGPRS, GMSK" },
+ { 0, NULL },
+};
+
+static enum rach_synch_seq_t rach_get_synch_seq(sbit_t *bits, float *certitude)
+{
+ sbit_t *synch_seq_burst = bits + RACH_EXT_TAIL_LEN;
+ unsigned int score[RACH_SYNCH_SEQ_NUM] = { 0 };
+ unsigned int max_score = 0;
+ unsigned int i, j;
+
+ /* 3GPP TS 05.02, section 5.2.7 "Access burst (AB)", synch. sequence bits */
+ static const char synch_seq_ref[RACH_SYNCH_SEQ_NUM][RACH_SYNCH_SEQ_LEN] = {
+ [RACH_SYNCH_SEQ_TS0] = "01001011011111111001100110101010001111000",
+ [RACH_SYNCH_SEQ_TS1] = "01010100111110001000011000101111001001101",
+ [RACH_SYNCH_SEQ_TS2] = "11101111001001110101011000001101101110111",
+ };
+
+#define RACH_SYNCH_SEQ_MATCH(seq_ref) \
+ (seq_ref[j] == '1' ? synch_seq_burst[j] < 0 : synch_seq_burst[j] >= 0)
+
+#define RACH_SYNCH_SEQ_SCORE(seq_ref) \
+ (RACH_SYNCH_SEQ_MATCH(seq_ref) ? abs(synch_seq_burst[j]) : 0)
+
+ /* For each synch. sequence, count the bit match score. Since we deal with
+ * soft-bits (-127...127), we sum the absolute values of matching ones, so
+ * the resulting scores are more accurate than it could be with hard-bits. */
+ for (i = 0; i < RACH_SYNCH_SEQ_NUM; i++) {
+ for (j = 0; j < RACH_SYNCH_SEQ_LEN; j++)
+ score[i] += RACH_SYNCH_SEQ_SCORE(synch_seq_ref[i]);
+ /* Keep the maximum value updated */
+ if (max_score < score[i])
+ max_score = score[i];
+ }
+
+ /* Calculate an approximate level of our confidence */
+ if (certitude != NULL)
+ *certitude = max_score * 100 / (RACH_SYNCH_SEQ_LEN * 127);
+
+ /* At least 1/3 of a synch. sequence shall match */
+ if (max_score < (127 * RACH_SYNCH_SEQ_LEN / 3))
+ return RACH_SYNCH_SEQ_UNKNOWN;
+
+ /* Which synch. sequence is the best? */
+ else if (max_score == score[RACH_SYNCH_SEQ_TS0])
+ return RACH_SYNCH_SEQ_TS0;
+ else if (max_score == score[RACH_SYNCH_SEQ_TS1])
+ return RACH_SYNCH_SEQ_TS1;
+ else if (max_score == score[RACH_SYNCH_SEQ_TS2])
+ return RACH_SYNCH_SEQ_TS2;
+ else /* Shall not happen in general */
+ return RACH_SYNCH_SEQ_UNKNOWN;
+}
+
int rx_rach_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits,
int8_t rssi, int16_t toa256)
{
- uint8_t chan_nr;
struct osmo_phsap_prim l1sap;
int n_errors, n_bits_total;
- bool is_11bit = true;
uint16_t ra11;
uint8_t ra;
- int rc = 1;
+ int rc;
- chan_nr = trx_chan_desc[chan].chan_nr | tn;
+ /* It would be great if the transceiver were doing some kind of tagging,
+ * whether it is extended (11-bit) RACH or not. We would not need to guess
+ * it here. For now, let's try to correlate the synch. sequence of a received
+ * Access Burst with the known ones (3GPP TS 05.02, section 5.2.7), and
+ * fall-back to the default TS0 if it fails. This would save some CPU
+ * power, and what is more important - prevent possible collisions. */
+ enum rach_synch_seq_t synch_seq = RACH_SYNCH_SEQ_TS0;
+ float certitude = 100;
- LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, chan, fn, "Received RACH toa=%d\n", toa256);
+ /* Handover RACH cannot be extended (11-bit) */
+ if (chan == TRXC_RACH)
+ synch_seq = rach_get_synch_seq(bits, &certitude);
- if (chan == TRXC_RACH) /* Attempt to decode as extended (11-bit) RACH first */
- rc = gsm0503_rach_ext_decode_ber(&ra11, bits + 8 + 41,
+ LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, chan, fn, "Received RACH (%s; confidence=%.1f%%) toa=%d\n",
+ get_value_string(rach_synch_seq_names, synch_seq), certitude, toa256);
+
+ /* Compose a new L1SAP primitive */
+ memset(&l1sap, 0x00, sizeof(l1sap));
+ osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_PH_RACH, PRIM_OP_INDICATION, NULL);
+ l1sap.u.rach_ind.chan_nr = trx_chan_desc[chan].chan_nr | tn;
+ l1sap.u.rach_ind.acc_delay = (toa256 >= 0) ? toa256 / 256 : 0;
+ l1sap.u.rach_ind.acc_delay_256bits = toa256;
+ l1sap.u.rach_ind.rssi = rssi;
+ l1sap.u.rach_ind.fn = fn;
+
+ /* Decode RACH depending on its synch. sequence */
+ switch (synch_seq) {
+ case RACH_SYNCH_SEQ_TS1:
+ case RACH_SYNCH_SEQ_TS2:
+ rc = gsm0503_rach_ext_decode_ber(&ra11, bits + RACH_EXT_TAIL_LEN + RACH_SYNCH_SEQ_LEN,
l1t->trx->bts->bsic, &n_errors, &n_bits_total);
- if (rc) {
- /* Indicate non-extended RACH */
- is_11bit = false;
-
- /* Fall-back to the normal RACH decoding */
- rc = gsm0503_rach_decode_ber(&ra, bits + 8 + 41,
- l1t->trx->bts->bsic, &n_errors, &n_bits_total);
if (rc) {
- LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, chan, fn, "Received bad AB frame\n");
+ LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, chan, fn, "Received bad Access Burst\n");
return 0;
}
- }
- /* compose primitive */
- /* generate prim */
- memset(&l1sap, 0, sizeof(l1sap));
- osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_PH_RACH, PRIM_OP_INDICATION,
- NULL);
- l1sap.u.rach_ind.chan_nr = chan_nr;
- l1sap.u.rach_ind.acc_delay = (toa256 >= 0) ? toa256/256 : 0;
- l1sap.u.rach_ind.fn = fn;
- l1sap.u.rach_ind.rssi = rssi;
- l1sap.u.rach_ind.ber10k = compute_ber10k(n_bits_total, n_errors);
- l1sap.u.rach_ind.acc_delay_256bits = toa256;
+ if (synch_seq == RACH_SYNCH_SEQ_TS1)
+ l1sap.u.rach_ind.burst_type = GSM_L1_BURST_TYPE_ACCESS_1;
+ else
+ l1sap.u.rach_ind.burst_type = GSM_L1_BURST_TYPE_ACCESS_2;
- if (is_11bit) {
l1sap.u.rach_ind.is_11bit = 1;
l1sap.u.rach_ind.ra = ra11;
- l1sap.u.rach_ind.burst_type = BSIC2BCC(l1t->trx->bts->bsic);
- switch (l1sap.u.rach_ind.burst_type) {
- case GSM_L1_BURST_TYPE_ACCESS_0:
- case GSM_L1_BURST_TYPE_ACCESS_1:
- case GSM_L1_BURST_TYPE_ACCESS_2:
- break;
- default:
- LOGL1S(DL1P, LOGL_NOTICE, l1t, tn, chan, fn,
- "Received RACH frame with unexpected TSC %u, "
- "forcing default %u\n", l1sap.u.rach_ind.burst_type,
- GSM_L1_BURST_TYPE_ACCESS_0);
- l1sap.u.rach_ind.burst_type = GSM_L1_BURST_TYPE_ACCESS_0;
+ break;
+
+ case RACH_SYNCH_SEQ_TS0:
+ default:
+ /* Fall-back to the default TS0 if needed */
+ if (synch_seq != RACH_SYNCH_SEQ_TS0) {
+ LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, chan, fn, "Falling-back to the default TS0\n");
+ synch_seq = RACH_SYNCH_SEQ_TS0;
}
- } else {
+
+ rc = gsm0503_rach_decode_ber(&ra, bits + RACH_EXT_TAIL_LEN + RACH_SYNCH_SEQ_LEN,
+ l1t->trx->bts->bsic, &n_errors, &n_bits_total);
+ if (rc) {
+ LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, chan, fn, "Received bad Access Burst\n");
+ return 0;
+ }
+
+ l1sap.u.rach_ind.burst_type = GSM_L1_BURST_TYPE_ACCESS_0;
l1sap.u.rach_ind.is_11bit = 0;
l1sap.u.rach_ind.ra = ra;
- l1sap.u.rach_ind.burst_type = GSM_L1_BURST_TYPE_ACCESS_0;
+ break;
}
+ l1sap.u.rach_ind.ber10k = compute_ber10k(n_bits_total, n_errors);
+
/* forward primitive */
l1sap_up(l1t->trx, &l1sap);
--
To view, visit https://gerrit.osmocom.org/13723
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibb6d27c6589965c8b59a6d2598a7c43fd860f284
Gerrit-Change-Number: 13723
Gerrit-PatchSet: 1
Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190420/1576d51d/attachment.html>
More information about the gerrit-log
mailing list