aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2021-01-29 20:11:53 +0100
committerlaforge <laforge@osmocom.org>2021-02-03 08:26:25 +0000
commit98c7b44f8da542b84d018d9c14ff8b8e7b9370e8 (patch)
tree5b7382c1c393094713f5872c220719d12392c6a7
parent23ff5f886103a68bb64c13c1c6c87382df575882 (diff)
pcu_sock: send SI1, SI3 and SI13 via PCUIF
This patch PCUIF extends the SAPI 4 that is used to transfer SI13 only, so that it can transfer SI1 and SI3 as well. The system information SI1, SI3 and SI13 is needed by the NACC RIM application which runs inside osmo-pcu. Depends: osmo-pcu I5138ab183793e7eee4dc494318d984e9f1f56932 Change-Id: Ib7aeb41e634ad6fcab3766a4667b0267c749436a Related: SYS#5103
-rw-r--r--include/osmo-bts/pcu_if.h2
-rw-r--r--src/common/pcu_sock.c67
-rw-r--r--src/common/rsl.c24
3 files changed, 77 insertions, 16 deletions
diff --git a/include/osmo-bts/pcu_if.h b/include/osmo-bts/pcu_if.h
index 1475a944..add37f85 100644
--- a/include/osmo-bts/pcu_if.h
+++ b/include/osmo-bts/pcu_if.h
@@ -4,7 +4,7 @@
extern int pcu_direct;
int pcu_tx_info_ind(void);
-int pcu_tx_si13(const struct gsm_bts *bts, bool enable);
+int pcu_tx_si(const struct gsm_bts *bts, enum osmo_sysinfo_type si_type, bool enable);
int pcu_tx_app_info_req(struct gsm_bts *bts, uint8_t app_type, uint8_t len, const uint8_t *app_data);
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);
diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c
index 0466698d..ffa8e77b 100644
--- a/src/common/pcu_sock.c
+++ b/src/common/pcu_sock.c
@@ -725,17 +725,64 @@ static int pcu_rx_pag_req(struct gsm_bts *bts, uint8_t msg_type,
return rc;
}
-int pcu_tx_si13(const struct gsm_bts *bts, bool enable)
+int pcu_tx_si(const struct gsm_bts *bts, enum osmo_sysinfo_type si_type,
+ bool enable)
{
/* the SI is per-BTS so it doesn't matter which TRX we use */
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, 0);
- /* The low-level data like FN, ARFCN etc will be ignored but we have to set lqual high enough to bypass
- the check at lower levels */
- int rc = pcu_tx_data_ind(&trx->ts[0], PCU_IF_SAPI_BCCH, 0, 0, 0, GSM_BTS_SI(bts, SYSINFO_TYPE_13),
- enable ? GSM_MACBLOCK_LEN : 0, 0, 0, 0, INT16_MAX);
+ uint8_t si_buf[GSM_MACBLOCK_LEN];
+ uint8_t len;
+ int rc;
+
+ if (enable) {
+ memcpy(si_buf, GSM_BTS_SI(bts, si_type), GSM_MACBLOCK_LEN);
+ len = GSM_MACBLOCK_LEN;
+ LOGP(DPCU, LOGL_DEBUG, "Updating SI%s to PCU: %s\n",
+ get_value_string(osmo_sitype_strs, si_type),
+ osmo_hexdump_nospc(si_buf, GSM_MACBLOCK_LEN));
+ } else {
+ si_buf[0] = si_type;
+ len = 1;
+
+ /* Note: SI13 is the only system information type that is revked
+ * by just sending a completely empty message. This is due to
+ * historical reasons */
+ if (si_type != SYSINFO_TYPE_13)
+ len = 0;
+
+ LOGP(DPCU, LOGL_DEBUG, "Revoking SI%s from PCU\n",
+ get_value_string(osmo_sitype_strs, si_buf[0]));
+ }
+
+ /* The low-level data like FN, ARFCN etc will be ignored but we have to
+ * set lqual high enough to bypass the check at lower levels */
+ rc = pcu_tx_data_ind(&trx->ts[0], PCU_IF_SAPI_BCCH, 0, 0, 0, si_buf, len,
+ 0, 0, 0, INT16_MAX);
if (rc < 0)
- LOGP(DPCU, LOGL_NOTICE, "Failed to send SI13 to PCU: %d\n", rc);
+ LOGP(DPCU, LOGL_NOTICE, "Failed to send SI%s to PCU: rc=%d\n",
+ get_value_string(osmo_sitype_strs, si_type), rc);
+
+ return rc;
+}
+
+static int pcu_tx_si_all(struct gsm_bts *bts)
+{
+ enum osmo_sysinfo_type si_types[3] =
+ { SYSINFO_TYPE_1, SYSINFO_TYPE_3, SYSINFO_TYPE_13 };
+ unsigned int i;
+ int rc;
+
+ for (i = 0; i < ARRAY_SIZE(si_types); i++) {
+ if (GSM_BTS_HAS_SI(bts, si_types[i])) {
+ rc = pcu_tx_si(bts, si_types[i], true);
+ if (rc < 0)
+ rc = -EINVAL;
+ } else
+ LOGP(DPCU, LOGL_INFO,
+ "SI%s is not available on PCU connection\n",
+ get_value_string(osmo_sitype_strs, si_types[i]));
+ }
return rc;
}
@@ -743,6 +790,8 @@ int pcu_tx_si13(const struct gsm_bts *bts, bool enable)
static int pcu_rx_txt_ind(struct gsm_bts *bts,
struct gsm_pcu_if_txt_ind *txt)
{
+ int rc;
+
switch (txt->type) {
case PCU_VERSION:
LOGP(DPCU, LOGL_INFO, "OsmoPCU version %s connected\n",
@@ -754,10 +803,10 @@ static int pcu_rx_txt_ind(struct gsm_bts *bts,
regenerate_si3_restoctets(bts);
regenerate_si4_restoctets(bts);
- if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_13))
- return pcu_tx_si13(bts, true);
+ rc = pcu_tx_si_all(bts);
+ if (rc < 0)
+ return -EINVAL;
- LOGP(DPCU, LOGL_INFO, "SI13 is not available on PCU connection\n");
break;
case PCU_OML_ALERT:
oml_tx_failure_event_rep(&bts->gprs.cell.mo, NM_SEVER_INDETERMINATE, OSMO_EVT_EXT_ALARM,
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 01a0ab48..bde53a18 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -379,6 +379,7 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg)
/* patch out GPRS indicator from binary if PCU is not connected; will be enabled
* after PCU connects */
regenerate_si3_restoctets(bts);
+ pcu_tx_si(trx->bts, SYSINFO_TYPE_3, true);
} else if (SYSINFO_TYPE_4 == osmo_si) {
/* decode original SI4 Rest Octets as sent by BSC */
const uint8_t *si4 = (uint8_t *) GSM_BTS_SI(bts, osmo_si);
@@ -391,11 +392,12 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg)
* enabled after PCU connects */
regenerate_si4_restoctets(bts);
}
+ } else if (SYSINFO_TYPE_13 == osmo_si) {
+ pcu_tx_si(trx->bts, SYSINFO_TYPE_13, true);
+ } else if (SYSINFO_TYPE_1 == osmo_si) {
+ pcu_tx_si(trx->bts, SYSINFO_TYPE_1, true);
}
- if (SYSINFO_TYPE_13 == osmo_si)
- pcu_tx_si13(trx->bts, true);
-
} else if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) {
uint16_t len = TLVP_LEN(&tp, RSL_IE_L3_INFO);
if (len > sizeof(sysinfo_buf_t))
@@ -410,10 +412,20 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg)
bts->si_valid &= ~(1 << osmo_si);
LOGP(DRSL, LOGL_INFO, " RX RSL Disabling BCCH INFO (SI%s)\n",
get_value_string(osmo_sitype_strs, osmo_si));
- if (SYSINFO_TYPE_13 == osmo_si)
- pcu_tx_si13(trx->bts, false);
- if (SYSINFO_TYPE_3 == osmo_si)
+ switch (osmo_si) {
+ case SYSINFO_TYPE_13:
+ pcu_tx_si(trx->bts, SYSINFO_TYPE_13, false);
+ break;
+ case SYSINFO_TYPE_3:
memset(&bts->si3_ro_decoded, 0, sizeof(bts->si3_ro_decoded));
+ pcu_tx_si(trx->bts, SYSINFO_TYPE_3, false);
+ break;
+ case SYSINFO_TYPE_1:
+ pcu_tx_si(trx->bts, SYSINFO_TYPE_1, false);
+ break;
+ default:
+ break;
+ }
}
osmo_signal_dispatch(SS_GLOBAL, S_NEW_SYSINFO, bts);