Change in osmo-bts[master]: cbch: Support Extended CBCH

Harald Welte gerrit-no-reply at lists.osmocom.org
Tue May 21 18:14:21 UTC 2019


Harald Welte has submitted this change and it was merged. ( https://gerrit.osmocom.org/14109 )

Change subject: cbch: Support Extended CBCH
......................................................................

cbch: Support Extended CBCH

The logic for Extended CBCH are the same as for the Basic CBCH, we just
need to
* duplicate our related state
* parse the optional RSL_IE_SMSCB_CHAN_INDICATOR IE
* start to send data on the Extended CBCH (TB=4..7)

Change-Id: If2c6dc7da1e2185ab75fc957f8d305ad8db22429
Closes: OS#3535
---
M include/osmo-bts/cbch.h
M include/osmo-bts/gsm_data_shared.h
M src/common/bts.c
M src/common/cbch.c
M src/common/rsl.c
M src/common/vty.c
6 files changed, 69 insertions(+), 37 deletions(-)

Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved



diff --git a/include/osmo-bts/cbch.h b/include/osmo-bts/cbch.h
index b4ac409..af5fd9a 100644
--- a/include/osmo-bts/cbch.h
+++ b/include/osmo-bts/cbch.h
@@ -7,9 +7,8 @@
 #include <osmo-bts/bts.h>
 
 /* incoming SMS broadcast command from RSL */
-int bts_process_smscb_cmd(struct gsm_bts *bts,
-			  struct rsl_ie_cb_cmd_type cmd_type,
-			  uint8_t msg_len, const uint8_t *msg);
+int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_type,
+			  bool extended_cbch, uint8_t msg_len, const uint8_t *msg);
 
 /* call-back from bts model specific code when it wants to obtain a CBCH
  * block for a given gsm_time.  outbuf must have 23 bytes of space. */
diff --git a/include/osmo-bts/gsm_data_shared.h b/include/osmo-bts/gsm_data_shared.h
index 6974e62..9378730 100644
--- a/include/osmo-bts/gsm_data_shared.h
+++ b/include/osmo-bts/gsm_data_shared.h
@@ -539,6 +539,12 @@
 	uint8_t initial_mcs;
 };
 
+struct bts_smscb_state {
+	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 */
+};
+
 /* The amount of time within which a sudden disconnect of a newly established
  * OML connection will cause a special warning to be logged. */
 #define OSMO_BTS_OML_CONN_EARLY_DISCONNECT 10	 /* in seconds */
@@ -734,11 +740,9 @@
 	/* used by the sysmoBTS to adjust band */
 	uint8_t auto_band;
 
-	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;
+	/* State for SMSCB (Cell Broadcast) for BASIC and EXTENDED channel */
+	struct bts_smscb_state smscb_basic;
+	struct bts_smscb_state smscb_extended;
 
 	float min_qual_rach;	/* minimum quality for RACH bursts */
 	float min_qual_norm;	/* minimum quality for normal daata */
diff --git a/src/common/bts.c b/src/common/bts.c
index 5851e9b..4af219b 100644
--- a/src/common/bts.c
+++ b/src/common/bts.c
@@ -190,7 +190,8 @@
 		initialized = 1;
 	}
 
-	INIT_LLIST_HEAD(&bts->smscb_state.queue);
+	INIT_LLIST_HEAD(&bts->smscb_basic.queue);
+	INIT_LLIST_HEAD(&bts->smscb_extended.queue);
 	INIT_LLIST_HEAD(&bts->oml_queue);
 
 	/* register DTX DL FSM */
diff --git a/src/common/cbch.c b/src/common/cbch.c
index c75b510..6092e46 100644
--- a/src/common/cbch.c
+++ b/src/common/cbch.c
@@ -37,6 +37,17 @@
 	uint8_t num_segs;		/* total number of segments */
 };
 
+/* determine SMSCB state by tb number */
+static struct bts_smscb_state *bts_smscb_state(struct gsm_bts *bts, uint8_t tb)
+{
+	if (tb < 4)
+		return &bts->smscb_basic;
+	else if (tb < 8)
+		return &bts->smscb_extended;
+	else
+		OSMO_ASSERT(0);
+}
+
 /* construct a SMSCB NULL block in the user-provided output buffer at 'out' */
 static int get_smscb_null_block(uint8_t *out)
 {
@@ -52,12 +63,12 @@
 }
 
 /* get the next block of the current CB message */
