aboutsummaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2019-10-31 09:36:17 +0100
committerlaforge <laforge@osmocom.org>2020-01-20 14:35:19 +0000
commitd4f67591c77dd011bb4886d92565fb5014437330 (patch)
treeeffe95a8b5b46716fe6aff5448e217e6df9c4894 /src/common
parent8969adc5d940e32031ade68e4eb2fdf7ac4e17d0 (diff)
l1sap: merge MEAS IND into PRIM PH DATA / PRIM TCH
The MPH INFO MEAS IND indication, which contains the uplink measurement data is sent in parallel to the PH DATA and TCH indications as a separate indications. This makes the overall uplink measurement data processing unnecessarly complex. So lets put the data that is relevant for measurement into the PH DATA and TCH indications directly. This change only affects osmo-bts-trx at the moment. In order to keep the upper layers (l1sap.c) compatible we add an autodection to switch between separate measurement indications and included measurement data. Related: OS#2977 Depends: libosmocore I2c34b02d329f9df190c5035c396403ca0a4f9c42 Change-Id: I710d0b7cf193afa8515807836ee69b8b7db84a84
Diffstat (limited to 'src/common')
-rw-r--r--src/common/gsm_data_shared.c1
-rw-r--r--src/common/l1sap.c108
-rw-r--r--src/common/scheduler.c7
3 files changed, 95 insertions, 21 deletions
diff --git a/src/common/gsm_data_shared.c b/src/common/gsm_data_shared.c
index b31d458b..c4a60b51 100644
--- a/src/common/gsm_data_shared.c
+++ b/src/common/gsm_data_shared.c
@@ -109,6 +109,7 @@ const struct value_string gsm_bts_features_descs[] = {
{ BTS_FEAT_SPEECH_H_AMR, "Halfrate speech AMR" },
{ BTS_FEAT_ETWS_PN, "ETWS Primary Notification on PCH" },
{ BTS_FEAT_MS_PWR_CTRL_DSP, "DSP/HW based MS Power Control Loop" },
+ { BTS_FEAT_MEAS_PAYLOAD_COMB, "Measurement and Payload data combined"},
{ 0, NULL }
};
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index 889f7f60..21f3a8a8 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -629,42 +629,93 @@ static inline void set_ms_to_data(struct gsm_lchan *lchan, int16_t data, bool se
}
/* measurement information received from bts model */
-static int l1sap_info_meas_ind(struct gsm_bts_trx *trx,
- struct osmo_phsap_prim *l1sap,
- struct info_meas_ind_param *info_meas_ind)
+static void process_l1sap_meas_data(struct gsm_bts_trx *trx,
+ struct osmo_phsap_prim *l1sap,
+ enum osmo_ph_prim ind_type)
{
struct bts_ul_meas ulm;
struct gsm_lchan *lchan;
+ struct info_meas_ind_param *info_meas_ind;
+ struct ph_data_param *ph_data_ind;
+ struct ph_tch_param *ph_tch_ind;
+ uint8_t chan_nr;
+ uint32_t fn;
+ uint8_t inv_rssi;
+ uint8_t is_sub;
+ int16_t ta_offs_256bits;
+ uint16_t ber10k;
+ const char *ind_name;
+
+ switch (ind_type) {
+ case PRIM_MPH_INFO:
+ /* (legacy way, see also OS#2977) */
+ info_meas_ind = &l1sap->u.info.u.meas_ind;
+ chan_nr = info_meas_ind->chan_nr;
+ fn = info_meas_ind->fn;
+ inv_rssi = info_meas_ind->inv_rssi;
+ is_sub = info_meas_ind->is_sub;
+ ta_offs_256bits = info_meas_ind->ta_offs_256bits;
+ ber10k = info_meas_ind->ber10k;
+ ind_name = "MPH INFO";
+ break;
+ case PRIM_TCH:
+ ph_tch_ind = &l1sap->u.tch;
+ if (ph_tch_ind->rssi == 0)
+ return;
+ chan_nr = ph_tch_ind->chan_nr;
+ fn = ph_tch_ind->fn;
+ inv_rssi = abs(ph_tch_ind->rssi);
+ is_sub = ph_tch_ind->is_sub;
+ ta_offs_256bits = ph_tch_ind->ta_offs_256bits;
+ ber10k = ph_tch_ind->ber10k;
+ ind_name = "TCH";
+ break;
+ case PRIM_PH_DATA:
+ ph_data_ind = &l1sap->u.data;
+ if (ph_data_ind->rssi == 0)
+ return;
+ chan_nr = ph_data_ind->chan_nr;
+ fn = ph_data_ind->fn;
+ inv_rssi = abs(ph_data_ind->rssi);
+ is_sub = ph_data_ind->is_sub;
+ ta_offs_256bits = ph_data_ind->ta_offs_256bits;
+ ber10k = ph_data_ind->ber10k;
+ ind_name = "DATA";
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
- lchan = get_active_lchan_by_chan_nr(trx, info_meas_ind->chan_nr);
+ lchan = get_active_lchan_by_chan_nr(trx, chan_nr);
if (!lchan) {
- LOGPFN(DL1P, LOGL_ERROR, info_meas_ind->fn,
- "No lchan for MPH INFO MEAS IND (chan_nr=%s)\n", rsl_chan_nr_str(info_meas_ind->chan_nr));
- return 0;
+ LOGPFN(DL1P, LOGL_ERROR, fn,
+ "No lchan for %s MEAS IND (chan_nr=%s)\n",
+ ind_name, rsl_chan_nr_str(chan_nr));
+ return;
}
- DEBUGPFN(DL1P, info_meas_ind->fn,
- "%s MPH_INFO meas ind, ta_offs_256bits=%d, ber10k=%d, inv_rssi=%u\n",
- gsm_lchan_name(lchan), info_meas_ind->ta_offs_256bits,
- info_meas_ind->ber10k, info_meas_ind->inv_rssi);
+ DEBUGPFN(DL1P, fn,
+ "%s %s meas ind, ta_offs_256bits=%d, ber10k=%d, inv_rssi=%u\n",
+ gsm_lchan_name(lchan), ind_name, ta_offs_256bits, ber10k,
+ inv_rssi);
/* in the GPRS case we are not interested in measurement
* processing. The PCU will take care of it */
if (lchan->type == GSM_LCHAN_PDTCH)
- return 0;
+ return;
memset(&ulm, 0, sizeof(ulm));
- ulm.ta_offs_256bits = info_meas_ind->ta_offs_256bits;
- ulm.ber10k = info_meas_ind->ber10k;
- ulm.inv_rssi = info_meas_ind->inv_rssi;
- ulm.is_sub = info_meas_ind->is_sub;
+ ulm.ta_offs_256bits = ta_offs_256bits;
+ ulm.ber10k = ber10k;
+ ulm.inv_rssi = inv_rssi;
+ ulm.is_sub = is_sub;
/* we assume that symbol period is 1 bit: */
- set_ms_to_data(lchan, info_meas_ind->ta_offs_256bits / 256, true);
+ set_ms_to_data(lchan, ta_offs_256bits / 256, true);
- lchan_meas_process_measurement(lchan, &ulm, info_meas_ind->fn);
+ lchan_meas_process_measurement(lchan, &ulm, fn);
- return 0;
+ return;
}
/* any L1 MPH_INFO indication prim received from bts model */
@@ -685,7 +736,12 @@ static int l1sap_mph_info_ind(struct gsm_bts_trx *trx,
&info->u.time_ind);
break;
case PRIM_INFO_MEAS:
- rc = l1sap_info_meas_ind(trx, l1sap, &info->u.meas_ind);
+ /* We should never get an INFO_IND with PRIM_INFO_MEAS
+ * when BTS_FEAT_MEAS_PAYLOAD_COMB is enabled */
+ if (gsm_bts_has_feature(trx->bts, BTS_FEAT_MEAS_PAYLOAD_COMB))
+ OSMO_ASSERT(false);
+
+ process_l1sap_meas_data(trx, l1sap, PRIM_MPH_INFO);
break;
default:
LOGP(DL1P, LOGL_NOTICE, "unknown MPH_INFO ind type %d\n",
@@ -1200,6 +1256,12 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
return -EINVAL;
}
+ /* The ph_data_param contained in the l1sap primitive may contain
+ * measurement data. If this data is present, forward it for
+ * processing */
+ if (gsm_bts_has_feature(trx->bts, BTS_FEAT_MEAS_PAYLOAD_COMB))
+ process_l1sap_meas_data(trx, l1sap, PRIM_PH_DATA);
+
if (ts_is_pdch(&trx->ts[tn])) {
lchan = get_lchan_by_chan_nr(trx, chan_nr);
if (!lchan)
@@ -1315,6 +1377,12 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap,
return 0;
}
+ /* The ph_tch_param contained in the l1sap primitive may contain
+ * measurement data. If this data is present, forward it for
+ * processing */
+ if (gsm_bts_has_feature(trx->bts, BTS_FEAT_MEAS_PAYLOAD_COMB))
+ process_l1sap_meas_data(trx, l1sap, PRIM_TCH);
+
msgb_pull(msg, sizeof(*l1sap));
/* Low level layers always call us when TCH content is expected, even if
diff --git a/src/common/scheduler.c b/src/common/scheduler.c
index 3713b063..e8df5373 100644
--- a/src/common/scheduler.c
+++ b/src/common/scheduler.c
@@ -753,7 +753,8 @@ int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
}
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)
+ enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len,
+ int16_t ta_offs_256bits, uint16_t ber10k, float rssi)
{
struct msgb *msg;
struct osmo_phsap_prim *l1sap;
@@ -769,6 +770,10 @@ int _sched_compose_tch_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
PRIM_OP_INDICATION, msg);
l1sap->u.tch.chan_nr = chan_nr;
l1sap->u.tch.fn = fn;
+ l1sap->u.tch.rssi = (int8_t) (rssi);
+ l1sap->u.tch.ber10k = ber10k;
+ l1sap->u.tch.ta_offs_256bits = ta_offs_256bits;
+
msg->l2h = msgb_put(msg, tch_len);
if (tch_len)
memcpy(msg->l2h, tch, tch_len);