diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-12-27 13:46:48 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2011-01-06 14:52:51 +0100 |
commit | ebd50a6fd23c630ae9db13851b986fa7aebc2f62 (patch) | |
tree | e45845615735d2f55a48bd4d6235a0f936808cb7 | |
parent | f1ba09b2e60a0f77ae142d62e8c5bcd0c294d35a (diff) |
bsc: Clear the hand-over in case the new_lchan is failing
When the new_lchan for handover is failing we should stop the
handover operation. This is fixing a crash that we get a timeout
on the lchan and have no conn set to it. Introduce a flag to
the bsc_clear_handover to not free the lchan. In case the ho_lchan
is failing we do not want to call lchan_release as it would
reset the state.
-rw-r--r-- | openbsc/include/openbsc/handover.h | 2 | ||||
-rw-r--r-- | openbsc/src/bsc_api.c | 6 | ||||
-rw-r--r-- | openbsc/src/handover_logic.c | 6 |
3 files changed, 9 insertions, 5 deletions
diff --git a/openbsc/include/openbsc/handover.h b/openbsc/include/openbsc/handover.h index 5d710576c..9d9a90b84 100644 --- a/openbsc/include/openbsc/handover.h +++ b/openbsc/include/openbsc/handover.h @@ -9,6 +9,6 @@ struct gsm_subscriber_connection; 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); +void bsc_clear_handover(struct gsm_subscriber_connection *conn, int free_lchan); #endif /* _HANDOVER_H */ diff --git a/openbsc/src/bsc_api.c b/openbsc/src/bsc_api.c index 73b29b5ff..a9e5f71ed 100644 --- a/openbsc/src/bsc_api.c +++ b/openbsc/src/bsc_api.c @@ -520,7 +520,7 @@ int gsm0808_cipher_mode(struct gsm_subscriber_connection *conn, int cipher, int gsm0808_clear(struct gsm_subscriber_connection *conn) { if (conn->ho_lchan) - bsc_clear_handover(conn); + bsc_clear_handover(conn, 1); if (conn->secondary_lchan) lchan_release(conn->secondary_lchan, 0, 1); @@ -633,8 +633,10 @@ static void handle_release(struct gsm_subscriber_connection *conn, /* now give up all channels */ if (conn->lchan == lchan) conn->lchan = NULL; - if (conn->ho_lchan == lchan) + if (conn->ho_lchan == lchan) { + bsc_clear_handover(conn, 0); conn->ho_lchan = NULL; + } lchan->conn = NULL; gsm0808_clear(conn); diff --git a/openbsc/src/handover_logic.c b/openbsc/src/handover_logic.c index 44a69331c..c2e3f8c72 100644 --- a/openbsc/src/handover_logic.c +++ b/openbsc/src/handover_logic.c @@ -149,7 +149,7 @@ int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts) return 0; } -void bsc_clear_handover(struct gsm_subscriber_connection *conn) +void bsc_clear_handover(struct gsm_subscriber_connection *conn, int free_lchan) { struct bsc_handover *ho; @@ -166,7 +166,9 @@ void bsc_clear_handover(struct gsm_subscriber_connection *conn) conn->ho_lchan->conn = NULL; conn->ho_lchan = NULL; - lchan_release(ho->new_lchan, 0, 1); + + if (free_lchan) + lchan_release(ho->new_lchan, 0, 1); bsc_del_timer(&ho->T3103); llist_del(&ho->list); |