aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmocom
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2019-06-13 09:41:58 +0200
committerHarald Welte <laforge@gnumonks.org>2019-09-02 12:06:25 +0200
commitd41b7c7f830e90c7c4ce1d8ed97f13cfd3ed8cad (patch)
tree7a8a53f81cd42f34c8c761ef5c8bbd7a05a9944c /include/osmocom
parent9508e2232f72a368ab87b5903e0764c4ae4985ad (diff)
Cell Broadcast: CBSP and CBCH scheduling support
This adds code to handle CBSP (Cell Broadcast Service Protocol) from the CBC (Cell Broadcast Centre), as well as BSC-internal data structures for scheduling the various SMSCB on the CBCH of each BTS. There are currently one known shortcoming in the code: We don't yet verify if keepalives are received within repetition period. Change-Id: Ia0a0de862a104d0f447a5d6e56c7c83981b825c7
Diffstat (limited to 'include/osmocom')
-rw-r--r--include/osmocom/bsc/Makefile.am1
-rw-r--r--include/osmocom/bsc/bsc_msc_data.h3
-rw-r--r--include/osmocom/bsc/debug.h1
-rw-r--r--include/osmocom/bsc/gsm_data.h53
-rw-r--r--include/osmocom/bsc/smscb.h59
-rw-r--r--include/osmocom/bsc/vty.h1
6 files changed, 118 insertions, 0 deletions
diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am
index f44e7fc86..396604eb1 100644
--- a/include/osmocom/bsc/Makefile.am
+++ b/include/osmocom/bsc/Makefile.am
@@ -55,4 +55,5 @@ noinst_HEADERS = \
gsm_08_08.h \
penalty_timers.h \
osmo_bsc_lcls.h \
+ smscb.h \
$(NULL)
diff --git a/include/osmocom/bsc/bsc_msc_data.h b/include/osmocom/bsc/bsc_msc_data.h
index 56124830c..b9df4ba8f 100644
--- a/include/osmocom/bsc/bsc_msc_data.h
+++ b/include/osmocom/bsc/bsc_msc_data.h
@@ -150,6 +150,7 @@ struct bsc_msc_data {
/*
* Per BSC data.
*/
+struct bsc_cbc_link;
struct osmo_bsc_data {
struct gsm_network *network;
@@ -167,6 +168,8 @@ struct osmo_bsc_data {
char *ussd_no_msc_txt;
char *acc_lst_name;
+
+ struct bsc_cbc_link *cbc;
};
diff --git a/include/osmocom/bsc/debug.h b/include/osmocom/bsc/debug.h
index 326012185..adc6abbe1 100644
--- a/include/osmocom/bsc/debug.h
+++ b/include/osmocom/bsc/debug.h
@@ -27,6 +27,7 @@ enum {
DCHAN,
DTS,
DAS,
+ DCBS,
Debug_LastEntry,
};
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index d82d1bac8..8dfbc6425 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -14,6 +14,7 @@
#include <osmocom/core/stat_item.h>
#include <osmocom/gsm/bts_features.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
+#include <osmocom/gsm/protocol/gsm_48_049.h>
#include <osmocom/gsm/gsm0808.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/core/fsm.h>
@@ -957,6 +958,53 @@ struct gsm_bts_ref {
struct gsm_bts *bts;
};
+/* A single Page of a SMSCB message */
+struct bts_smscb_page {
+ /* SMSCB message we're part of */
+ struct bts_smscb_message *msg;
+ /* Page Number within message (1 to 15) */
+ uint8_t nr;
+ /* number of valid blocks in data (up to 4) */
+ uint8_t num_blocks;
+ /* up to four blocks of 22 bytes each */
+ uint8_t data[88];
+};
+
+/* A SMSCB message (received from CBSP) */
+struct bts_smscb_message {
+ /* entry in bts_smscb_chan_state.messages */
+ struct llist_head list;
+ struct {
+ /* input data from CBSP (CBC) side */
+ uint16_t msg_id;
+ uint16_t serial_nr;
+ enum cbsp_category category;
+ uint16_t rep_period;
+ uint16_t num_bcast_req;
+ uint8_t dcs;
+ } input;
+ /* how often have all pages of this message been broadcast? */
+ uint32_t bcast_count;
+ /* actual page data of this message */
+ uint8_t num_pages; /* up to 15 */
+ struct bts_smscb_page page[15];
+};
+
+/* per-channel (basic/extended) CBCH state for a single BTS */
+struct bts_smscb_chan_state {
+ /* back-pointer to BTS */
+ struct gsm_bts *bts;
+ /* list of bts_smscb_message */
+ struct llist_head messages;
+ /* scheduling array; pointer of SMSCB pages */
+ struct bts_smscb_page **sched_arr;
+ size_t sched_arr_size;
+ /* index of the next to be transmitted page into the scheduler array */
+ size_t next_idx;
+ /* number of messages we have to pause due to overflow */
+ uint8_t overflow;
+};
+
/* One BTS */
struct gsm_bts {
/* list header in net->bts_list */
@@ -1213,6 +1261,11 @@ struct gsm_bts {
struct load_counter chan_load_samples[7];
int chan_load_samples_idx;
uint8_t chan_load_avg; /* current channel load average in percent (0 - 100). */
+
+ /* cell broadcast system */
+ struct osmo_timer_list cbch_timer;
+ struct bts_smscb_chan_state cbch_basic;
+ struct bts_smscb_chan_state cbch_extended;
};
/* One rejected BTS */
diff --git a/include/osmocom/bsc/smscb.h b/include/osmocom/bsc/smscb.h
new file mode 100644
index 000000000..22a258da9
--- /dev/null
+++ b/include/osmocom/bsc/smscb.h
@@ -0,0 +1,59 @@
+#pragma once
+#include <osmocom/bsc/gsm_data.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/netif/stream.h>
+#include <osmocom/gsm/cbsp.h>
+
+struct bsc_cbc_link;
+
+/* smscb.c */
+void bts_smscb_del(struct bts_smscb_message *smscb, struct bts_smscb_chan_state *cstate,
+ const char *reason);
+const char *bts_smscb_msg2str(const struct bts_smscb_message *smscb);
+struct bts_smscb_chan_state *bts_get_smscb_chan(struct gsm_bts *bts, bool extended);
+int cbsp_rx_decoded(struct bsc_cbc_link *cbc, const struct osmo_cbsp_decoded *dec);
+int cbsp_tx_restart(struct bsc_cbc_link *cbc, bool is_emerg);
+const char *bts_smscb_chan_state_name(const struct bts_smscb_chan_state *cstate);
+unsigned int bts_smscb_chan_load_percent(const struct bts_smscb_chan_state *cstate);
+unsigned int bts_smscb_chan_page_count(const struct bts_smscb_chan_state *cstate);
+void smscb_vty_init(void);
+
+/* cbch_scheduler.c */
+int bts_smscb_gen_sched_arr(struct bts_smscb_chan_state *cstate, struct bts_smscb_page ***arr_out);
+struct bts_smscb_page *bts_smscb_pull_page(struct bts_smscb_chan_state *cstate);
+void bts_smscb_page_done(struct bts_smscb_chan_state *cstate, struct bts_smscb_page *page);
+int bts_smscb_rx_cbch_load_ind(struct gsm_bts *bts, bool cbch_extended, bool is_overflow,
+ uint8_t slot_count);
+void bts_cbch_timer_schedule(struct gsm_bts *bts);
+
+/* cbsp_link.c */
+struct bsc_cbc_link {
+ struct gsm_network *net;
+ struct {
+ /* hostname/IP of CBC */
+ char *cbc_hostname;
+ /* TCP port (Default: 48049) of CBC */
+ int cbc_port;
+ /* local listening port (0 for disabling local server) */
+ int listen_port;
+ /* local listening hostname/IP */
+ char *listen_hostname;
+ } config;
+ /* for handling inbound TCP connections */
+ struct {
+ struct osmo_stream_srv *srv;
+ struct osmo_stream_srv_link *link;
+ char *sock_name;
+ struct msgb *msg;
+ } server;
+ /* for handling outbound TCP connections */
+ struct {
+ struct osmo_stream_cli *cli;
+ char *sock_name;
+ struct msgb *msg;
+ } client;
+};
+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);
diff --git a/include/osmocom/bsc/vty.h b/include/osmocom/bsc/vty.h
index 7e3c5053c..10ce16b2d 100644
--- a/include/osmocom/bsc/vty.h
+++ b/include/osmocom/bsc/vty.h
@@ -24,6 +24,7 @@ enum bsc_vty_node {
OM2K_NODE,
OM2K_CON_GROUP_NODE,
BSC_NODE,
+ CBC_NODE,
};
struct log_info;