L1SAP: Increase resolution of reported burst timing

Before this patch we had:
* osmo-bts-trx internally using 1/256th bit/symbol period
* osmo-bts-sysmo internally using 1/4 bit/smbol period
* PCU interface using 1/4
* L1SAP interface using 1/4
* measurement processing code on top of L1SAP using 1/256

So for sysmo/lc15/octphy we are not loosing resolution, but for
osmo-bts-trx we're arbitrarily reducing the resolution via L1SAP
only then to compute with higher resolution again.

Let's change L1SAP to use 1/256 bits and hence not loose any resolution.
This requires a corresponding change in libosmocore for l1sap.h, which
is found in Change-Id Ibb58113c2819fe2d6d23ecbcfb8b3fce4055025d

Change-Id: If9b0f617845ba6c4aa47969f521734388197c9a7
This commit is contained in:
Harald Welte 2018-02-27 16:58:46 +01:00
parent c092f4e1de
commit acefd0586e
8 changed files with 19 additions and 19 deletions

View File

@ -51,7 +51,7 @@ struct msgb *_sched_dequeue_prim(struct l1sched_trx *l1t, int8_t tn, uint32_t fn
int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t *l2, enum trx_chan_type chan, uint8_t *l2,
uint8_t l2_len, float rssi, uint8_t l2_len, float rssi,
int16_t ta_offs_qbits, int16_t link_qual_cb, int16_t ta_offs_256bits, int16_t link_qual_cb,
uint16_t ber10k, uint16_t ber10k,
enum osmo_ph_pres_info_type presence_info); enum osmo_ph_pres_info_type presence_info);

View File

@ -512,8 +512,8 @@ static int l1sap_info_meas_ind(struct gsm_bts_trx *trx,
} }
DEBUGPFN(DL1P, info_meas_ind->fn, DEBUGPFN(DL1P, info_meas_ind->fn,
"%s MPH_INFO meas ind, ta_offs_qbits=%d, ber10k=%d, inv_rssi=%u\n", "%s MPH_INFO meas ind, ta_offs_256bits=%d, ber10k=%d, inv_rssi=%u\n",
gsm_lchan_name(lchan), info_meas_ind->ta_offs_qbits, gsm_lchan_name(lchan), info_meas_ind->ta_offs_256bits,
info_meas_ind->ber10k, info_meas_ind->inv_rssi); info_meas_ind->ber10k, info_meas_ind->inv_rssi);
/* in the GPRS case we are not interested in measurement /* in the GPRS case we are not interested in measurement
@ -522,13 +522,13 @@ static int l1sap_info_meas_ind(struct gsm_bts_trx *trx,
return 0; return 0;
memset(&ulm, 0, sizeof(ulm)); memset(&ulm, 0, sizeof(ulm));
ulm.ta_offs_256bits = info_meas_ind->ta_offs_qbits*(256/4); ulm.ta_offs_256bits = info_meas_ind->ta_offs_256bits;
ulm.ber10k = info_meas_ind->ber10k; ulm.ber10k = info_meas_ind->ber10k;
ulm.inv_rssi = info_meas_ind->inv_rssi; ulm.inv_rssi = info_meas_ind->inv_rssi;
ulm.is_sub = info_meas_ind->is_sub; ulm.is_sub = info_meas_ind->is_sub;
/* we assume that symbol period is 1 bit: */ /* we assume that symbol period is 1 bit: */
set_ms_to_data(lchan, info_meas_ind->ta_offs_qbits / 4, true); set_ms_to_data(lchan, info_meas_ind->ta_offs_256bits / 256, true);
lchan_new_ul_meas(lchan, &ulm, info_meas_ind->fn); lchan_new_ul_meas(lchan, &ulm, info_meas_ind->fn);
@ -1058,7 +1058,7 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
pcu_tx_data_ind(&trx->ts[tn], PCU_IF_SAPI_PTCCH, fn, pcu_tx_data_ind(&trx->ts[tn], PCU_IF_SAPI_PTCCH, fn,
0 /* ARFCN */, L1SAP_FN2PTCCHBLOCK(fn), 0 /* ARFCN */, L1SAP_FN2PTCCHBLOCK(fn),
data, len, rssi, data_ind->ber10k, data, len, rssi, data_ind->ber10k,
data_ind->ta_offs_qbits, data_ind->ta_offs_256bits/64,
data_ind->lqual_cb); data_ind->lqual_cb);
} else { } else {
/* drop incomplete UL block */ /* drop incomplete UL block */
@ -1067,7 +1067,7 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
/* PDTCH / PACCH frame handling */ /* PDTCH / PACCH frame handling */
pcu_tx_data_ind(&trx->ts[tn], PCU_IF_SAPI_PDTCH, fn, 0 /* ARFCN */, pcu_tx_data_ind(&trx->ts[tn], PCU_IF_SAPI_PDTCH, fn, 0 /* ARFCN */,
L1SAP_FN2MACBLOCK(fn), data, len, rssi, data_ind->ber10k, L1SAP_FN2MACBLOCK(fn), data, len, rssi, data_ind->ber10k,
data_ind->ta_offs_qbits, data_ind->lqual_cb); data_ind->ta_offs_256bits/64, data_ind->lqual_cb);
} }
return 0; return 0;
} }

