aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bts.cpp10
-rw-r--r--src/bts.h6
-rw-r--r--src/pcu_l1_if.cpp8
-rw-r--r--src/pcu_l1_if.h34
-rw-r--r--src/sysmo_l1_if.c18
-rw-r--r--src/tbf.h4
-rw-r--r--src/tbf_ul.cpp5
7 files changed, 70 insertions, 15 deletions
diff --git a/src/bts.cpp b/src/bts.cpp
index 608bd0e9..f94799b6 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -657,7 +657,8 @@ void gprs_rlcmac_pdch::add_paging(struct gprs_rlcmac_paging *pag)
*
* The blocks are defragmented and forwarded as LLC frames, if complete.
*/
-int gprs_rlcmac_pdch::rcv_data_block_acknowledged(uint8_t *data, uint8_t len, int8_t rssi)
+int gprs_rlcmac_pdch::rcv_data_block_acknowledged(uint8_t *data, uint8_t len,
+ struct pcu_l1_meas *meas)
{
struct gprs_rlcmac_ul_tbf *tbf;
struct rlc_ul_header *rh = (struct rlc_ul_header *)data;
@@ -692,7 +693,7 @@ int gprs_rlcmac_pdch::rcv_data_block_acknowledged(uint8_t *data, uint8_t len, in
return 0;
}
- return tbf->rcv_data_block_acknowledged(data, len, rssi);
+ return tbf->rcv_data_block_acknowledged(data, len, meas);
}
void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, uint32_t fn)
@@ -995,7 +996,8 @@ int gprs_rlcmac_pdch::rcv_control_block(
/* received RLC/MAC block from L1 */
-int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn, int8_t rssi)
+int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn,
+ struct pcu_l1_meas *meas)
{
unsigned payload = data[0] >> 6;
bitvec *block;
@@ -1003,7 +1005,7 @@ int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn, int8_t
switch (payload) {
case GPRS_RLCMAC_DATA_BLOCK:
- rc = rcv_data_block_acknowledged(data, len, rssi);
+ rc = rcv_data_block_acknowledged(data, len, meas);
break;
case GPRS_RLCMAC_CONTROL_BLOCK:
block = bitvec_alloc(len);
diff --git a/src/bts.h b/src/bts.h
index e52875eb..8233b637 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -56,7 +56,8 @@ struct gprs_rlcmac_pdch {
void disable();
/* dispatching of messages */
- int rcv_block(uint8_t *data, uint8_t len, uint32_t fn, int8_t rssi);
+ int rcv_block(uint8_t *data, uint8_t len, uint32_t fn,
+ struct pcu_l1_meas *meas);
gprs_rlcmac_bts *bts_data() const;
BTS *bts() const;
@@ -80,7 +81,8 @@ struct gprs_rlcmac_pdch {
#ifdef __cplusplus
private:
- int rcv_data_block_acknowledged(uint8_t *data, uint8_t len, int8_t rssi);
+ int rcv_data_block_acknowledged(uint8_t *data, uint8_t len,
+ struct pcu_l1_meas *meas);
int rcv_control_block(bitvec *rlc_block, uint32_t fn);
void rcv_control_ack(Packet_Control_Acknowledgement_t *, uint32_t fn);
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index 0cb79eb6..9d7d9c48 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -181,17 +181,19 @@ void pcu_l1if_tx_pch(bitvec * block, int plen, const char *imsi)
}
extern "C" int pcu_rx_data_ind_pdtch(uint8_t trx_no, uint8_t ts_no, uint8_t *data,
- uint8_t len, uint32_t fn, int8_t rssi)
+ uint8_t len, uint32_t fn, struct pcu_l1_meas *meas)
{
struct gprs_rlcmac_pdch *pdch;
pdch = &bts_main_data()->trx[trx_no].pdch[ts_no];
- return pdch->rcv_block(data, len, fn, rssi);
+ return pdch->rcv_block(data, len, fn, meas);
}
static int pcu_rx_data_ind(struct gsm_pcu_if_data *data_ind)
{
int rc = 0;
+ pcu_l1_meas meas;
+ meas.set_rssi(data_ind->rssi);
LOGP(DL1IF, LOGL_DEBUG, "Data indication received: sapi=%d arfcn=%d "
"block=%d data=%s\n", data_ind->sapi,
@@ -202,7 +204,7 @@ static int pcu_rx_data_ind(struct gsm_pcu_if_data *data_ind)
case PCU_IF_SAPI_PDTCH:
rc = pcu_rx_data_ind_pdtch(data_ind->trx_nr, data_ind->ts_nr,
data_ind->data, data_ind->len, data_ind->fn,
- data_ind->rssi);
+ &meas);
break;
default:
LOGP(DL1IF, LOGL_ERROR, "Received PCU data indication with "
diff --git a/src/pcu_l1_if.h b/src/pcu_l1_if.h
index bd8fe940..88c83991 100644
--- a/src/pcu_l1_if.h
+++ b/src/pcu_l1_if.h
@@ -31,7 +31,39 @@ extern "C" {
#include <osmocom/gsm/gsm_utils.h>
#ifdef __cplusplus
}
+#endif
+
+/*
+ * L1 Measurement values
+ */
+
+struct pcu_l1_meas {
+ unsigned have_rssi:1;
+ unsigned have_ber:1;
+ unsigned have_bto:1;
+ unsigned have_link_qual:1;
+ int8_t rssi; /* RSSI in dBm */
+ uint8_t ber; /* Bit error rate in % */
+ int16_t bto; /* Burst timing offset in quarter bits */
+ int16_t link_qual; /* Link quality in db */
+#ifdef __cplusplus
+ pcu_l1_meas& set_rssi(int8_t v) { rssi = v; have_rssi = 1; return *this;}
+ pcu_l1_meas& set_ber(uint8_t v) { ber = v; have_ber = 1; return *this;}
+ pcu_l1_meas& set_bto(int16_t v) { bto = v; have_bto = 1; return *this;}
+ pcu_l1_meas& set_link_qual(int16_t v) {
+ link_qual = v; have_link_qual = 1; return *this;
+ }
+ pcu_l1_meas() :
+ have_rssi(0),
+ have_ber(0),
+ have_bto(0),
+ have_link_qual(0)
+ {}
+#endif
+};
+
+#ifdef __cplusplus
void pcu_l1if_tx_pdtch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn,
uint32_t fn, uint8_t block_nr);
void pcu_l1if_tx_ptcch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn,
@@ -57,6 +89,6 @@ int pcu_rx_rts_req_pdtch(uint8_t trx, uint8_t ts, uint16_t arfcn,
extern "C"
#endif
int pcu_rx_data_ind_pdtch(uint8_t trx, uint8_t ts, uint8_t *data,
- uint8_t len, uint32_t fn, int8_t rssi);
+ uint8_t len, uint32_t fn, struct pcu_l1_meas *meas);
#endif // PCU_L1_IF_H
diff --git a/src/sysmo_l1_if.c b/src/sysmo_l1_if.c
index 6e1e9e47..fc4b59b1 100644
--- a/src/sysmo_l1_if.c
+++ b/src/sysmo_l1_if.c
@@ -166,10 +166,23 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1h,
return rc;
}
+static void get_meas(struct pcu_l1_meas *meas, const GsmL1_MeasParam_t *l1_meas)
+{
+ meas->rssi = (int8_t) (l1_meas->fRssi);
+ meas->have_rssi = 1;
+ meas->ber = (uint8_t) (l1_meas->fBer * 100);
+ meas->have_ber = 1;
+ meas->bto = (int16_t) (l1_meas->i16BurstTiming);
+ meas->have_bto = 1;
+ meas->link_qual = (int16_t) (l1_meas->fLinkQuality);
+ meas->have_link_qual = 1;
+}
+
static int handle_ph_data_ind(struct femtol1_hdl *fl1h,
GsmL1_PhDataInd_t *data_ind, struct msgb *l1p_msg)
{
int rc = 0;
+ struct pcu_l1_meas meas = {0};
DEBUGP(DL1IF, "Rx PH-DATA.ind %s (hL2 %08x): %s\n",
get_value_string(femtobts_l1sapi_names, data_ind->sapi),
@@ -190,8 +203,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1h,
data_ind->u32Fn, 0, 0, data_ind->msgUnitParam.u8Buffer+1,
data_ind->msgUnitParam.u8Size-1);
-
-
+ get_meas(&meas, &data_ind->measParam);
switch (data_ind->sapi) {
case GsmL1_Sapi_Pdtch:
@@ -205,7 +217,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1h,
data_ind->msgUnitParam.u8Buffer + 1,
data_ind->msgUnitParam.u8Size - 1,
data_ind->u32Fn,
- (int8_t) (data_ind->measParam.fRssi));
+ &meas);
break;
case GsmL1_Sapi_Ptcch:
// FIXME
diff --git a/src/tbf.h b/src/tbf.h
index 8e4c3b98..c74fcc36 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -30,6 +30,7 @@
struct bssgp_bvc_ctx;
struct rlc_ul_header;
struct msgb;
+struct pcu_l1_meas;
class GprsMs;
/*
@@ -372,7 +373,8 @@ struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {
struct msgb *create_ul_ack(uint32_t fn);
/* blocks were acked */
- int rcv_data_block_acknowledged(const uint8_t *data, size_t len, int8_t rssi);
+ int rcv_data_block_acknowledged(const uint8_t *data, size_t len,
+ struct pcu_l1_meas *meas);
/* TODO: extract LLC class? */
int assemble_forward_llc(const gprs_rlc_data *data);
diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp
index 3ab71f05..b9ea6599 100644
--- a/src/tbf_ul.cpp
+++ b/src/tbf_ul.cpp
@@ -27,6 +27,7 @@
#include <gprs_debug.h>
#include <gprs_bssgp_pcu.h>
#include <decoding.h>
+#include <pcu_l1_if.h>
extern "C" {
#include <osmocom/core/msgb.h>
@@ -261,10 +262,12 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn)
return msg;
}
-int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t len, int8_t rssi)
+int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(const uint8_t *data,
+ size_t len, struct pcu_l1_meas *meas)
{
struct rlc_ul_header *rh = (struct rlc_ul_header *)data;
int rc;
+ int8_t rssi = meas->have_rssi ? meas->rssi : 0;
const uint16_t mod_sns = m_window.mod_sns();
const uint16_t ws = m_window.ws();