Harald Welte has uploaded this change for review. ( 
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(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/09/14109/1

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 9284e6f..fda1c32 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: newchange
Gerrit-Change-Id: If2c6dc7da1e2185ab75fc957f8d305ad8db22429
Gerrit-Change-Number: 14109
Gerrit-PatchSet: 1
Gerrit-Owner: Harald Welte <lafo...@gnumonks.org>

Reply via email to