diff options
-rw-r--r-- | include/osmocom/bsc/abis_rsl.h | 1 | ||||
-rw-r--r-- | include/osmocom/bsc/gsm_data.h | 1 | ||||
-rw-r--r-- | src/osmo-bsc/abis_rsl.c | 19 | ||||
-rw-r--r-- | src/osmo-bsc/smscb.c | 29 |
4 files changed, 44 insertions, 6 deletions
diff --git a/include/osmocom/bsc/abis_rsl.h b/include/osmocom/bsc/abis_rsl.h index ec630909c..4ccfd148e 100644 --- a/include/osmocom/bsc/abis_rsl.h +++ b/include/osmocom/bsc/abis_rsl.h @@ -91,6 +91,7 @@ int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm); int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number, struct rsl_ie_cb_cmd_type cb_command, bool use_extended_cbch, const uint8_t *data, int len); +int rsl_etws_pn_command(struct gsm_bts *bts, uint8_t chan_nr, const uint8_t *data, int len); /* some Nokia specific stuff */ int rsl_nokia_si_begin(struct gsm_bts_trx *trx); diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h index 8dfbc6425..f6d6d5e92 100644 --- a/include/osmocom/bsc/gsm_data.h +++ b/include/osmocom/bsc/gsm_data.h @@ -1266,6 +1266,7 @@ struct gsm_bts { 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 */ }; /* One rejected BTS */ diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c index 06d19a5d5..4a7d104e8 100644 --- a/src/osmo-bsc/abis_rsl.c +++ b/src/osmo-bsc/abis_rsl.c @@ -2203,6 +2203,25 @@ int abis_rsl_rcvmsg(struct msgb *msg) return rc; } +/* Send an Osmocom-specific Abis RSL message for ETWS Primary Notification */ +int rsl_etws_pn_command(struct gsm_bts *bts, uint8_t chan_nr, const uint8_t *data, int len) +{ + struct abis_rsl_dchan_hdr *dh; + struct msgb *msg = rsl_msgb_alloc(); + if (!msg) + return -1; + dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh)); + init_dchan_hdr(dh, RSL_MT_OSMO_ETWS_CMD); + dh->c.msg_discr = ABIS_RSL_MDISC_COM_CHAN; + dh->chan_nr = chan_nr; + + msgb_tlv_put(msg, RSL_IE_SMSCB_MSG, len, data); + + msg->dst = bts->c0->rsl_link; + + return abis_rsl_sendmsg(msg); +} + int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number, struct rsl_ie_cb_cmd_type cb_command, bool use_extended_cbch, const uint8_t *data, int len) diff --git a/src/osmo-bsc/smscb.c b/src/osmo-bsc/smscb.c index 319ef21a7..8d48af9fe 100644 --- a/src/osmo-bsc/smscb.c +++ b/src/osmo-bsc/smscb.c @@ -40,6 +40,7 @@ #include <osmocom/bsc/vty.h> #include <osmocom/bsc/gsm_04_08_rr.h> #include <osmocom/bsc/lchan_fsm.h> +#include <osmocom/bsc/abis_rsl.h> /********************************************************************************* * Helper Functions @@ -461,8 +462,15 @@ 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_primary_to_dedicated(struct gsm_bts *bts, - const struct osmo_cbsp_write_replace *wrepl) +/* 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); +} + +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 gsm_bts_trx *trx; @@ -491,7 +499,18 @@ static void etws_primary_to_dedicated(struct gsm_bts *bts, LOG_BTS(bts, DCBS, LOGL_NOTICE, "Sent ETWS Primary Notification via %u dedicated channels\n", count); - /* FIXME: Notify BTS of primary ETWS notification via vendor-specific Abis message */ + /* 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)); + 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); + } else + LOG_BTS(bts, DCBS, LOGL_NOTICE, "Unlimited ETWS PN broadcast, this breaks " + "normal network operation due to PCH blockage\n"); + } else + LOG_BTS(bts, DCBS, LOGL_ERROR, "BTS doesn't support RSL command for ETWS PN\n"); } /*! Try to execute a write-replace operation; roll-back if it fails. @@ -563,9 +582,7 @@ static int bts_rx_write_replace(struct gsm_bts *bts, const struct osmo_cbsp_deco int rc; if (!wrepl->is_cbs) { - /* send through any active dedicated channels of this BTS */ - etws_primary_to_dedicated(bts, wrepl); - /* TODO: send via RSL to BTS for transmission on PCH */ + etws_primary_to_bts(bts, wrepl); return 0; } |