-static int get_smscb_block(struct gsm_bts *bts, uint8_t *out, uint8_t block_nr,
+static int get_smscb_block(struct bts_smscb_state *bts_ss, uint8_t *out, uint8_t block_nr,
 			   const struct gsm_time *g_time)
 {
 	int to_copy;
 	struct gsm412_block_type *block_type;
-	struct smscb_msg *msg = bts->smscb_state.cur_msg;
+	struct smscb_msg *msg = bts_ss->cur_msg;
 
 	if (!msg) {
 		/* No message: Send NULL block */
@@ -101,11 +112,11 @@
 		block_type->lb = 0;
 
 	if (block_nr == 4) {
-		if (msg != bts->smscb_state.default_msg) {
+		if (msg != bts_ss->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;
+			talloc_free(bts_ss->cur_msg);
+			bts_ss->cur_msg = NULL;
 		} else {
 			DEBUGPGT(DLSMS, g_time, "keeping fully-transmitted default message %p\n", msg);
 		}
@@ -131,11 +142,16 @@
 
 
 /* incoming SMS broadcast command from RSL */
-int bts_process_smscb_cmd(struct gsm_bts *bts,
-			  struct rsl_ie_cb_cmd_type cmd_type,
-			  uint8_t msg_len, const uint8_t *msg)
+int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_type,
+			  bool extended_cbch, uint8_t msg_len, const uint8_t *msg)
 {
 	struct smscb_msg *scm;
+	struct bts_smscb_state *bts_ss;
+
+	if (extended_cbch)
+		bts_ss = &bts->smscb_extended;
+	else
+		bts_ss = &bts->smscb_basic;
 
 	if (msg_len > sizeof(scm->msg)) {
 		LOGP(DLSMS, LOGL_ERROR,
@@ -157,7 +173,8 @@
 	scm->num_segs = last_block_rsl2um[cmd_type.last_block&3];
 	memcpy(scm->msg, msg, msg_len);
 
-	LOGP(DLSMS, LOGL_INFO, "RSL SMSCB COMMAND (type=%s, num_blocks=%u)\n",
+	LOGP(DLSMS, LOGL_INFO, "RSL SMSCB COMMAND (chan=%s, type=%s, num_blocks=%u)\n",
+		extended_cbch ? "EXTENDED" : "BASIC",
 		get_value_string(rsl_cb_cmd_names, cmd_type.command), scm->num_segs);
 
 	switch (cmd_type.command) {
@@ -165,20 +182,20 @@
 	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);
+		llist_add_tail(&scm->list, &bts_ss->queue);
 		/* FIXME: limit queue size and optionally send CBCH LOAD Information (overflow) via RSL */
 		break;
 	case RSL_CB_CMD_TYPE_DEFAULT:
 		/* 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 (bts_ss->cur_msg && bts_ss->cur_msg == bts_ss->default_msg)
+			talloc_free(bts_ss->cur_msg);
 		if (cmd_type.def_bcast == RSL_CB_CMD_DEFBCAST_NORMAL)
 			/* def_bcast == 0: normal message */
-			bts->smscb_state.default_msg = scm;
+			bts_ss->default_msg = scm;
 		else {
 			/* def_bcast == 1: NULL message */
-			bts->smscb_state.default_msg = NULL;
+			bts_ss->default_msg = NULL;
 			talloc_free(scm);
 		}
 		break;
@@ -190,11 +207,12 @@
 	return 0;
 }
 
-static struct smscb_msg *select_next_smscb(struct gsm_bts *bts)
+static struct smscb_msg *select_next_smscb(struct gsm_bts *bts, uint8_t tb)
 {
+	struct bts_smscb_state *bts_ss = bts_smscb_state(bts, tb);
 	struct smscb_msg *msg;
 
-	msg = llist_first_entry_or_null(&bts->smscb_state.queue, struct smscb_msg, list);
+	msg = llist_first_entry_or_null(&bts_ss->queue, struct smscb_msg, list);
 	if (msg) {
 		llist_del(&msg->list);
 		DEBUGP(DLSMS, "%s: Dequeued msg\n", __func__);
@@ -204,7 +222,7 @@
 	/* FIXME: send CBCH LOAD Information (underflow) via RSL */
 
 	/* choose the default message, if any */
-	msg = bts->smscb_state.default_msg;
+	msg = bts_ss->default_msg;
 	if (msg) {
 		DEBUGP(DLSMS, "%s: Using default msg\n", __func__);
 		return msg;
@@ -219,10 +237,14 @@
 int bts_cbch_get(struct gsm_bts *bts, uint8_t *outbuf, struct gsm_time *g_time)
 {
 	uint32_t fn = gsm_gsmtime2fn(g_time);
+	struct bts_smscb_state *bts_ss;
 	/* According to 05.02 Section 6.5.4 */
 	uint32_t tb = (fn / 51) % 8;
+	uint8_t block_nr = tb % 4;
 	int rc = 0;
 
+	bts_ss = bts_smscb_state(bts, tb);
+
 	/* The multiframes used for the basic cell broadcast channel
 	 * shall be those in * which TB = 0,1,2 and 3. The multiframes
 	 * used for the extended cell broadcast channel shall be those
@@ -234,16 +256,14 @@
 
 	switch (tb) {
 	case 0:
+	case 4:
 		/* select a new SMSCB message */
-		bts->smscb_state.cur_msg = select_next_smscb(bts);
-		rc = get_smscb_block(bts, outbuf, tb, g_time);
+		bts_ss->cur_msg = select_next_smscb(bts, tb);
+		rc = get_smscb_block(bts_ss, outbuf, block_nr, g_time);
 		break;
 	case 1: case 2: case 3:
-		rc = get_smscb_block(bts, outbuf, tb, g_time);
-		break;
-	case 4: case 5: case 6: case 7:
-		/* always send NULL frame in extended CBCH for now */
-		rc = get_smscb_null_block(outbuf);
+	case 5: case 6: case 7:
+		rc = get_smscb_block(bts_ss, outbuf, block_nr, g_time);
 		break;
 	}
 
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 8021d2d..364e829 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -487,6 +487,7 @@
 	struct abis_rsl_cchan_hdr *cch = msgb_l2(msg);
 	struct tlv_parsed tp;
 	struct rsl_ie_cb_cmd_type *cb_cmd_type;
+	bool extended_cbch = false;
 	int rc;
 
 	rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg));
@@ -495,11 +496,16 @@
 	    !TLVP_PRESENT(&tp, RSL_IE_SMSCB_MSG))
 		return rsl_tx_error_report(trx, RSL_ERR_MAND_IE_ERROR, &cch->chan_nr, NULL, msg);
 
+	if (TLVP_PRESENT(&tp, RSL_IE_SMSCB_CHAN_INDICATOR)) {
+		if ((*TLVP_VAL(&tp, RSL_IE_SMSCB_CHAN_INDICATOR) & 0x0f) == 0x01)
+			extended_cbch = true;
+	}
+
 	cb_cmd_type = (struct rsl_ie_cb_cmd_type *)
 					TLVP_VAL(&tp, RSL_IE_CB_CMD_TYPE);
 
-	rc = bts_process_smscb_cmd(trx->bts, *cb_cmd_type, TLVP_LEN(&tp, RSL_IE_SMSCB_MSG),
-				   TLVP_VAL(&tp, RSL_IE_SMSCB_MSG));
+	rc = bts_process_smscb_cmd(trx->bts, *cb_cmd_type, extended_cbch,
+				   TLVP_LEN(&tp, RSL_IE_SMSCB_MSG), TLVP_VAL(&tp, RSL_IE_SMSCB_MSG));
 	if (rc < 0)
 		return rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT, &cch->chan_nr, NULL, msg);
 
diff --git a/src/common/vty.c b/src/common/vty.c
index 9e900b2..53a8674 100644
--- a/src/common/vty.c
+++ b/src/common/vty.c
@@ -865,8 +865,10 @@
 		bts->agch_queue.rejected_msgs, bts->agch_queue.agch_msgs,
 		bts->agch_queue.pch_msgs,
 		VTY_NEWLINE);
-	vty_out(vty, "  CBCH backlog queue length: %u%s",
-		llist_length(&bts->smscb_state.queue), VTY_NEWLINE);
+	vty_out(vty, "  CBCH backlog queue length (BASIC): %u%s",
+		llist_length(&bts->smscb_basic.queue), VTY_NEWLINE);
+	vty_out(vty, "  CBCH backlog queue length (EXTENDED): %u%s",
+		llist_length(&bts->smscb_extended.queue), VTY_NEWLINE);
 	vty_out(vty, "  Paging: queue length %d, buffer space %d%s",
 		paging_queue_length(bts->paging_state), paging_buffer_space(bts->paging_state),
 		VTY_NEWLINE);

-- 
To view, visit https://gerrit.osmocom.org/14109
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: If2c6dc7da1e2185ab75fc957f8d305ad8db22429
Gerrit-Change-Number: 14109
Gerrit-PatchSet: 2
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder (1000002)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190521/a95bc793/attachment.html>


More information about the gerrit-log mailing list