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 <[email protected]>

Reply via email to