aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmo-bts/gsm_data_shared.h1
-rw-r--r--src/common/cbch.c50
2 files changed, 38 insertions, 13 deletions
diff --git a/include/osmo-bts/gsm_data_shared.h b/include/osmo-bts/gsm_data_shared.h
index 72d97105..6974e622 100644
--- a/include/osmo-bts/gsm_data_shared.h
+++ b/include/osmo-bts/gsm_data_shared.h
@@ -737,6 +737,7 @@ struct gsm_bts {
struct {
struct llist_head queue; /* list of struct smscb_msg */
struct smscb_msg *cur_msg; /* current SMS-CB */
+ struct smscb_msg *default_msg; /* default broadcast message; NULL if none */
} smscb_state;
float min_qual_rach; /* minimum quality for RACH bursts */
diff --git a/src/common/cbch.c b/src/common/cbch.c
index 817489f2..185386ab 100644
--- a/src/common/cbch.c
+++ b/src/common/cbch.c
@@ -101,9 +101,14 @@ static int get_smscb_block(struct gsm_bts *bts, uint8_t *out, uint8_t block_nr,
block_type->lb = 0;
if (block_nr == 4) {
- /* delete any fully-transmitted normal message (or superseded default) */
- talloc_free(bts->smscb_state.cur_msg);
- bts->smscb_state.cur_msg = NULL;
+ if (msg != bts->smscb_state.default_msg) {
+ DEBUGPGT(DLSMS, g_time, "deleting fully-transmitted message %p\n", msg);
+ /* delete any fully-transmitted normal message (or superseded default) */
+ talloc_free(bts->smscb_state.cur_msg);
+ bts->smscb_state.cur_msg = NULL;
+ } else {
+ DEBUGPGT(DLSMS, g_time, "keeping fully-transmitted default message %p\n", msg);
+ }
}
return block_type->lb;
@@ -160,16 +165,25 @@ int bts_process_smscb_cmd(struct gsm_bts *bts,
case RSL_CB_CMD_TYPE_SCHEDULE:
case RSL_CB_CMD_TYPE_NULL:
/* def_bcast is ignored as per Section 9.3.41 of 3GPP TS 48.058 */
+ llist_add_tail(&scm->list, &bts->smscb_state.queue);
+ /* FIXME: limit queue size and optionally send CBCH LOAD Information (overflow) via RSL */
break;
case RSL_CB_CMD_TYPE_DEFAULT:
- /* use def_bcast, ignore command */
- /* def_bcast == 0: normal mess */
+ /* old default msg will be free'd in get_smscb_block() if it is currently in transit
+ * and we set a new default_msg here */
+ if (bts->smscb_state.cur_msg && bts->smscb_state.cur_msg == bts->smscb_state.default_msg)
+ talloc_free(bts->smscb_state.cur_msg);
+ if (cmd_type.def_bcast == RSL_CB_CMD_DEFBCAST_NORMAL)
+ /* def_bcast == 0: normal message */
+ bts->smscb_state.default_msg = scm;
+ else {
+ /* def_bcast == 1: NULL message */
+ bts->smscb_state.default_msg = NULL;
+ talloc_free(scm);
+ }
break;
}
- llist_add_tail(&scm->list, &bts->smscb_state.queue);
- /* FIXME: limit queue size and optionally send CBCH LOAD Information (overflow) via RSL */
-
return 0;
}
@@ -178,13 +192,23 @@ static struct smscb_msg *select_next_smscb(struct gsm_bts *bts)
struct smscb_msg *msg;
msg = llist_first_entry_or_null(&bts->smscb_state.queue, struct smscb_msg, list);
- if (!msg) {
- /* FIXME: send CBCH LOAD Information (underflow) via RSL */
- return NULL;
+ if (msg) {
+ llist_del(&msg->list);
+ DEBUGP(DLSMS, "%s: Dequeued msg\n", __func__);
+ return msg;
+ }
+
+ /* FIXME: send CBCH LOAD Information (underflow) via RSL */
+
+ /* choose the default message, if any */
+ msg = bts->smscb_state.default_msg;
+ if (msg) {
+ DEBUGP(DLSMS, "%s: Using default msg\n", __func__);
+ return msg;
}
- llist_del(&msg->list);
- return msg;
+ DEBUGP(DLSMS, "%s: No queued msg nor default\n", __func__);
+ return NULL;
}
/* call-back from bts model specific code when it wants to obtain a CBCH