diff options
-rw-r--r-- | include/osmo-bts/pcu_if.h | 2 | ||||
-rw-r--r-- | include/osmo-bts/pcuif_proto.h | 5 | ||||
-rw-r--r-- | include/osmo-bts/scheduler_backend.h | 6 | ||||
-rw-r--r-- | src/common/l1sap.c | 7 | ||||
-rw-r--r-- | src/common/pcu_sock.c | 5 | ||||
-rw-r--r-- | src/common/scheduler.c | 9 | ||||
-rw-r--r-- | src/osmo-bts-litecell15/l1_if.c | 6 | ||||
-rw-r--r-- | src/osmo-bts-octphy/l1_if.c | 13 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/l1_if.c | 6 | ||||
-rw-r--r-- | src/osmo-bts-trx/scheduler_trx.c | 30 |
10 files changed, 71 insertions, 18 deletions
diff --git a/include/osmo-bts/pcu_if.h b/include/osmo-bts/pcu_if.h index 3ce4d0b2..efad0c5e 100644 --- a/include/osmo-bts/pcu_if.h +++ b/include/osmo-bts/pcu_if.h @@ -10,7 +10,7 @@ int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, uint16_t arfcn, uint8_t block_nr); int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len, - int8_t rssi); + int8_t rssi, uint16_t ber10k, int16_t bto, int16_t lqual); int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint8_t ra, uint32_t fn); int pcu_tx_time_ind(uint32_t fn); int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed); diff --git a/include/osmo-bts/pcuif_proto.h b/include/osmo-bts/pcuif_proto.h index 9d740ac1..07d35f82 100644 --- a/include/osmo-bts/pcuif_proto.h +++ b/include/osmo-bts/pcuif_proto.h @@ -1,7 +1,7 @@ #ifndef _PCUIF_PROTO_H #define _PCUIF_PROTO_H -#define PCU_IF_VERSION 0x05 +#define PCU_IF_VERSION 0x06 /* msg_type */ #define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */ @@ -50,6 +50,9 @@ struct gsm_pcu_if_data { uint8_t ts_nr; uint8_t block_nr; int8_t rssi; + uint16_t ber10k; /*!< \brief BER in units of 0.01% */ + int16_t ta_offs_qbits; /* !< \brief Burst TA Offset in quarter bits */ + int16_t lqual_cb; /* !< \brief Link quality in centiBel */ } __attribute__ ((packed)); struct gsm_pcu_if_rts_req { diff --git a/include/osmo-bts/scheduler_backend.h b/include/osmo-bts/scheduler_backend.h index 68f0c605..e63b9616 100644 --- a/include/osmo-bts/scheduler_backend.h +++ b/include/osmo-bts/scheduler_backend.h @@ -43,7 +43,11 @@ struct msgb *_sched_dequeue_prim(struct l1sched_trx *l1t, int8_t tn, uint32_t fn enum trx_chan_type chan); int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t *l2, uint8_t l2_len, float rssi, enum osmo_ph_pres_info_type presence_info); + enum trx_chan_type chan, uint8_t *l2, + uint8_t l2_len, float rssi, + int16_t ta_offs_qbits, int16_t link_qual_cb, + uint16_t ber10k, + enum osmo_ph_pres_info_type presence_info); int _sched_compose_tch_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len); diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 4f6cf05d..304f7185 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -820,7 +820,9 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, if (L1SAP_IS_PTCCH(fn)) { pcu_tx_data_ind(&trx->ts[tn], 1, fn, 0 /* ARFCN */, L1SAP_FN2PTCCHBLOCK(fn), - data, len, rssi); + data, len, rssi, data_ind->ber10k, + data_ind->ta_offs_qbits, + data_ind->lqual_cb); return 0; } @@ -829,7 +831,8 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, return 0; /* PDTCH / PACCH frame handling */ pcu_tx_data_ind(&trx->ts[tn], 0, fn, 0 /* ARFCN */, - L1SAP_FN2MACBLOCK(fn), data, len, rssi); + L1SAP_FN2MACBLOCK(fn), data, len, rssi, data_ind->ber10k, + data_ind->ta_offs_qbits, data_ind->lqual_cb); return 0; } diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index 22b6fabf..fed464fb 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -337,7 +337,7 @@ int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len, - int8_t rssi) + int8_t rssi, uint16_t ber10k, int16_t bto, int16_t lqual) { struct msgb *msg; struct gsm_pcu_if *pcu_prim; @@ -362,6 +362,9 @@ int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, data_ind->ts_nr = ts->nr; data_ind->block_nr = block_nr; data_ind->rssi = rssi; + data_ind->ber10k = ber10k; + data_ind->ta_offs_qbits = bto; + data_ind->lqual_cb = lqual; memcpy(data_ind->data, data, len); data_ind->len = len; diff --git a/src/common/scheduler.c b/src/common/scheduler.c index eeaf2c13..ec66cfc4 100644 --- a/src/common/scheduler.c +++ b/src/common/scheduler.c @@ -295,7 +295,11 @@ found_msg: } int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t *l2, uint8_t l2_len, float rssi, enum osmo_ph_pres_info_type presence_info) + enum trx_chan_type chan, uint8_t *l2, + uint8_t l2_len, float rssi, + int16_t ta_offs_qbits, int16_t link_qual_cb, + uint16_t ber10k, + enum osmo_ph_pres_info_type presence_info) { struct msgb *msg; struct osmo_phsap_prim *l1sap; @@ -311,6 +315,9 @@ int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, l1sap->u.data.link_id = trx_chan_desc[chan].link_id; l1sap->u.data.fn = fn; l1sap->u.data.rssi = (int8_t) (rssi); + l1sap->u.data.ber10k = ber10k; + l1sap->u.data.ta_offs_qbits = ta_offs_qbits; + l1sap->u.data.lqual_cb = link_qual_cb; l1sap->u.data.pdch_presence_info = presence_info; msg->l2h = msgb_put(msg, l2_len); if (l2_len) diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index a979bd7f..dcd25ee6 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -916,7 +916,11 @@ static int handle_ph_data_ind(struct lc15l1_hdl *fl1, GsmL1_PhDataInd_t *data_in l1sap->u.data.chan_nr = chan_nr; l1sap->u.data.fn = fn; l1sap->u.data.rssi = rssi; - + if (!pcu_direct) { + l1sap->u.data.ber10k = data_ind->measParam.fBer * 10000; + l1sap->u.data.ta_offs_qbits = data_ind->measParam.i16BurstTiming; + l1sap->u.data.lqual_cb = data_ind->measParam.fLinkQuality * 10; + } return l1sap_up(trx, l1sap); } diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index 760c988f..d621bcf5 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -961,7 +961,8 @@ static int handle_ph_data_ind(struct octphy_hdl *fl1, struct osmo_phsap_prim *l1sap; uint32_t fn; uint8_t *data; - uint16_t len; + uint16_t len, b_total, b_error; + int16_t snr; int8_t rssi; int rc; @@ -1029,6 +1030,16 @@ static int handle_ph_data_ind(struct octphy_hdl *fl1, l1sap->u.data.chan_nr = chan_nr; l1sap->u.data.fn = fn; l1sap->u.data.rssi = rssi; + b_total = data_ind->MeasurementInfo.usBERTotalBitCnt; + b_error =data_ind->MeasurementInfo.usBERCnt; + l1sap->u.data.ber10k = b_total ? 10000 * b_error / b_total : 0; + l1sap->u.data.ta_offs_qbits = data_ind->MeasurementInfo.sBurstTiming4x; + snr = data_ind->MeasurementInfo.sSNRDb; + /* FIXME: better converion formulae for SnR -> C / I? + l1sap->u.data.lqual_cb = (snr ? snr : (snr - 65536)) * 10 / 256; + LOGP(DL1C, LOGL_ERROR, "SnR: raw %d, computed %d\n", snr, l1sap->u.data.lqual_cb); + */ + l1sap->u.data.lqual_cb = (snr ? snr : (snr - 65536)) * 100; l1sap->u.data.pdch_presence_info = PRES_INFO_BOTH; /* FIXME: consider EDGE support */ l1sap_up(trx, l1sap); diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 45de199c..f70ccf5d 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -904,7 +904,11 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i l1sap->u.data.chan_nr = chan_nr; l1sap->u.data.fn = fn; l1sap->u.data.rssi = (int8_t) (data_ind->measParam.fRssi); - + if (!pcu_direct) { + l1sap->u.data.ber10k = data_ind->measParam.fBer * 10000; + l1sap->u.data.ta_offs_qbits = data_ind->measParam.i16BurstTiming; + l1sap->u.data.lqual_cb = data_ind->measParam.fLinkQuality * 10; + } /* copy data from L1 primitive to L1SAP primitive */ sap_msg->l2h = msgb_put(sap_msg, data_ind->msgUnitParam.u8Size); memcpy(sap_msg->l2h, data_ind->msgUnitParam.u8Buffer, diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c index 3a6ede37..e02232b2 100644 --- a/src/osmo-bts-trx/scheduler_trx.c +++ b/src/osmo-bts-trx/scheduler_trx.c @@ -200,8 +200,10 @@ got_msg: /* Send uplnk measurement information to L2 */ l1if_process_meas_res(l1t->trx, tn, fn, trx_chan_desc[chan].chan_nr | tn, 456, 456, -110, 0); - - _sched_compose_ph_data_ind(l1t, tn, 0, chan, NULL, 0, -110, PRES_INFO_INVALID); + /* FIXME: use actual values for BER etc */ + _sched_compose_ph_data_ind(l1t, tn, 0, chan, NULL, 0, + -110, 0, 0, 10000, + PRES_INFO_INVALID); } } @@ -886,8 +888,12 @@ int rx_data_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, /* Send uplnk measurement information to L2 */ l1if_process_meas_res(l1t->trx, tn, fn, trx_chan_desc[chan].chan_nr | tn, n_errors, n_bits_total, *rssi_sum / *rssi_num, *toa_sum / *toa_num); - - return _sched_compose_ph_data_ind(l1t, tn, *first_fn, chan, l2, l2_len, *rssi_sum / *rssi_num, PRES_INFO_UNKNOWN); + uint16_t ber10k = + (n_bits_total == 0) ? 10000 : 10000 * n_errors / n_bits_total; + return _sched_compose_ph_data_ind(l1t, tn, *first_fn, chan, l2, l2_len, + *rssi_sum / *rssi_num, + 4 * (*toa_sum) / *toa_num, 0, ber10k, + PRES_INFO_UNKNOWN); } int rx_pdtch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, @@ -985,9 +991,11 @@ int rx_pdtch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, l1ts->mf_period, trx_chan_desc[chan].name); return 0; } - + uint16_t ber10k = + (n_bits_total == 0) ? 10000 : 10000 * n_errors / n_bits_total; return _sched_compose_ph_data_ind(l1t, tn, (fn + GSM_HYPERFRAME - 3) % GSM_HYPERFRAME, chan, - l2, rc, *rssi_sum / *rssi_num, PRES_INFO_BOTH); + l2, rc, *rssi_sum / *rssi_num, 4 * (*toa_sum) / *toa_num, 0, + ber10k, PRES_INFO_BOTH); } int rx_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, @@ -1105,8 +1113,11 @@ int rx_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, /* FACCH */ if (rc == GSM_MACBLOCK_LEN) { + uint16_t ber10k = (n_bits_total == 0) ? 10000 : + 10000 * n_errors / n_bits_total; _sched_compose_ph_data_ind(l1t, tn, (fn + GSM_HYPERFRAME - 7) % GSM_HYPERFRAME, chan, - tch_data + amr, GSM_MACBLOCK_LEN, rssi, PRES_INFO_UNKNOWN); + tch_data + amr, GSM_MACBLOCK_LEN, rssi, 4 * toa, 0, + ber10k, PRES_INFO_UNKNOWN); bfi: if (rsl_cmode == RSL_CMOD_SPD_SPEECH) { /* indicate bad frame */ @@ -1275,9 +1286,12 @@ int rx_tchh_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, /* FACCH */ if (rc == GSM_MACBLOCK_LEN) { chan_state->ul_ongoing_facch = 1; + uint16_t ber10k = + (n_bits_total == 0) ? 10000 : 10000 * n_errors / n_bits_total; _sched_compose_ph_data_ind(l1t, tn, (fn + GSM_HYPERFRAME - 10 - ((fn % 26) >= 19)) % GSM_HYPERFRAME, chan, - tch_data + amr, GSM_MACBLOCK_LEN, rssi, PRES_INFO_UNKNOWN); + tch_data + amr, GSM_MACBLOCK_LEN, rssi, 4 * toa, 0, + ber10k, PRES_INFO_UNKNOWN); bfi: if (rsl_cmode == RSL_CMOD_SPD_SPEECH) { /* indicate bad frame */ |