aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2020-10-11 19:56:08 +0200
committerlaforge <laforge@osmocom.org>2020-10-15 11:29:29 +0000
commit9a7acc17448e7486e41292379359239c7f5c81fe (patch)
treeb435d075a65e410528b590a6882c904822271424
parent8d62d66ed5d52d7458b56db67d686defb183528e (diff)
sysinfo: Don't broadcast SI4 GPRS INDICATOR if PCU is disconnected
-rw-r--r--include/osmo-bts/bts.h8
-rw-r--r--src/common/pcu_sock.c4
-rw-r--r--src/common/rsl.c9
-rw-r--r--src/common/sysinfo.c45
4 files changed, 56 insertions, 10 deletions
diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h
index 4e496b59..9df7f087 100644
--- a/include/osmo-bts/bts.h
+++ b/include/osmo-bts/bts.h
@@ -158,10 +158,11 @@ struct gsm_bts {
/* offsets used while generating SI2quater */
size_t e_offset;
size_t u_offset;
- /* decoded SI3 rest octets - *unmodified* as received from BSC */
+ /* decoded SI rest octets - *unmodified* as received from BSC */
struct osmo_gsm48_si_ro_info si3_ro_decoded;
- /* is SI3 GPRS Indicator currently disabled due to lack of PCU connection? */
- bool si3_gprs_ind_disabled;
+ struct osmo_gsm48_si_ro_info si4_ro_decoded;
+ /* is SI GPRS Indicator currently disabled due to lack of PCU connection? */
+ bool si_gprs_ind_disabled;
/* ip.access Unit ID's have Site/BTS/TRX layout */
union {
@@ -338,6 +339,7 @@ int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt
int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher);
uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time);
void regenerate_si3_restoctets(struct gsm_bts *bts);
+void regenerate_si4_restoctets(struct gsm_bts *bts);
uint8_t *lchan_sacch_get(struct gsm_lchan *lchan);
int lchan_init_lapdm(struct gsm_lchan *lchan);
diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c
index ee5f4a6b..550dd37d 100644
--- a/src/common/pcu_sock.c
+++ b/src/common/pcu_sock.c
@@ -746,8 +746,9 @@ static int pcu_rx_txt_ind(struct gsm_bts *bts,
oml_tx_failure_event_rep(&bts->gprs.cell.mo, NM_SEVER_CEASED, OSMO_EVT_PCU_VERS, txt->text);
osmo_strlcpy(bts->pcu_version, txt->text, MAX_VERSION_LENGTH);
- /* patch SI3 to advertise GPRS, *if* the SI3 sent by BSC said so */
+ /* patch SI to advertise GPRS, *if* the SI sent by BSC said so */
regenerate_si3_restoctets(bts);
+ regenerate_si4_restoctets(bts);
if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_13))
return pcu_tx_si13(bts, true);
@@ -899,6 +900,7 @@ static void pcu_sock_close(struct pcu_sock_state *state)
/* patch SI3 to remove GPRS indicator */
regenerate_si3_restoctets(bts);
+ regenerate_si4_restoctets(bts);
/* re-enable the generation of ACCEPT for new connections */
state->listen_bfd.when |= OSMO_FD_READ;
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 919981dd..cb9c19b3 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -378,6 +378,15 @@ 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);
+ } else if (SYSINFO_TYPE_4 == osmo_si) {
+ /* decode original SI4 Rest Octets as sent by BSC */
+ const uint8_t *si4_ro_buf = (uint8_t *) GSM_BTS_SI(bts, osmo_si);
+ si4_ro_buf += offsetof(struct gsm48_system_information_type_4, data);
+ osmo_gsm48_rest_octets_si4_decode(&bts->si4_ro_decoded, si4_ro_buf,
+ GSM_MACBLOCK_LEN - offsetof(struct gsm48_system_information_type_4, data));
+ /* patch out GPRS indicator from binary if PCU is not connected; will be enabled
+ * after PCU connects */
+ regenerate_si4_restoctets(bts);
}
if (SYSINFO_TYPE_13 == osmo_si)
diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c
index d3efffcb..f3deb0dc 100644
--- a/src/common/sysinfo.c
+++ b/src/common/sysinfo.c
@@ -197,17 +197,50 @@ void regenerate_si3_restoctets(struct gsm_bts *bts)
/* Create a temporary copy and patch that, if no PCU is around */
si3ro_tmp = bts->si3_ro_decoded;
if (!pcu_connected()) {
- if (!bts->si3_gprs_ind_disabled)
- LOGP(DPCU, LOGL_NOTICE, "Disabling GPRS Indicator in SI3 (No PCU connected)\n");
- bts->si3_gprs_ind_disabled = true;
+ if (!bts->si_gprs_ind_disabled)
+ LOGP(DPCU, LOGL_NOTICE, "Disabling GPRS Indicator in SI (No PCU connected)\n");
+ bts->si_gprs_ind_disabled = true;
si3ro_tmp.gprs_ind.present = 0;
} else {
- if (bts->si3_gprs_ind_disabled)
- LOGP(DPCU, LOGL_NOTICE, "Enabling GPRS Indicator in SI3 (PCU connected)\n");
- bts->si3_gprs_ind_disabled = false;
+ if (bts->si_gprs_ind_disabled)
+ LOGP(DPCU, LOGL_NOTICE, "Enabling GPRS Indicator in SI (PCU connected)\n");
+ bts->si_gprs_ind_disabled = false;
si3ro_tmp.gprs_ind.present = 1; /* is a no-op as we copy from bts->si3_ro_decoded */
}
/* re-generate the binary SI3 rest octets */
osmo_gsm48_rest_octets_si3_encode(si3_buf + si3_size, &si3ro_tmp);
}
+
+/* re-generate SI4 restoctets with GPRS indicator depending on the PCU socket connection state */
+void regenerate_si4_restoctets(struct gsm_bts *bts)
+{
+ uint8_t *si4_buf = GSM_BTS_SI(bts, SYSINFO_TYPE_4);
+ size_t si4_size = offsetof(struct gsm48_system_information_type_4, data);
+ struct osmo_gsm48_si_ro_info si4ro_tmp;
+
+ /* If BSC has never set SI4, there's nothing to patch */
+ if (!GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_4))
+ return;
+
+ /* If SI4 from BSC doesn't have a GPRS indicator, we won't have anything to patch */
+ if (!bts->si4_ro_decoded.gprs_ind.present)
+ return;
+
+ /* Create a temporary copy and patch that, if no PCU is around */
+ si4ro_tmp = bts->si4_ro_decoded;
+ if (!pcu_connected()) {
+ if (!bts->si_gprs_ind_disabled)
+ LOGP(DPCU, LOGL_NOTICE, "Disabling GPRS Indicator in SI (No PCU connected)\n");
+ bts->si_gprs_ind_disabled = true;
+ si4ro_tmp.gprs_ind.present = 0;
+ } else {
+ if (bts->si_gprs_ind_disabled)
+ LOGP(DPCU, LOGL_NOTICE, "Enabling GPRS Indicator in SI (PCU connected)\n");
+ bts->si_gprs_ind_disabled = false;
+ si4ro_tmp.gprs_ind.present = 1; /* is a no-op as we copy from bts->si4_ro_decoded */
+ }
+
+ /* re-generate the binary SI4 rest octets */
+ osmo_gsm48_rest_octets_si4_encode(si4_buf + si4_size, &si4ro_tmp, GSM_MACBLOCK_LEN - si4_size);
+}