aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-05-30 14:12:48 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2018-01-12 03:28:14 +0100
commit02afe465bfdbc381a7c174b0d83b4720d7d18fe9 (patch)
treef13b7c0763583f932d0cddd601ba84c36fc12ef3
parent178ebc1e664d399861ead0bdc0e94aecc23cb015 (diff)
HO: Add a penalty timer list to the subscriber connection entity
This penalty timer is used to temporarily block cells where handover or assignment failed or where handover is not allowed. This is usefull to prevent repeated handover attempts to broken cells or cells that have limited allowed distance. Change-Id: I95cb7e3211b2470b773965e7aa94d8eb6c8c1a3a
-rw-r--r--include/osmocom/bsc/gsm_data.h10
-rw-r--r--src/libbsc/bsc_api.c10
2 files changed, 20 insertions, 0 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index f07a593cc..d03e9b52a 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -67,6 +67,13 @@ struct gsm_classmark {
uint8_t classmark3[14]; /* if cm3 gets extended by spec, it will be truncated */
};
+/* penalty timers for handover */
+struct ho_penalty_timer {
+ struct llist_head entry;
+ uint8_t bts;
+ time_t timeout;
+};
+
/* active radio connection of a mobile subscriber */
struct gsm_subscriber_connection {
/* global linked list of subscriber_connections */
@@ -96,6 +103,9 @@ struct gsm_subscriber_connection {
/* buffer/cache for classmark of the ME of the subscriber */
struct gsm_classmark classmark;
+
+ /* penalty timers for handover */
+ struct llist_head ho_penalty_timers;
};
static inline struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn) {
diff --git a/src/libbsc/bsc_api.c b/src/libbsc/bsc_api.c
index bd55dfc5c..236163bc1 100644
--- a/src/libbsc/bsc_api.c
+++ b/src/libbsc/bsc_api.c
@@ -262,12 +262,15 @@ struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_lchan *lcha
conn->lchan = lchan;
conn->bts = lchan->ts->trx->bts;
lchan->conn = conn;
+ INIT_LLIST_HEAD(&conn->ho_penalty_timers);
llist_add_tail(&conn->entry, &net->subscr_conns);
return conn;
}
void bsc_subscr_con_free(struct gsm_subscriber_connection *conn)
{
+ struct ho_penalty_timer *penalty;
+
if (!conn)
return;
@@ -289,6 +292,13 @@ void bsc_subscr_con_free(struct gsm_subscriber_connection *conn)
conn->secondary_lchan->conn = NULL;
}
+ /* flush handover penalty timers */
+ while ((penalty = llist_first_entry_or_null(&conn->ho_penalty_timers,
+ struct ho_penalty_timer, entry))) {
+ llist_del(&penalty->entry);
+ talloc_free(penalty);
+ }
+
llist_del(&conn->entry);
talloc_free(conn);
}