View File

@ -340,7 +340,7 @@ found_msg:
int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t *l2, enum trx_chan_type chan, uint8_t *l2,
uint8_t l2_len, float rssi, uint8_t l2_len, float rssi,
int16_t ta_offs_qbits, int16_t link_qual_cb, int16_t ta_offs_256bits, int16_t link_qual_cb,
uint16_t ber10k, uint16_t ber10k,
enum osmo_ph_pres_info_type presence_info) enum osmo_ph_pres_info_type presence_info)
{ {
@ -359,7 +359,7 @@ int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
l1sap->u.data.fn = fn; l1sap->u.data.fn = fn;
l1sap->u.data.rssi = (int8_t) (rssi); l1sap->u.data.rssi = (int8_t) (rssi);
l1sap->u.data.ber10k = ber10k; l1sap->u.data.ber10k = ber10k;
l1sap->u.data.ta_offs_qbits = ta_offs_qbits; l1sap->u.data.ta_offs_256bits = ta_offs_256bits;
l1sap->u.data.lqual_cb = link_qual_cb; l1sap->u.data.lqual_cb = link_qual_cb;
l1sap->u.data.pdch_presence_info = presence_info; l1sap->u.data.pdch_presence_info = presence_info;
msg->l2h = msgb_put(msg, l2_len); msg->l2h = msgb_put(msg, l2_len);

View File

@ -907,7 +907,7 @@ static int process_meas_res(struct gsm_bts_trx *trx, uint8_t chan_nr,
PRIM_OP_INDICATION, NULL); PRIM_OP_INDICATION, NULL);
l1sap.u.info.type = PRIM_INFO_MEAS; l1sap.u.info.type = PRIM_INFO_MEAS;
l1sap.u.info.u.meas_ind.chan_nr = chan_nr; l1sap.u.info.u.meas_ind.chan_nr = chan_nr;
l1sap.u.info.u.meas_ind.ta_offs_qbits = m->i16BurstTiming; l1sap.u.info.u.meas_ind.ta_offs_256bits = m->i16BurstTiming*64;
l1sap.u.info.u.meas_ind.ber10k = (unsigned int) (m->fBer * 10000); l1sap.u.info.u.meas_ind.ber10k = (unsigned int) (m->fBer * 10000);
l1sap.u.info.u.meas_ind.inv_rssi = (uint8_t) (m->fRssi * -1); l1sap.u.info.u.meas_ind.inv_rssi = (uint8_t) (m->fRssi * -1);
l1sap.u.info.u.meas_ind.fn = fn; l1sap.u.info.u.meas_ind.fn = fn;
@ -983,7 +983,7 @@ static int handle_ph_data_ind(struct lc15l1_hdl *fl1, GsmL1_PhDataInd_t *data_in
l1sap->u.data.rssi = rssi; l1sap->u.data.rssi = rssi;
if (!pcu_direct) { if (!pcu_direct) {
l1sap->u.data.ber10k = data_ind->measParam.fBer * 10000; l1sap->u.data.ber10k = data_ind->measParam.fBer * 10000;
l1sap->u.data.ta_offs_qbits = data_ind->measParam.i16BurstTiming; l1sap->u.data.ta_offs_256bits = data_ind->measParam.i16BurstTiming*64;
l1sap->u.data.lqual_cb = data_ind->measParam.fLinkQuality * 10; l1sap->u.data.lqual_cb = data_ind->measParam.fLinkQuality * 10;
} }
return l1sap_up(trx, l1sap); return l1sap_up(trx, l1sap);

View File

@ -876,7 +876,7 @@ static void process_meas_res(struct gsm_bts_trx *trx, uint8_t chan_nr,
/* Update Timing offset for valid radio block */ /* Update Timing offset for valid radio block */
if (data_len != 0) { if (data_len != 0) {
/* burst timing in 1x */ /* burst timing in 1x */
l1sap.u.info.u.meas_ind.ta_offs_qbits = m->sBurstTiming; l1sap.u.info.u.meas_ind.ta_offs_256bits = m->sBurstTiming4x*64;
} else { } else {
/* FIXME, In current implementation, OCTPHY would send DATA_IND /* FIXME, In current implementation, OCTPHY would send DATA_IND
* for all radio blocks (valid or invalid) But timing offset * for all radio blocks (valid or invalid) But timing offset
@ -884,7 +884,7 @@ static void process_meas_res(struct gsm_bts_trx *trx, uint8_t chan_nr,
* counter to accumulate Timing offset.. even we add zero for * counter to accumulate Timing offset.. even we add zero for
* invalid block.. timing offset average calucation would not * invalid block.. timing offset average calucation would not
* correct. */ * correct. */
l1sap.u.info.u.meas_ind.ta_offs_qbits = 0; l1sap.u.info.u.meas_ind.ta_offs_256bits = 0;
} }
l1sap.u.info.u.meas_ind.ber10k = oct_meas2ber10k(m); l1sap.u.info.u.meas_ind.ber10k = oct_meas2ber10k(m);
@ -1145,7 +1145,7 @@ static int handle_ph_data_ind(struct octphy_hdl *fl1,
l1sap->u.data.ber10k = oct_meas2ber10k(&data_ind->MeasurementInfo); l1sap->u.data.ber10k = oct_meas2ber10k(&data_ind->MeasurementInfo);
/* burst timing in 1x but PCU is expecting 4X */ /* burst timing in 1x but PCU is expecting 4X */
l1sap->u.data.ta_offs_qbits = data_ind->MeasurementInfo.sBurstTiming4x; l1sap->u.data.ta_offs_256bits = data_ind->MeasurementInfo.sBurstTiming4x*64;
snr = data_ind->MeasurementInfo.sSNRDb; snr = data_ind->MeasurementInfo.sSNRDb;
/* FIXME: better converion formulae for SnR -> C / I? /* FIXME: better converion formulae for SnR -> C / I?
l1sap->u.data.lqual_cb = (snr ? snr : (snr - 65536)) * 10 / 256; l1sap->u.data.lqual_cb = (snr ? snr : (snr - 65536)) * 10 / 256;

View File

@ -904,7 +904,7 @@ static int process_meas_res(struct gsm_bts_trx *trx, uint8_t chan_nr,
PRIM_OP_INDICATION, NULL); PRIM_OP_INDICATION, NULL);
l1sap.u.info.type = PRIM_INFO_MEAS; l1sap.u.info.type = PRIM_INFO_MEAS;
l1sap.u.info.u.meas_ind.chan_nr = chan_nr; l1sap.u.info.u.meas_ind.chan_nr = chan_nr;
l1sap.u.info.u.meas_ind.ta_offs_qbits = m->i16BurstTiming; l1sap.u.info.u.meas_ind.ta_offs_256bits = m->i16BurstTiming * 64;
l1sap.u.info.u.meas_ind.ber10k = (unsigned int) (m->fBer * 10000); l1sap.u.info.u.meas_ind.ber10k = (unsigned int) (m->fBer * 10000);
l1sap.u.info.u.meas_ind.inv_rssi = (uint8_t) (m->fRssi * -1); l1sap.u.info.u.meas_ind.inv_rssi = (uint8_t) (m->fRssi * -1);
l1sap.u.info.u.meas_ind.fn = fn; l1sap.u.info.u.meas_ind.fn = fn;
@ -965,7 +965,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
l1sap->u.data.rssi = (int8_t) (data_ind->measParam.fRssi); l1sap->u.data.rssi = (int8_t) (data_ind->measParam.fRssi);
if (!pcu_direct) { /* FIXME: if pcu_direct=1, then this is not set, what to do in pcu_tx_data_ind() in this case ?*/ if (!pcu_direct) { /* FIXME: if pcu_direct=1, then this is not set, what to do in pcu_tx_data_ind() in this case ?*/
l1sap->u.data.ber10k = data_ind->measParam.fBer * 10000; l1sap->u.data.ber10k = data_ind->measParam.fBer * 10000;
l1sap->u.data.ta_offs_qbits = data_ind->measParam.i16BurstTiming; l1sap->u.data.ta_offs_256bits = data_ind->measParam.i16BurstTiming * 64;
l1sap->u.data.lqual_cb = data_ind->measParam.fLinkQuality * 10; l1sap->u.data.lqual_cb = data_ind->measParam.fLinkQuality * 10;
} }
/* copy data from L1 primitive to L1SAP primitive */ /* copy data from L1 primitive to L1SAP primitive */

View File

@ -495,7 +495,7 @@ static void l1if_fill_meas_res(struct osmo_phsap_prim *l1sap, uint8_t chan_nr, i
PRIM_OP_INDICATION, NULL); PRIM_OP_INDICATION, NULL);
l1sap->u.info.type = PRIM_INFO_MEAS; l1sap->u.info.type = PRIM_INFO_MEAS;
l1sap->u.info.u.meas_ind.chan_nr = chan_nr; l1sap->u.info.u.meas_ind.chan_nr = chan_nr;
l1sap->u.info.u.meas_ind.ta_offs_qbits = toa256/64; l1sap->u.info.u.meas_ind.ta_offs_256bits = toa256;
l1sap->u.info.u.meas_ind.ber10k = (unsigned int) (ber * 10000); l1sap->u.info.u.meas_ind.ber10k = (unsigned int) (ber * 10000);
l1sap->u.info.u.meas_ind.inv_rssi = (uint8_t) (rssi * -1); l1sap->u.info.u.meas_ind.inv_rssi = (uint8_t) (rssi * -1);
l1sap->u.info.u.meas_ind.fn = fn; l1sap->u.info.u.meas_ind.fn = fn;

View File

@ -145,7 +145,7 @@ static void virt_um_rcv_cb(struct virt_um_inst *vui, struct msgb *msg)
l1sap.u.data.fn = fn; l1sap.u.data.fn = fn;
l1sap.u.data.rssi = 0; /* Radio Signal Strength Indicator. Best -> 0 */ l1sap.u.data.rssi = 0; /* Radio Signal Strength Indicator. Best -> 0 */
l1sap.u.data.ber10k = 0; /* Bit Error Rate in 0.01%. Best -> 0 */ l1sap.u.data.ber10k = 0; /* Bit Error Rate in 0.01%. Best -> 0 */
l1sap.u.data.ta_offs_qbits = 0; /* Burst time of arrival in quarter bits. Probably used for Timing Advance calc. Best -> 0 */ l1sap.u.data.ta_offs_256bits = 0; /* Burst time of arrival in quarter bits. Probably used for Timing Advance calc. Best -> 0 */
l1sap.u.data.lqual_cb = 10 * signal_dbm; /* Link quality in centiBel = 10 * dB. */ l1sap.u.data.lqual_cb = 10 * signal_dbm; /* Link quality in centiBel = 10 * dB. */
l1sap.u.data.pdch_presence_info = PRES_INFO_BOTH; l1sap.u.data.pdch_presence_info = PRES_INFO_BOTH;
l1if_process_meas_res(pinst->trx, timeslot, fn, chan_nr, 0, 0, 0, 0); l1if_process_meas_res(pinst->trx, timeslot, fn, chan_nr, 0, 0, 0, 0);
@ -303,7 +303,7 @@ static void l1if_fill_meas_res(struct osmo_phsap_prim *l1sap, uint8_t chan_nr, f
PRIM_OP_INDICATION, NULL); PRIM_OP_INDICATION, NULL);
l1sap->u.info.type = PRIM_INFO_MEAS; l1sap->u.info.type = PRIM_INFO_MEAS;
l1sap->u.info.u.meas_ind.chan_nr = chan_nr; l1sap->u.info.u.meas_ind.chan_nr = chan_nr;
l1sap->u.info.u.meas_ind.ta_offs_qbits = (int16_t)(ta*4); l1sap->u.info.u.meas_ind.ta_offs_256bits = (int16_t)(ta*4);
l1sap->u.info.u.meas_ind.ber10k = (unsigned int) (ber * 10000); l1sap->u.info.u.meas_ind.ber10k = (unsigned int) (ber * 10000);
l1sap->u.info.u.meas_ind.inv_rssi = (uint8_t) (rssi * -1); l1sap->u.info.u.meas_ind.inv_rssi = (uint8_t) (rssi * -1);
l1sap->u.info.u.meas_ind.fn = fn; l1sap->u.info.u.meas_ind.fn = fn;