smscb: Send ETWS PN to BTS if ETWS active before BTS connects
Especially during emergencies / natural disasters, it is particularly likely that networks become unreliable and BTSs disconnect and reconnect. If upon reconnect there still is an active ETWS/PWS emergency message active for this BTS, send it to the BTS to ensure it re-starts broadcasting that message until disabled. Change-Id: I175c33297c08e65bdbf38447e697e37f8a64d527
This commit is contained in:
parent
fa3e40e454
commit
d8017c3533
|
@ -66,3 +66,4 @@ int bsc_cbc_link_restart(void);
|
|||
int cbsp_tx_decoded(struct bsc_cbc_link *cbc, struct osmo_cbsp_decoded *decoded);
|
||||
|
||||
void bts_etws_init(struct gsm_bts *bts);
|
||||
void bts_etws_bootstrap(struct gsm_bts *bts);
|
||||
|
|
|
@ -363,6 +363,10 @@ static void bootstrap_rsl(struct gsm_bts_trx *trx)
|
|||
if (trx->nr == 0 && gsm_bts_get_cbch(trx->bts))
|
||||
bts_cbch_timer_schedule(trx->bts);
|
||||
|
||||
/* Start ETWS/PWS Primary Notification, if active */
|
||||
if (trx->nr == 0)
|
||||
bts_etws_bootstrap(trx->bts);
|
||||
|
||||
/* Drop all expired channel requests in the list */
|
||||
abis_rsl_chan_rqd_queue_flush(trx->bts);
|
||||
}
|
||||
|
|
|
@ -494,13 +494,45 @@ static void etws_pn_cb(void *data)
|
|||
etws_pn_stop(bts, true);
|
||||
}
|
||||
|
||||
static int etws_primary_to_bts(struct gsm_bts *bts, const struct osmo_cbsp_write_replace *wrepl)
|
||||
|
||||
/* the actual "execution" part: Send ETWS to all active lchan in the BTS and via PCH */
|
||||
static void bts_send_etws(struct gsm_bts *bts)
|
||||
{
|
||||
struct bts_etws_state *bes = &bts->etws;
|
||||
struct gsm_bts_trx *trx;
|
||||
unsigned int count = 0;
|
||||
int i, j;
|
||||
|
||||
/* iterate over all lchan in each TS in each TRX of this BTS */
|
||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||
for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
|
||||
struct gsm_bts_trx_ts *ts = &trx->ts[i];
|
||||
for (j = 0; j < ARRAY_SIZE(ts->lchan); j++) {
|
||||
struct gsm_lchan *lchan = &ts->lchan[j];
|
||||
if (!lchan_may_receive_data(lchan))
|
||||
continue;
|
||||
gsm48_send_rr_app_info(lchan, 0x1, 0x0, bes->primary,
|
||||
sizeof(bes->primary));
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_BTS(bts, DCBS, LOGL_NOTICE, "Sent ETWS Primary Notification via %u dedicated channels\n",
|
||||
count);
|
||||
|
||||
/* Notify BTS of primary ETWS notification via vendor-specific Abis message */
|
||||
if (osmo_bts_has_feature(&bts->features, BTS_FEAT_ETWS_PN)) {
|
||||
rsl_etws_pn_command(bts, RSL_CHAN_PCH_AGCH, bes->primary, sizeof(bes->primary));
|
||||
LOG_BTS(bts, DCBS, LOGL_NOTICE, "Sent ETWS Primary Notification via common channel\n");
|
||||
} else
|
||||
LOG_BTS(bts, DCBS, LOGL_ERROR, "BTS doesn't support RSL command for ETWS PN\n");
|
||||
}
|
||||
|
||||
static int etws_primary_to_bts(struct gsm_bts *bts, const struct osmo_cbsp_write_replace *wrepl)
|
||||
{
|
||||
struct bts_etws_state *bes = &bts->etws;
|
||||
|
||||
if (bes->active) {
|
||||
/* we were already broadcasting emergency before receiving this WRITE-REPLACE */
|
||||
|
||||
|
@ -546,30 +578,7 @@ static int etws_primary_to_bts(struct gsm_bts *bts, const struct osmo_cbsp_write
|
|||
|
||||
bes->active = true;
|
||||
|
||||
/* iterate over all lchan in each TS in each TRX of this BTS */
|
||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||
for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
|
||||
struct gsm_bts_trx_ts *ts = &trx->ts[i];
|
||||
for (j = 0; j < ARRAY_SIZE(ts->lchan); j++) {
|
||||
struct gsm_lchan *lchan = &ts->lchan[j];
|
||||
if (!lchan_may_receive_data(lchan))
|
||||
continue;
|
||||
gsm48_send_rr_app_info(lchan, 0x1, 0x0, bes->primary,
|
||||
sizeof(bes->primary));
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_BTS(bts, DCBS, LOGL_NOTICE, "Sent ETWS Primary Notification via %u dedicated channels\n",
|
||||
count);
|
||||
|
||||
/* Notify BTS of primary ETWS notification via vendor-specific Abis message */
|
||||
if (osmo_bts_has_feature(&bts->features, BTS_FEAT_ETWS_PN)) {
|
||||
rsl_etws_pn_command(bts, RSL_CHAN_PCH_AGCH, bes->primary, sizeof(bes->primary));
|
||||
LOG_BTS(bts, DCBS, LOGL_NOTICE, "Sent ETWS Primary Notification via common channel\n");
|
||||
} else
|
||||
LOG_BTS(bts, DCBS, LOGL_ERROR, "BTS doesn't support RSL command for ETWS PN\n");
|
||||
bts_send_etws(bts);
|
||||
|
||||
/* start the expiration timer, if any */
|
||||
if (wrepl->u.emergency.warning_period != 0xffffffff) {
|
||||
|
@ -1087,3 +1096,10 @@ void bts_etws_init(struct gsm_bts *bts)
|
|||
bts->etws.active = false;
|
||||
osmo_timer_setup(&bts->etws.timer, etws_pn_cb, bts);
|
||||
}
|
||||
|
||||
/* BSC is bootstrapping a BTS; install any currently active ETWS PN */
|
||||
void bts_etws_bootstrap(struct gsm_bts *bts)
|
||||
{
|
||||
if (bts->etws.active)
|
||||
bts_send_etws(bts);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue