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> | 2010-12-27 14:12:12 +0100 |
commit | 3a2453cad1837a6990a2c0b36bd21df11a50d87d (patch) | |
tree | ce1ce485e4a14e439540e302ea8d156d16019b3e | |
parent | 5eea1f8c20be88eec69ec7d9d7ed005098a70937 (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 a91de66f7..44db39f1c 100644 --- a/openbsc/src/bsc_api.c +++ b/openbsc/src/bsc_api.c @@ -521,7 +521,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); @@ -634,8 +634,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 d04c0eb64..22949dbd5 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); |