summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-05-30 10:29:36 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2013-07-29 12:43:54 +0200
commit507c0a363a7e55040b3925858299966f849b6c78 (patch)
tree7247d5588cff372698198913e21a8ecec1ac2d0f
parentc42c4da720ac18cde075fcd718ae4cc827cbf18e (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.
-rw-r--r--openbsc/include/openbsc/chan_alloc.h3
-rw-r--r--openbsc/src/libbsc/chan_alloc.c47
2 files changed, 50 insertions, 0 deletions
diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h
index f2d3c781d..63c072496 100644
--- a/openbsc/include/openbsc/chan_alloc.h
+++ b/openbsc/include/openbsc/chan_alloc.h
@@ -35,6 +35,9 @@ struct gsm_bts_trx_ts *ts_alloc(struct gsm_bts *bts,
/* Regular physical channel (TS) */
void ts_free(struct gsm_bts_trx_ts *ts);
+/* Count number of free TS of given pchan type */
+int lc_count_bts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan);
+
/* Find an allocated channel for a specified subscriber */
struct gsm_subscriber_connection *connection_for_subscr(struct gsm_subscriber *subscr);
diff --git a/openbsc/src/libbsc/chan_alloc.c b/openbsc/src/libbsc/chan_alloc.c
index 3feecc59c..5a7b3f42e 100644
--- a/openbsc/src/libbsc/chan_alloc.c
+++ b/openbsc/src/libbsc/chan_alloc.c
@@ -224,6 +224,53 @@ _lc_find_bts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)
return &ts->lchan[0];
}
+static int
+_lc_count_trx(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++) {
+ ts = &trx->ts[j];
+ if (!ts_is_usable(ts))
+ continue;
+ /* ip.access dynamic TCH/F + PDCH combination */
+ if (ts->pchan == GSM_PCHAN_TCH_F_PDCH &&
+ pchan == GSM_PCHAN_TCH_F) {
+ /* we can only consider such a dynamic channel
+ * if the PDCH is currently inactive */
+ if (ts->flags & TS_F_PDCH_MODE)
+ continue;
+ } else if (ts->pchan != pchan)
+ continue;
+ /* check if all sub-slots are allocated yet */
+ for (ss = 0; ss < subslots_per_pchan[pchan]; 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 lc_count_bts(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 += _lc_count_trx(trx, pchan);
+
+ return count;
+}
+
/* Allocate a logical channel */
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type,
int allow_bigger)