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>