Harald Welte has uploaded this change for review. ( https://gerrit.osmocom.org/14113
Change subject: cbch: Add counters; queue length limits and CBCH LOAD reporting ...................................................................... cbch: Add counters; queue length limits and CBCH LOAD reporting This adds the final missing part to full CBCH support: * keep a tab on the current queue length for basic + extended CBCH * keep rate counters about the number of sent / transmitted SSMCB * send CBCH LOAD information via RSL to the BSC Change-Id: I7068c7937a60a900c40439115bb84dc3ee0d061f --- M include/osmo-bts/cbch.h M include/osmo-bts/gsm_data_shared.h M include/osmo-bts/rsl.h M src/common/bts.c M src/common/cbch.c M src/common/rsl.c M src/common/vty.c 7 files changed, 137 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/13/14113/1 diff --git a/include/osmo-bts/cbch.h b/include/osmo-bts/cbch.h index af5fd9a..6bba5fa 100644 --- a/include/osmo-bts/cbch.h +++ b/include/osmo-bts/cbch.h @@ -6,6 +6,14 @@ #include <osmo-bts/gsm_data.h> #include <osmo-bts/bts.h> +enum { + CBCH_CTR_RCVD_QUEUED, + CBCH_CTR_RCVD_DROPPED, + CBCH_CTR_SENT_SINGLE, + CBCH_CTR_SENT_DEFAULT, + CBCH_CTR_SENT_NULL, +}; + /* incoming SMS broadcast command from RSL */ 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); diff --git a/include/osmo-bts/gsm_data_shared.h b/include/osmo-bts/gsm_data_shared.h index 860c296..415e6bc 100644 --- a/include/osmo-bts/gsm_data_shared.h +++ b/include/osmo-bts/gsm_data_shared.h @@ -542,6 +542,7 @@ struct bts_smscb_state { struct llist_head queue; /* list of struct smscb_msg */ int queue_len; + struct rate_ctr_group *ctrs; struct smscb_msg *cur_msg; /* current SMS-CB */ struct smscb_msg *default_msg; /* default broadcast message; NULL if none */ }; @@ -744,6 +745,9 @@ /* State for SMSCB (Cell Broadcast) for BASIC and EXTENDED channel */ struct bts_smscb_state smscb_basic; struct bts_smscb_state smscb_extended; + int smscb_queue_tgt_len; /* ideal/target queue length */ + int smscb_queue_max_len; /* maximum queue length */ + int smscb_queue_hyst; /* hysteresis for CBCH laod indications */ float min_qual_rach; /* minimum quality for RACH bursts */ float min_qual_norm; /* minimum quality for normal daata */ diff --git a/include/osmo-bts/rsl.h b/include/osmo-bts/rsl.h index 0361841..186018e 100644 --- a/include/osmo-bts/rsl.h +++ b/include/osmo-bts/rsl.h @@ -43,4 +43,6 @@ void cb_ts_connected(struct gsm_bts_trx_ts *ts, int rc); void ipacc_dyn_pdch_complete(struct gsm_bts_trx_ts *ts, int rc); +int rsl_tx_cbch_load_indication(struct gsm_bts *bts, bool ext_cbch, bool overflow, uint8_t amount); + #endif // _RSL_H */ diff --git a/src/common/bts.c b/src/common/bts.c index 4af219b..9ac58bd 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -49,6 +49,7 @@ #include <osmo-bts/oml.h> #include <osmo-bts/signal.h> #include <osmo-bts/dtx_dl_amr_fsm.h> +#include <osmo-bts/cbch.h> #define MIN_QUAL_RACH 5.0f /* at least 5 dB C/I */ #define MIN_QUAL_NORM -0.5f /* at least -1 dB C/I */ @@ -105,6 +106,22 @@ bts_ctr_desc }; +static const struct rate_ctr_desc cbch_ctr_desc[] = { + [CBCH_CTR_RCVD_QUEUED] = {"cbch:rcvd_queued", "Received + queeud CBCH messages (Abis)" }, + [CBCH_CTR_RCVD_DROPPED] = {"cbch:rcvd_dropped", "Received + dropped CBCH messages (Abis)" }, + + [CBCH_CTR_SENT_SINGLE] = {"cbch:sent_single", "Sent single CBCH messages (Um)" }, + [CBCH_CTR_SENT_DEFAULT] = {"cbch:sent_default", "Sent default CBCH messages (Um)" }, + [CBCH_CTR_SENT_NULL] = {"cbch:sent_null", "Sent NULL CBCH messages (Um)" }, +}; +static const struct rate_ctr_group_desc cbch_ctrg_desc = { + "cbch", + "cell broadcast channel", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(cbch_ctr_desc), + cbch_ctr_desc +}; + /* Initialize the BTS data structures, called before config * file reading */ int bts_init(struct gsm_bts *bts) @@ -191,7 +208,15 @@ } INIT_LLIST_HEAD(&bts->smscb_basic.queue); + bts->smscb_basic.ctrs = rate_ctr_group_alloc(bts, &cbch_ctrg_desc, 0); + OSMO_ASSERT(bts->smscb_basic.ctrs); INIT_LLIST_HEAD(&bts->smscb_extended.queue); + bts->smscb_extended.ctrs = rate_ctr_group_alloc(bts, &cbch_ctrg_desc, 1); + OSMO_ASSERT(bts->smscb_extended.ctrs); + bts->smscb_queue_max_len = 15; + bts->smscb_queue_tgt_len = 2; + bts->smscb_queue_hyst = 2; + INIT_LLIST_HEAD(&bts->oml_queue); /* register DTX DL FSM */ diff --git a/src/common/cbch.c b/src/common/cbch.c index 2107f11..cdd30e6 100644 --- a/src/common/cbch.c +++ b/src/common/cbch.c @@ -26,6 +26,7 @@ #include <osmo-bts/bts.h> #include <osmo-bts/cbch.h> +#include <osmo-bts/rsl.h> #include <osmo-bts/logging.h> /* internal representation of one SMS-CB message (e.g. in the pending queue */ @@ -37,6 +38,28 @@ uint8_t num_segs; /* total number of segments */ }; +/* determine if current queue length differes more than permitted hysteresis from target + * queue length. If it does, send CBCH LOAD IND */ +static void check_and_send_cbch_load(struct gsm_bts *bts, struct bts_smscb_state *bts_ss) +{ + int delta = bts_ss->queue_len - bts->smscb_queue_tgt_len; + bool extended_cbch = false; + + if (bts_ss == &bts->smscb_extended) + extended_cbch = true; + + if (abs(delta) < bts->smscb_queue_hyst) + return; + + if (delta < 0) { + /* Overrun */ + rsl_tx_cbch_load_indication(bts, extended_cbch, true, OSMO_MIN(15, -delta)); + } else { + /* Underrun */ + rsl_tx_cbch_load_indication(bts, extended_cbch, false, OSMO_MIN(15, delta)); + } +} + /* determine SMSCB state by tb number */ static struct bts_smscb_state *bts_smscb_state(struct gsm_bts *bts, uint8_t tb) { @@ -182,9 +205,16 @@ 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 */ + /* limit queue size and optionally send CBCH LOAD Information (overflow) via RSL */ + if (bts_ss->queue_len >= bts->smscb_queue_max_len) { + rate_ctr_inc2(bts_ss->ctrs, CBCH_CTR_RCVD_DROPPED); + talloc_free(scm); + break; + } llist_add_tail(&scm->list, &bts_ss->queue); bts_ss->queue_len++; - /* FIXME: limit queue size and optionally send CBCH LOAD Information (overflow) via RSL */ + check_and_send_cbch_load(bts, bts_ss); + rate_ctr_inc2(bts_ss->ctrs, CBCH_CTR_RCVD_QUEUED); break; case RSL_CB_CMD_TYPE_DEFAULT: /* old default msg will be free'd in get_smscb_block() if it is currently in transit @@ -217,20 +247,25 @@ if (msg) { llist_del(&msg->list); bts_ss->queue_len--; + check_and_send_cbch_load(bts, bts_ss); DEBUGP(DLSMS, "%s: Dequeued msg\n", __func__); + rate_ctr_inc2(bts_ss->ctrs, CBCH_CTR_SENT_SINGLE); return msg; } - /* FIXME: send CBCH LOAD Information (underflow) via RSL */ + /* send CBCH LOAD Information (underflow) via RSL */ + check_and_send_cbch_load(bts, bts_ss); /* choose the default message, if any */ msg = bts_ss->default_msg; if (msg) { DEBUGP(DLSMS, "%s: Using default msg\n", __func__); + rate_ctr_inc2(bts_ss->ctrs, CBCH_CTR_SENT_DEFAULT); return msg; } DEBUGP(DLSMS, "%s: No queued msg nor default\n", __func__); + rate_ctr_inc2(bts_ss->ctrs, CBCH_CTR_SENT_NULL); return NULL; } diff --git a/src/common/rsl.c b/src/common/rsl.c index 364e829..af0b72d 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -1636,6 +1636,32 @@ return 0; } +/* 8.5.8 CBCH Load Information */ +int rsl_tx_cbch_load_indication(struct gsm_bts *bts, bool ext_cbch, bool overflow, uint8_t amount) +{ + struct gsm_lchan *lchan = gsm_bts_get_cbch(bts); + struct msgb *msg; + uint8_t load_info; + + msg = rsl_msgb_alloc(sizeof(struct abis_rsl_cchan_hdr)); + if (!msg) + return -ENOMEM; + + /* 9.3.1 Channel Number */ + rsl_cch_push_hdr(msg, RSL_MT_CBCH_LOAD_IND, gsm_lchan2chan_nr(lchan)); + + /* 9.3.43 CBCH Load Information */ + load_info = ((overflow & 1) << 7) | (amount & 0x0F); + msgb_tv_put(msg, RSL_IE_CBCH_LOAD_INFO, load_info); + /* 9.3.44 SMSCB Channel Indicator */ + if (ext_cbch) + msgb_tv_put(msg, RSL_IE_SMSCB_CHAN_INDICATOR, 0x01); + + msg->trx = bts->c0; + + return abis_bts_rsl_sendmsg(msg); +} + /* * ip.access related messages */ diff --git a/src/common/vty.c b/src/common/vty.c index fab5516..84a0edd 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -310,6 +310,9 @@ vty_out(vty, " pcu-socket %s%s", bts->pcu.sock_path, VTY_NEWLINE); if (bts->supp_meas_toa256) vty_out(vty, " supp-meas-info toa256%s", VTY_NEWLINE); + vty_out(vty, " smscb queue-max-length %d%s", bts->smscb_queue_max_len, VTY_NEWLINE); + vty_out(vty, " smscb queue-target-length %d%s", bts->smscb_queue_tgt_len, VTY_NEWLINE); + vty_out(vty, " smscb queue-hysteresis %d%s", bts->smscb_queue_hyst, VTY_NEWLINE); bts_model_config_write_bts(vty, bts); @@ -687,6 +690,33 @@ return CMD_SUCCESS; } +DEFUN(cfg_bts_smscb_max_qlen, cfg_bts_smscb_max_qlen_cmd, + "smscb queue-max-length <1-60>", + "Maximum queue length for SMSCB (CBCH) queue. In count of messages/pages") +{ + struct gsm_bts *bts = vty->index; + bts->smscb_queue_max_len = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_smscb_tgt_qlen, cfg_bts_smscb_tgt_qlen_cmd, + "smscb queue-target-length <1-30>", + "Target queue length for SMSCB (CBCH) queue. In count of messages/pages") +{ + struct gsm_bts *bts = vty->index; + bts->smscb_queue_tgt_len = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_smscb_qhyst, cfg_bts_smscb_qhyst_cmd, + "smscb queue-hysteresis <0-30>", + "Hysteresis for SMSCB (CBCH) queue. In count of messages/pages") +{ + struct gsm_bts *bts = vty->index; + bts->smscb_queue_hyst = atoi(argv[0]); + return CMD_SUCCESS; +} + #define DB_DBM_STR \ "Unit is dB (decibels)\n" \ @@ -854,6 +884,8 @@ bts->agch_queue.rejected_msgs, bts->agch_queue.agch_msgs, bts->agch_queue.pch_msgs, VTY_NEWLINE); + vty_out(vty, " CBCH queue target: %d, hysteresis: %d, maximum: %d%s", + bts->smscb_queue_tgt_len, bts->smscb_queue_max_len, bts->smscb_queue_hyst, VTY_NEWLINE); vty_out(vty, " CBCH backlog queue length (BASIC): %d%s", bts->smscb_basic.queue_len, VTY_NEWLINE); vty_out(vty, " CBCH backlog queue length (EXTENDED): %u%s", @@ -1614,6 +1646,9 @@ install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd); install_element(BTS_NODE, &cfg_bts_supp_meas_toa256_cmd); install_element(BTS_NODE, &cfg_bts_no_supp_meas_toa256_cmd); + install_element(BTS_NODE, &cfg_bts_smscb_max_qlen_cmd); + install_element(BTS_NODE, &cfg_bts_smscb_tgt_qlen_cmd); + install_element(BTS_NODE, &cfg_bts_smscb_qhyst_cmd); install_element(BTS_NODE, &cfg_trx_gsmtap_sapi_cmd); install_element(BTS_NODE, &cfg_trx_no_gsmtap_sapi_cmd); -- To view, visit https://gerrit.osmocom.org/14113 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: I7068c7937a60a900c40439115bb84dc3ee0d061f Gerrit-Change-Number: 14113 Gerrit-PatchSet: 1 Gerrit-Owner: Harald Welte <lafo...@gnumonks.org>