diff options
author | Harald Welte <laforge@osmocom.org> | 2022-04-25 11:10:30 +0200 |
---|---|---|
committer | laforge <laforge@osmocom.org> | 2022-04-28 13:48:20 +0000 |
commit | 7a982712ac258c9b0b1df64fba181a7beaefa5f2 (patch) | |
tree | 4d787d170478a8d097dcdbc22e9f3ecf1b46c8cd /src/osmo-bsc/smscb.c | |
parent | bcd0f63dce341878bc3e4e67dd2cb29507ba1f39 (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
Diffstat (limited to 'src/osmo-bsc/smscb.c')
-rw-r--r-- | src/osmo-bsc/smscb.c | 62 |
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(¢->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; } |