diff options
-rw-r--r-- | openbsc/include/openbsc/handover.h | 6 | ||||
-rw-r--r-- | openbsc/src/bsc_api.c | 3 | ||||
-rw-r--r-- | openbsc/src/chan_alloc.c | 9 | ||||
-rw-r--r-- | openbsc/src/handover_logic.c | 24 |
4 files changed, 35 insertions, 7 deletions
diff --git a/openbsc/include/openbsc/handover.h b/openbsc/include/openbsc/handover.h index 8ab1b0642..5d710576c 100644 --- a/openbsc/include/openbsc/handover.h +++ b/openbsc/include/openbsc/handover.h @@ -1,8 +1,14 @@ #ifndef _HANDOVER_H #define _HANDOVER_H + +struct gsm_subscriber_connection; + /* Hand over the specified logical channel to the specified new BTS. * This is the main entry point for the actual handover algorithm, * after it has decided it wants to initiate HO to a specific BTS */ int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts); +/* clear any operation for this connection */ +void bsc_clear_handover(struct gsm_subscriber_connection *conn); + #endif /* _HANDOVER_H */ diff --git a/openbsc/src/bsc_api.c b/openbsc/src/bsc_api.c index 9c1d09063..856dc615c 100644 --- a/openbsc/src/bsc_api.c +++ b/openbsc/src/bsc_api.c @@ -28,6 +28,7 @@ #include <openbsc/signal.h> #include <openbsc/abis_rsl.h> #include <openbsc/chan_alloc.h> +#include <openbsc/handover.h> #include <osmocore/talloc.h> @@ -115,6 +116,8 @@ int gsm0808_clear(struct gsm_subscriber_connection* conn) { struct gsm_lchan *lchan; + bsc_clear_handover(conn); + lchan = conn->lchan; subscr_con_free(conn); lchan_release(lchan, 1, 0); diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c index 675cbbb1d..dda5ff20d 100644 --- a/openbsc/src/chan_alloc.c +++ b/openbsc/src/chan_alloc.c @@ -478,13 +478,8 @@ void subscr_con_free(struct gsm_subscriber_connection *conn) } - /* Release a handover that might be in operation */ - if (conn->ho_lchan) { - conn->ho_lchan->conn = NULL; - lchan_release(conn->ho_lchan, 0, 1); - conn->ho_lchan = NULL; - } - + if (conn->ho_lchan) + LOGP(DNM, LOGL_ERROR, "The ho_lchan should have been cleared.\n"); lchan = conn->lchan; talloc_free(conn); diff --git a/openbsc/src/handover_logic.c b/openbsc/src/handover_logic.c index 42dc5d8e6..cdb066447 100644 --- a/openbsc/src/handover_logic.c +++ b/openbsc/src/handover_logic.c @@ -149,6 +149,30 @@ int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts) return 0; } +void bsc_clear_handover(struct gsm_subscriber_connection *conn) +{ + struct bsc_handover *ho; + + ho = bsc_ho_by_new_lchan(conn->ho_lchan); + + + if (!ho && conn->ho_lchan) + LOGP(DHO, LOGL_ERROR, "BUG: We lost some state.\n"); + + if (!ho) { + LOGP(DHO, LOGL_ERROR, "unable to find HO record\n"); + return; + } + + conn->ho_lchan->conn = NULL; + conn->ho_lchan = NULL; + lchan_release(ho->new_lchan, 0, 1); + + bsc_del_timer(&ho->T3103); + llist_del(&ho->list); + talloc_free(ho); +} + /* T3103 expired: Handover has failed without HO COMPLETE or HO FAIL */ static void ho_T3103_cb(void *_ho) { |