aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-05-30 14:12:48 +0200
committerHarald Welte <laforge@gnumonks.org>2018-01-22 01:57:50 +0000
commit084b421fba9284e9dbe80cf4ee514fafb92ca54f (patch)
treebccd6520e7eb9e7975f957611c3223c523c0c4d2
parent83594847a8fa8dee4011000747906f10a09bf652 (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 4e07f2672..d9dd2d4b8 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -71,6 +71,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 */
@@ -104,6 +111,9 @@ struct gsm_subscriber_connection {
/* Cache DTAP messages during handover/assignment (msgb_enqueue()/msgb_dequeue())*/
struct llist_head ho_dtap_cache;
unsigned int ho_dtap_cache_len;
+
+ /* 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 9c60af9c0..27bf739d1 100644
--- a/src/libbsc/bsc_api.c
+++ b/src/libbsc/bsc_api.c
@@ -277,6 +277,7 @@ struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_lchan *lcha
conn->bts = lchan->ts->trx->bts;
lchan->conn = conn;
INIT_LLIST_HEAD(&conn->ho_dtap_cache);
+ INIT_LLIST_HEAD(&conn->ho_penalty_timers);
llist_add_tail(&conn->entry, &net->subscr_conns);
return conn;
}
@@ -326,6 +327,8 @@ static void ho_dtap_cache_flush(struct gsm_subscriber_connection *conn, int send
void bsc_subscr_con_free(struct gsm_subscriber_connection *conn)
{
+ struct ho_penalty_timer *penalty;
+
if (!conn)
return;
@@ -350,6 +353,13 @@ void bsc_subscr_con_free(struct gsm_subscriber_connection *conn)
/* drop pending messages */
ho_dtap_cache_flush(conn, 0);
+ /* 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);
}