diff options
author | Harald Welte <laforge@osmocom.org> | 2022-04-25 10:53:41 +0200 |
---|---|---|
committer | laforge <laforge@osmocom.org> | 2022-04-28 13:48:20 +0000 |
commit | 484f535c5091e3ca62547f8bbb6e06844c2ce8ae (patch) | |
tree | 7bc114a77812207bd181b113dbb0d42e491b58f3 /src/osmo-bsc/smscb.c | |
parent | 5e7458cbd8d38b3a2d8f3444c79aa03e82104ade (diff) |
smscb: Store ETWS input state from CBSP
Only if we store data like the CBSP message_id and serial_number
we are able to later (in a subsequent patch) match a CBSP KILL
for ETWS/PWS and stop emergency broadcast.
Change-Id: Ide74638880d7e3c6a7c774bf6320d3dce4b11c74
Related: OS#5540
Diffstat (limited to 'src/osmo-bsc/smscb.c')
-rw-r--r-- | src/osmo-bsc/smscb.c | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/src/osmo-bsc/smscb.c b/src/osmo-bsc/smscb.c index c89bedb4b..fc347eb85 100644 --- a/src/osmo-bsc/smscb.c +++ b/src/osmo-bsc/smscb.c @@ -59,8 +59,6 @@ static void llist_replace_head(struct llist_head *new, struct llist_head *old) INIT_LLIST_HEAD(old); } -#define ETWS_PRIM_NOTIF_SIZE 56 - /* Build a ETWS Primary Notification message as per TS 23.041 9.4.1.3 */ static int gen_etws_primary_notification(uint8_t *out, uint16_t serial_nr, uint16_t msg_id, uint16_t warn_type, const uint8_t *sec_info) @@ -471,24 +469,52 @@ static int tx_cbsp_keepalive_compl(struct bsc_cbc_link *cbc) * Per-BTS Processing of CBSP from CBC, called via cbsp_per_bts() *********************************************************************************/ +static void etws_pn_stop(struct gsm_bts *bts, bool timeout) +{ + if (osmo_bts_has_feature(&bts->features, BTS_FEAT_ETWS_PN)) { + LOG_BTS(bts, DCBS, LOGL_NOTICE, "ETWS PN broadcast via PCH disabled (cause=%s)\n", + timeout ? "timeout" : "request"); + rsl_etws_pn_command(bts, RSL_CHAN_PCH_AGCH, NULL, 0); + } + bts->etws.active = false; + if (!timeout) + osmo_timer_del(&bts->etws.timer); +} + /* timer call-back once ETWS warning period has expired */ static void etws_pn_cb(void *data) { struct gsm_bts *bts = (struct gsm_bts *)data; - LOG_BTS(bts, DCBS, LOGL_NOTICE, "ETWS PN Timeout; disabling broadcast via PCH\n"); - rsl_etws_pn_command(bts, RSL_CHAN_PCH_AGCH, NULL, 0); + etws_pn_stop(bts, true); } static void etws_primary_to_bts(struct gsm_bts *bts, const struct osmo_cbsp_write_replace *wrepl) { - uint8_t etws_primary[ETWS_PRIM_NOTIF_SIZE]; + struct bts_etws_state *bes = &bts->etws; struct gsm_bts_trx *trx; unsigned int count = 0; int i, j; - gen_etws_primary_notification(etws_primary, wrepl->new_serial_nr, wrepl->msg_id, - wrepl->u.emergency.warning_type, - wrepl->u.emergency.warning_sec_info); + if (bes->input.sec_info) { + talloc_free(bes->input.sec_info); + bes->input.sec_info = NULL; + } + + /* copy over all the data to per-BTS private state */ + bes->input.msg_id = wrepl->msg_id; + bes->input.serial_nr = wrepl->new_serial_nr; + bes->input.warn_type = wrepl->u.emergency.warning_type; + if (wrepl->u.emergency.warning_sec_info) { + bes->input.sec_info = talloc_named_const(bts, ETWS_SEC_INFO_SIZE, "etws_sec_info"); + if (bes->input.sec_info) + memcpy(bes->input.sec_info, wrepl->u.emergency.warning_sec_info, ETWS_SEC_INFO_SIZE); + } + + /* generate the encoded ETWS PN */ + gen_etws_primary_notification(bes->primary, bes->input.serial_nr, bes->input.msg_id, + bes->input.warn_type, bes->input.sec_info); + + 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) { @@ -498,8 +524,8 @@ static void etws_primary_to_bts(struct gsm_bts *bts, const struct osmo_cbsp_writ struct gsm_lchan *lchan = &ts->lchan[j]; if (!lchan_may_receive_data(lchan)) continue; - gsm48_send_rr_app_info(lchan, 0x1, 0x0, etws_primary, - sizeof(etws_primary)); + gsm48_send_rr_app_info(lchan, 0x1, 0x0, bes->primary, + sizeof(bes->primary)); count++; } } @@ -510,11 +536,10 @@ static void etws_primary_to_bts(struct gsm_bts *bts, const struct osmo_cbsp_writ /* 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, etws_primary, sizeof(etws_primary)); + 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"); if (wrepl->u.emergency.warning_period != 0xffffffff) { - osmo_timer_setup(&bts->etws_timer, etws_pn_cb, bts); - osmo_timer_schedule(&bts->etws_timer, wrepl->u.emergency.warning_period, 0); + osmo_timer_schedule(&bts->etws.timer, wrepl->u.emergency.warning_period, 0); } else LOG_BTS(bts, DCBS, LOGL_NOTICE, "Unlimited ETWS PN broadcast, this breaks " "normal network operation due to PCH blockage\n"); @@ -676,7 +701,7 @@ static int bts_rx_reset(struct gsm_bts *bts, const struct osmo_cbsp_decoded *dec llist_for_each_entry_safe(smscb, smscb2, &chan_state->messages, list) bts_smscb_del(smscb, chan_state, "RESET"); - osmo_timer_del(&bts->etws_timer); + osmo_timer_del(&bts->etws.timer); /* Make sure that broadcast is disabled */ rsl_etws_pn_command(bts, RSL_CHAN_PCH_AGCH, NULL, 0); @@ -991,3 +1016,11 @@ void smscb_vty_init(void) { install_element_ve(&bts_show_cbs_cmd); } + + +/* initialize the ETWS state of a BTS */ +void bts_etws_init(struct gsm_bts *bts) +{ + bts->etws.active = false; + osmo_timer_setup(&bts->etws.timer, etws_pn_cb, bts); +} |