From a9c2ef2638523d62f1f9eecb1c6c326f4c6519b6 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Sat, 16 Dec 2017 16:21:05 +0700 Subject: [PATCH] host/trxcon/scheduler: inform L2&3 about decoding errors Previously, we used to drop a frame if decoding wasn't successful. This way, the higher layers didn't even know about that, so the local counters and Measurement Reports were incomplete. This change makes scheduler to forward L2 frames in any case, setting the num_biterr for each of them. In case of decoding error, a dummy (payload filled by 0x00) L2 frame will be sent. Change-Id: I31011d8f3ca8b9a12474cd0bc653faed18391033 --- src/host/trxcon/sched_lchan_common.c | 16 +++++++++++----- src/host/trxcon/sched_lchan_tchf.c | 7 +++++-- src/host/trxcon/sched_lchan_xcch.c | 4 ++-- src/host/trxcon/sched_trx.h | 4 +++- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/host/trxcon/sched_lchan_common.c b/src/host/trxcon/sched_lchan_common.c index 6d75533da..c6b287a93 100644 --- a/src/host/trxcon/sched_lchan_common.c +++ b/src/host/trxcon/sched_lchan_common.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -80,7 +81,8 @@ const uint8_t sched_nb_training_bits[8][26] = { }; int sched_send_data_ind(struct trx_instance *trx, struct trx_ts *ts, - struct trx_lchan_state *lchan, uint8_t *l2, size_t l2_len) + struct trx_lchan_state *lchan, uint8_t *l2, size_t l2_len, + bool dec_failed, int bit_error_count) { const struct trx_lchan_desc *lchan_desc; struct l1ctl_info_dl *data; @@ -99,14 +101,18 @@ int sched_send_data_ind(struct trx_instance *trx, struct trx_ts *ts, data->band_arfcn = htons(trx->band_arfcn); data->frame_nr = htonl(lchan->rx_first_fn); data->rx_level = -(lchan->meas.rssi_sum / lchan->meas.rssi_num); + data->num_biterr = bit_error_count; /* FIXME: set proper values */ - data->num_biterr = 0; - data->fire_crc = 0; data->snr = 0; - /* Fill in the payload */ - memcpy(data->payload, l2, l2_len); + if (dec_failed) { + /* Mark frame as broken */ + data->fire_crc = 2; + } else { + /* Fill in the payload */ + memcpy(data->payload, l2, l2_len); + } /* Put a packet to higher layers */ l1ctl_tx_data_ind(trx->l1l, data, l2_len == GSM_MACBLOCK_LEN ? diff --git a/src/host/trxcon/sched_lchan_tchf.c b/src/host/trxcon/sched_lchan_tchf.c index 237e5388c..a0adf69c3 100644 --- a/src/host/trxcon/sched_lchan_tchf.c +++ b/src/host/trxcon/sched_lchan_tchf.c @@ -149,7 +149,9 @@ int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts, l2_len = sched_bad_frame_ind(l2, rsl_cmode, tch_mode); } else if (rc == GSM_MACBLOCK_LEN) { /* FACCH received, forward it to the higher layers */ - sched_send_data_ind(trx, ts, lchan, l2, GSM_MACBLOCK_LEN); + sched_send_data_ind(trx, ts, lchan, + l2, GSM_MACBLOCK_LEN, false, n_errors); + /* Send BFI instead of stolen TCH frame */ l2_len = sched_bad_frame_ind(l2, rsl_cmode, tch_mode); } else { @@ -159,7 +161,8 @@ int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts, /* Send a traffic frame to the higher layers */ if (l2_len > 0) - sched_send_data_ind(trx, ts, lchan, l2, l2_len); + sched_send_data_ind(trx, ts, lchan, + l2, l2_len, false, n_errors); return 0; } diff --git a/src/host/trxcon/sched_lchan_xcch.c b/src/host/trxcon/sched_lchan_xcch.c index 7d4786db6..1b7c4da3b 100644 --- a/src/host/trxcon/sched_lchan_xcch.c +++ b/src/host/trxcon/sched_lchan_xcch.c @@ -108,11 +108,11 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts, (*first_fn) % ts->mf_layout->period, ts->mf_layout->period, lchan_desc->name); - return rc; } /* Send a L2 frame to the higher layers */ - sched_send_data_ind(trx, ts, lchan, l2, GSM_MACBLOCK_LEN); + sched_send_data_ind(trx, ts, lchan, + l2, GSM_MACBLOCK_LEN, rc != 0, n_errors); /* TODO: AGC, TA loops */ return 0; diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h index 268c6b707..f2c091e11 100644 --- a/src/host/trxcon/sched_trx.h +++ b/src/host/trxcon/sched_trx.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -277,6 +278,7 @@ extern const uint8_t sched_nb_training_bits[8][26]; size_t sched_bad_frame_ind(uint8_t *l2, uint8_t rsl_cmode, uint8_t tch_mode); int sched_send_data_ind(struct trx_instance *trx, struct trx_ts *ts, - struct trx_lchan_state *lchan, uint8_t *l2, size_t l2_len); + struct trx_lchan_state *lchan, uint8_t *l2, size_t l2_len, + bool dec_failed, int bit_error_count); int sched_send_data_conf(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, size_t l2_len);