aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-05-30 10:29:36 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2018-01-12 03:28:50 +0100
commit130d7137858153a50394faf92df0d8d8de31ed87 (patch)
tree63c7d0c4a107f3906bef00f831d7cae60a901ae4
parent222e59b7c0adebd4e600b834ea7963386f334226 (diff)
HO: Count number of free timeslot on a given BTS
This is needed for handover algorithm to balance free slots and to prevent congestion of one cell, while other cells still have free capacities. Change-Id: Ic8bee8a515ee8aa9a99af71756fe60b8dd8f868b
-rw-r--r--include/osmocom/bsc/chan_alloc.h3
-rw-r--r--src/libbsc/chan_alloc.c64
2 files changed, 67 insertions, 0 deletions
diff --git a/include/osmocom/bsc/chan_alloc.h b/include/osmocom/bsc/chan_alloc.h
index f2a75c5b8..748e9cd9f 100644
--- a/include/osmocom/bsc/chan_alloc.h
+++ b/include/osmocom/bsc/chan_alloc.h
@@ -24,6 +24,9 @@
struct gsm_subscriber_connection;
+/* Count number of free TS of given pchan type */
+int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan);
+
/* Allocate a logical channel (SDCCH, TCH, ...) */
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type, int allow_bigger);
diff --git a/src/libbsc/chan_alloc.c b/src/libbsc/chan_alloc.c
index bb7df180d..e37d39c87 100644
--- a/src/libbsc/chan_alloc.c
+++ b/src/libbsc/chan_alloc.c
@@ -68,6 +68,70 @@ bool trx_is_usable(const struct gsm_bts_trx *trx)
return true;
}
+static int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan)
+{
+ struct gsm_bts_trx_ts *ts;
+ int j, ss;
+ int count = 0;
+
+ if (!trx_is_usable(trx))
+ return 0;
+
+ for (j = 0; j < 8; j++) {
+ enum gsm_phys_chan_config ts_pchan_is;
+ ts = &trx->ts[j];
+ if (!ts_is_usable(ts))
+ continue;
+
+ ts_pchan_is = ts_pchan(ts);
+
+ if (ts_pchan_is == GSM_PCHAN_PDCH) {
+ /* Dynamic timeslots in PDCH mode will become TCH if needed. */
+ switch (ts->pchan) {
+ case GSM_PCHAN_TCH_F_PDCH:
+ if (pchan == GSM_PCHAN_TCH_F)
+ count++;
+ continue;
+
+ case GSM_PCHAN_TCH_F_TCH_H_PDCH:
+ if (pchan == GSM_PCHAN_TCH_F)
+ count++;
+ else if (pchan == GSM_PCHAN_TCH_H)
+ count += 2;
+ continue;
+
+ default:
+ /* Not dynamic, not applicable. */
+ continue;
+ }
+ }
+
+ if (ts_pchan_is != pchan)
+ continue;
+ /* check if all sub-slots are allocated yet */
+ for (ss = 0; ss < ts_subslots(ts); ss++) {
+ struct gsm_lchan *lc = &ts->lchan[ss];
+ if (lc->type == GSM_LCHAN_NONE &&
+ lc->state == LCHAN_S_NONE)
+ count++;
+ }
+ }
+
+ return count;
+}
+
+/* Count number of free TS of given pchan type */
+int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)
+{
+ struct gsm_bts_trx *trx;
+ int count = 0;
+
+ llist_for_each_entry(trx, &bts->trx_list, list)
+ count += trx_count_free_ts(trx, pchan);
+
+ return count;
+}
+
static struct gsm_lchan *
_lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan,
enum gsm_phys_chan_config dyn_as_pchan)