aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-06-07 22:28:56 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-06-07 22:28:56 +0800
commit4d4e6714cd74d297d08d61965dd962938a09cc11 (patch)
tree3fa6f1818f6c81573c8191093cf4ba9c1808b774
parent3806b070bbe53d3031e49671d2c3ce0e3d097635 (diff)
bsc_msc_ip: When closing the SCCP check primary and secondary lchan
When closing a SCCP connection and any of the two lchan's are open, then close them down properly. Move the lchan freeing into a new method and call that one from the SCCP connection close handling. Move the bss scp data varaible to the top of the context..
-rw-r--r--openbsc/src/bsc_msc_ip.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/openbsc/src/bsc_msc_ip.c b/openbsc/src/bsc_msc_ip.c
index 4d1c1a18d..aedd45f38 100644
--- a/openbsc/src/bsc_msc_ip.c
+++ b/openbsc/src/bsc_msc_ip.c
@@ -131,7 +131,8 @@ static void sccp_it_fired(void *_data)
bsc_schedule_timer(&data->sccp_it, SCCP_IT_TIMER, 0);
}
-static void bss_force_close(struct bss_sccp_connection_data *bss)
+/* make sure to stop the T10 timer... bss_sccp_free_data is doing that */
+static void bss_close_lchans(struct bss_sccp_connection_data *bss)
{
if (bss->lchan) {
bss->lchan->msc_data = NULL;
@@ -144,6 +145,11 @@ static void bss_force_close(struct bss_sccp_connection_data *bss)
put_subscr_con(&bss->secondary_lchan->conn, 0);
bss->secondary_lchan = NULL;
}
+}
+
+static void bss_force_close(struct bss_sccp_connection_data *bss)
+{
+ bss_close_lchans(bss);
/* force the close by poking stuff */
if (bss->sccp) {
@@ -235,23 +241,21 @@ void msc_outgoing_sccp_data(struct sccp_connection *conn, struct msgb *msg, unsi
void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state)
{
+ struct bss_sccp_connection_data *con_data;
+
if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) {
- LOGP(DMSC, LOGL_DEBUG, "Freeing sccp conn: %p state: %d\n", conn, conn->connection_state);
- if (sccp_get_lchan(conn->data_ctx) != NULL) {
- struct gsm_lchan *lchan = sccp_get_lchan(conn->data_ctx);
+ con_data = (struct bss_sccp_connection_data *) conn->data_ctx;
+ LOGP(DMSC, LOGL_DEBUG, "Freeing sccp conn: %p state: %d\n", conn, conn->connection_state);
+ if (con_data->lchan || con_data->secondary_lchan) {
LOGP(DMSC, LOGL_ERROR, "ERROR: The lchan is still associated\n.");
-
- lchan->msc_data = NULL;
- put_subscr_con(&lchan->conn, 0);
+ bss_close_lchans(con_data);
}
- bss_sccp_free_data((struct bss_sccp_connection_data *)conn->data_ctx);
+ bss_sccp_free_data(con_data);
sccp_connection_free(conn);
return;
} else if (conn->connection_state == SCCP_CONNECTION_STATE_ESTABLISHED) {
- struct bss_sccp_connection_data *con_data;
-
LOGP(DMSC, LOGL_DEBUG, "Connection established: %p\n", conn);
con_data = (struct bss_sccp_connection_data *) conn->data_ctx;