diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/pcu_sock.c | 67 | ||||
-rw-r--r-- | src/common/rsl.c | 24 |
2 files changed, 76 insertions, 15 deletions
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); |