laforge has submitted this change. (
https://gerrit.osmocom.org/c/osmo-bsc/+/27960 )
Change subject: smscb: Store ETWS input state from CBSP
......................................................................
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
---
M include/osmocom/bsc/bts.h
M include/osmocom/bsc/gsm_data.h
M include/osmocom/bsc/smscb.h
M src/osmo-bsc/bts.c
M src/osmo-bsc/smscb.c
5 files changed, 73 insertions(+), 15 deletions(-)
Approvals:
laforge: Looks good to me, approved
pespin: Looks good to me, but someone else must approve
Jenkins Builder: Verified
diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h
index 151fd78..7d51707 100644
--- a/include/osmocom/bsc/bts.h
+++ b/include/osmocom/bsc/bts.h
@@ -589,7 +589,7 @@
struct osmo_timer_list cbch_timer;
struct bts_smscb_chan_state cbch_basic;
struct bts_smscb_chan_state cbch_extended;
- struct osmo_timer_list etws_timer; /* when to stop ETWS PN */
+ struct bts_etws_state etws;
struct llist_head oml_fail_rep;
struct llist_head chan_rqd_queue;
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index b478ba0..cb20b9e 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -1086,6 +1086,27 @@
uint8_t overflow;
};
+#define ETWS_PRIM_NOTIF_SIZE 56
+#define ETWS_SEC_INFO_SIZE (ETWS_PRIM_NOTIF_SIZE - sizeof(struct gsm341_etws_message))
+
+/* per-BTS ETWS/PWS (Emergency) state */
+struct bts_etws_state {
+ /* are we actively broadcasting emergency in this cell? */
+ bool active;
+ /* input parameters received from CBC */
+ struct {
+ uint16_t msg_id;
+ uint16_t serial_nr;
+ uint16_t warn_type;
+ uint8_t *sec_info;
+ } input;
+ /* encoded ETWS primary notification */
+ uint8_t primary[ETWS_PRIM_NOTIF_SIZE];
+
+ /* timer running for the duration of the ETWS Primary Notification (PN) */
+ struct osmo_timer_list timer;
+};
+
struct bts_oml_fail_rep {
struct llist_head list;
time_t time;
diff --git a/include/osmocom/bsc/smscb.h b/include/osmocom/bsc/smscb.h
index f48c1a1..5b0905b 100644
--- a/include/osmocom/bsc/smscb.h
+++ b/include/osmocom/bsc/smscb.h
@@ -64,3 +64,5 @@
void cbc_vty_init(void);
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);
diff --git a/src/osmo-bsc/bts.c b/src/osmo-bsc/bts.c
index a403c82..4066cf1 100644
--- a/src/osmo-bsc/bts.c
+++ b/src/osmo-bsc/bts.c
@@ -25,6 +25,7 @@
#include <osmocom/bsc/debug.h>
#include <osmocom/bsc/nm_common_fsm.h>
#include <osmocom/bsc/paging.h>
+#include <osmocom/bsc/smscb.h>
const struct value_string bts_attribute_names[] = {
OSMO_VALUE_STRING(BTS_TYPE_VARIANT),
@@ -427,6 +428,7 @@
bts_init_cbch_state(&bts->cbch_basic, bts);
bts_init_cbch_state(&bts->cbch_extended, bts);
+ bts_etws_init(bts);
acc_mgr_init(&bts->acc_mgr, bts);
acc_ramp_init(&bts->acc_ramp, bts);
diff --git a/src/osmo-bsc/smscb.c b/src/osmo-bsc/smscb.c
index c89bedb..fc347eb 100644
--- a/src/osmo-bsc/smscb.c
+++ b/src/osmo-bsc/smscb.c
@@ -59,8 +59,6 @@
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 @@
* 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 @@
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 @@
/* 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 @@
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 @@
{
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);
+}
--
To view, visit
https://gerrit.osmocom.org/c/osmo-bsc/+/27960
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: Ide74638880d7e3c6a7c774bf6320d3dce4b11c74
Gerrit-Change-Number: 27960
Gerrit-PatchSet: 3
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-MessageType: merged