sysinfo: Don't broadcast SI4 GPRS INDICATOR if PCU is disconnected

Depends: libosmocore.git I9d6ed06731ae15fdcef1a1f397d6ac2b7b1ca980
Change-Id: I1fd513ea03297918d15d4b28ed454f9b6dd6ebfa
Related: OS#3075
This commit is contained in:
Harald Welte 2020-10-11 19:56:08 +02:00 committed by laforge
parent 8d62d66ed5
commit 9a7acc1744
4 changed files with 56 additions and 10 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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);
}