aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2022-04-25 11:10:30 +0200
committerHarald Welte <laforge@osmocom.org>2022-05-03 14:05:08 +0200
commitcab2fb2a28efa99556a4c3a10e1fc0157475d249 (patch)
tree9c06f99e4ab94e5be4f50c3dea3ca616a776ac44
parentac123fd58e9c42ec53b439f1b887cb2b5f08a91a (diff)
cbsp: Implement KILL for Emergency Broadcast
So far, we only implemented KILL for CBS, but not for Emergency broadcasts. This patch adds KILL support for Emergency, by which a CBC can terminate broadcast of a previously-started Emergency message before its scheduled period ends. Change-Id: Ie91939b93de6847eeb5d00c97a137c43721c2711 Closes: OS#5540 Related: SYS#5906 (cherry picked from commit 7a982712ac258c9b0b1df64fba181a7beaefa5f2)
-rw-r--r--src/osmo-bsc/smscb.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/src/osmo-bsc/smscb.c b/src/osmo-bsc/smscb.c
index 208c20353..8ec239a99 100644
--- a/src/osmo-bsc/smscb.c
+++ b/src/osmo-bsc/smscb.c
@@ -243,6 +243,12 @@ static void append_bcast_compl(struct response_state *r_state, struct gsm_bts *b
llist_add_tail(&cent->list, &r_state->num_completed.list);
}
+static bool etws_msg_id_matches(uint16_t a, uint16_t b)
+{
+ /* ETWS messages are identified by the twelve most significant bits of the Message ID */
+ return (a & 0xFFF0) == (b & 0xFFF0);
+}
+
/*! Iterate over all BTSs, find matching ones, execute command on BTS, add result
* to succeeded/failed lists.
* \param[in] net GSM network in which we operate
@@ -665,23 +671,53 @@ static int bts_rx_kill(struct gsm_bts *bts, const struct osmo_cbsp_decoded *dec,
struct response_state *r_state, void *priv)
{
const struct osmo_cbsp_kill *kill = &dec->u.kill;
- struct bts_smscb_chan_state *chan_state;
- struct bts_smscb_message *smscb;
- bool extended = false;
- if (kill->channel_ind && *kill->channel_ind == 0x01)
- extended = true;
- chan_state = bts_get_smscb_chan(bts, extended);
+ if (kill->channel_ind) {
+ /* KILL for CBS message */
+ struct bts_smscb_chan_state *chan_state;
+ struct bts_smscb_message *smscb;
+ bool extended = false;
- /* Find message by msg_id + old_serial_nr */
- smscb = bts_find_smscb(chan_state, kill->msg_id, kill->old_serial_nr);
- if (!smscb)
- return -CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED;
+ if (*kill->channel_ind == 0x01)
+ extended = true;
- append_bcast_compl(r_state, chan_state->bts, smscb);
+ chan_state = bts_get_smscb_chan(bts, extended);
+
+ /* Find message by msg_id + old_serial_nr */
+ smscb = bts_find_smscb(chan_state, kill->msg_id, kill->old_serial_nr);
+ if (!smscb)
+ return -CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED;
+
+ append_bcast_compl(r_state, chan_state->bts, smscb);
+
+ /* Remove it */
+ bts_smscb_del(smscb, chan_state, "KILL");
+ } else {
+ /* KILL for Emergency */
+ struct bts_etws_state *bes = &bts->etws;
+
+ if (!bes->active) {
+ LOG_BTS(bts, DCBS, LOGL_NOTICE, "Rx CBSP KILL (Emerg) but no emergency "
+ "broadcast is currently active in this cell\n");
+ return -CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED;
+ }
- /* Remove it */
- bts_smscb_del(smscb, chan_state, "KILL");
+ if (kill->msg_id != bes->input.msg_id) {
+ LOG_BTS(bts, DCBS, LOGL_NOTICE, "Rx CBSP KILL (Emerg) for msg_id 0x%04x, but "
+ "current emergency msg_id is 0x%04x\n", kill->msg_id, bes->input.msg_id);
+ return -CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED;
+ }
+
+ if (!etws_msg_id_matches(kill->old_serial_nr, bes->input.serial_nr)) {
+ LOG_BTS(bts, DCBS, LOGL_NOTICE, "Rx CBSP KILL (Emerg) for old_serial_nr 0x%04x, but "
+ "current emergency serial_nr is 0x%04x\n",
+ kill->old_serial_nr, bes->input.serial_nr);
+ return -CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED;
+ }
+
+ /* stop broadcasting the PN in this BTS */
+ etws_pn_stop(bts, false);
+ }
return 0;
}