From 20971da499eafd11ce71f61a930ab0c1aa202fa8 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 24 Nov 2012 19:36:19 +0100 Subject: rxqual: Begin to implement the rxqual calculation * Make num_biterr 16bit because the API is 16bit. * Add the num_bits to count the bits transferred. * Re-order and add manual padding due the increase in size. * Add the bits to struct rx_meas_stat, increment and reset them. * Calculation for the sub_rxqual is missing, so is DTX code in general * Calculation for TCH/F, TCH/H in speech mode might be wrong --- include/l1ctl_proto.h | 6 +++- .../include/osmocom/bb/common/osmocom_data.h | 1 + src/host/layer23/src/common/l1ctl.c | 1 + src/host/layer23/src/mobile/gsm322.c | 2 +- src/host/layer23/src/mobile/gsm48_rr.c | 34 ++++++++++++++++++++-- src/target/firmware/layer1/prim_rx_nb.c | 11 ++++--- src/target/firmware/layer1/prim_tch.c | 27 +++++++++-------- 7 files changed, 57 insertions(+), 25 deletions(-) diff --git a/include/l1ctl_proto.h b/include/l1ctl_proto.h index 4b9540e9..14c03967 100644 --- a/include/l1ctl_proto.h +++ b/include/l1ctl_proto.h @@ -100,10 +100,14 @@ struct l1ctl_info_dl { uint32_t frame_nr; + uint16_t num_biterr; /* number of estimated bit errors (BER) */ + uint16_t num_bits; /* number of transfered bits */ + uint8_t rx_level; /* 0 .. 63 in typical GSM notation (dBm+110) */ uint8_t snr; /* Signal/Noise Ration (dB) */ - uint8_t num_biterr; + uint8_t fire_crc; + uint8_t padding[1]; uint8_t payload[0]; } __attribute__((packed)); diff --git a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h index ab7c2502..0a303b9c 100644 --- a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h +++ b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h @@ -45,6 +45,7 @@ struct rx_meas_stat { uint32_t frames; uint32_t snr; uint32_t berr; + uint32_t bits; uint32_t rxlev; /* counters loss criterion */ diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c index 521949c1..5fa345f4 100644 --- a/src/host/layer23/src/common/l1ctl.c +++ b/src/host/layer23/src/common/l1ctl.c @@ -186,6 +186,7 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg) meas->frames++; meas->snr += dl->snr; meas->berr += dl->num_biterr; + meas->bits += dl->num_bits; meas->rxlev += dl->rx_level; /* counting loss criteria */ diff --git a/src/host/layer23/src/mobile/gsm322.c b/src/host/layer23/src/mobile/gsm322.c index ce5e1e1d..c44a50b3 100644 --- a/src/host/layer23/src/mobile/gsm322.c +++ b/src/host/layer23/src/mobile/gsm322.c @@ -470,7 +470,7 @@ static int gsm322_sync_to_cell(struct gsm322_cellsel *cs, cs->ccch_mode = CCCH_MODE_NONE; } - meas->frames = meas->snr = meas->berr = meas->rxlev = 0; + meas->frames = meas->snr = meas->berr = meas->bits = meas->rxlev = 0; cs->rxlev_dbm = cs->rxlev_count = 0; cs->neighbour = neighbour; diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c index 36488606..02bc73c3 100644 --- a/src/host/layer23/src/mobile/gsm48_rr.c +++ b/src/host/layer23/src/mobile/gsm48_rr.c @@ -98,6 +98,33 @@ static int gsm48_rr_rel_cnf(struct osmocom_ms *ms, struct msgb *msg); #define MIN(a, b) ((a < b) ? a : b) +static int calc_rxqual(struct rx_meas_stat *stat) +{ + uint32_t qual; + + /* no bits transferred, so no error */ + if (stat->bits == 0) + return 0; + + qual = (stat->berr * 500) / stat->bits; + if (qual == 0) + return 0; + if (qual == 1) + return 1; + if (qual < 4) + return 2; + if (qual < 8) + return 3; + if (qual < 16) + return 4; + if (qual < 32) + return 5; + if (qual < 64) + return 6; + + return 7; +} + /* decode "Power Command" (10.5.2.28) and (10.5.2.28a) */ static int gsm48_decode_power_cmd_acc(struct gsm48_power_cmd *pc, uint8_t *power_level, uint8_t *atc) @@ -667,7 +694,7 @@ static void timeout_rr_meas(void *arg) gsm48_rr_tx_meas_rep(rr->ms); restart: - meas->frames = meas->snr = meas->berr = meas->rxlev = 0; + meas->frames = meas->snr = meas->berr = meas->bits = meas->rxlev = 0; start_rr_t_meas(rr, 1, 0); } @@ -2757,7 +2784,8 @@ static int gsm48_rr_tx_meas_rep(struct osmocom_ms *ms) meas_valid = 1; serv_rxlev_full = serv_rxlev_sub = (meas->rxlev + (meas->frames / 2)) / meas->frames; - serv_rxqual_full = serv_rxqual_sub = 0; // FIXME + serv_rxqual_full = calc_rxqual(meas); + serv_rxqual_sub = 0; // FIXME } memset(&rxlev_nc, 0, sizeof(rxlev_nc)); @@ -2987,7 +3015,7 @@ static int gsm48_rr_activate_channel(struct osmocom_ms *ms, memset(s->si5b_msg, 0, sizeof(s->si5b_msg)); memset(s->si5t_msg, 0, sizeof(s->si5t_msg)); } - meas->frames = meas->snr = meas->berr = meas->rxlev = 0; + meas->frames = meas->snr = meas->berr = meas->bits = meas->rxlev = 0; rr->meas.nc_num = 0; stop_rr_t_meas(rr); start_rr_t_meas(rr, 1, 0); diff --git a/src/target/firmware/layer1/prim_rx_nb.c b/src/target/firmware/layer1/prim_rx_nb.c index 38c7b53b..79e85a20 100644 --- a/src/target/firmware/layer1/prim_rx_nb.c +++ b/src/target/firmware/layer1/prim_rx_nb.c @@ -53,6 +53,9 @@ #include +/* From GSM 05.01 7 Coding and interleaving. Coded bits per block */ +#define BIT_LEN_SDCCH 456 /* and for BIT_LEN_SACCH */ + struct l1s_rxnb_state { struct l1s_meas_hdr meas[4]; @@ -112,7 +115,6 @@ static int l1s_nb_resp(__unused uint8_t p1, uint8_t burst_id, uint16_t p3) /* 4th burst, get frame data */ if (dsp_api.db_r->d_burst_d == 3) { uint8_t i; - uint16_t num_biterr; uint32_t avg_snr = 0; int32_t avg_dbm8 = 0; @@ -141,11 +143,8 @@ static int l1s_nb_resp(__unused uint8_t p1, uint8_t burst_id, uint16_t p3) rxnb.dl->snr = avg_snr / 4; rxnb.dl->rx_level = dbm2rxlev(avg_dbm8 / (8*4)); - num_biterr = dsp_api.ndb->a_cd[2] & 0xffff; - if (num_biterr > 0xff) - rxnb.dl->num_biterr = 0xff; - else - rxnb.dl->num_biterr = num_biterr; + rxnb.dl->num_biterr = dsp_api.ndb->a_cd[2] & 0xffff; + rxnb.dl->num_bits = BIT_LEN_SDCCH; rxnb.dl->fire_crc = ((dsp_api.ndb->a_cd[0] & 0xffff) & ((1 << B_FIRE1) | (1 << B_FIRE0))) >> B_FIRE0; diff --git a/src/target/firmware/layer1/prim_tch.c b/src/target/firmware/layer1/prim_tch.c index a0a03b81..02d327de 100644 --- a/src/target/firmware/layer1/prim_tch.c +++ b/src/target/firmware/layer1/prim_tch.c @@ -55,6 +55,12 @@ #include +/* From GSM 05.01 7 Coding and interleaving. Coded bits per block */ +#define BIT_LEN_FACCHF 456 +#define BIT_LEN_SACCH 456 /* and for BIT_LEN_SDCCH */ +#define BIT_LEN_TCHFS 378 +#define BIT_LEN_TCHHS 211 + /* This computes various parameters both for the DSP and for * our logic. Not all are used all the time, but it's easier @@ -211,7 +217,6 @@ static int l1s_tch_resp(__unused uint8_t p1, __unused uint8_t p2, uint16_t p3) struct msgb *msg; struct l1ctl_info_dl *dl; struct l1ctl_data_ind *di; - uint16_t num_biterr; uint32_t avg_snr = 0; int32_t avg_dbm8 = 0; int i, n; @@ -245,12 +250,8 @@ static int l1s_tch_resp(__unused uint8_t p1, __unused uint8_t p2, uint16_t p3) dl->rx_level = dbm2rxlev(avg_dbm8 / (8*n)); /* Errors & CRC status */ - num_biterr = dsp_api.ndb->a_fd[2] & 0xffff; - if (num_biterr > 0xff) - dl->num_biterr = 0xff; - else - dl->num_biterr = num_biterr; - + dl->num_biterr = dsp_api.ndb->a_fd[2] & 0xffff; + dl->num_bits = BIT_LEN_FACCHF; dl->fire_crc = ((dsp_api.ndb->a_fd[0] & 0xffff) & ((1 << B_FIRE1) | (1 << B_FIRE0))) >> B_FIRE0; /* Update rx level for pm report */ @@ -309,6 +310,9 @@ static int l1s_tch_resp(__unused uint8_t p1, __unused uint8_t p2, uint16_t p3) } dl = (struct l1ctl_info_dl *) msgb_put(msg, sizeof(*dl)); + /* FIXE: verify this for different audio modes */ + dl->num_biterr = traffic_buf[2] & 0xffff; + dl->num_bits = tch_f_hn ? BIT_LEN_TCHFS : BIT_LEN_TCHHS; ti = (struct l1ctl_traffic_ind *) msgb_put(msg, sizeof(*ti)); /* Copy actual data, skipping the information block [0,1,2] */ @@ -618,7 +622,6 @@ static int l1s_tch_a_resp(__unused uint8_t p1, __unused uint8_t p2, uint16_t p3) /* Last burst, read data & send to the up layer */ if ((burst_id == 3) && (dsp_api.ndb->a_cd[0] & (1<snr = avg_snr / 4; rx_tch_a.dl->rx_level = dbm2rxlev(avg_dbm8 / (8*4)); - num_biterr = dsp_api.ndb->a_cd[2]; - if (num_biterr > 0xff) - rx_tch_a.dl->num_biterr = 0xff; - else - rx_tch_a.dl->num_biterr = num_biterr; - + rx_tch_a.dl->num_biterr = dsp_api.ndb->a_cd[2] & 0xffff; + rx_tch_a.dl->num_bits = BIT_LEN_SACCH; rx_tch_a.dl->fire_crc = ((dsp_api.ndb->a_cd[0] & 0xffff) & ((1 << B_FIRE1) | (1 << B_FIRE0))) >> B_FIRE0; /* Update rx level for pm report */ -- cgit v1.2.3