/* lchan release handling */ void msc_release_connection(struct gsm_subscriber_connection *conn) { /* skip when we are in release, e.g. due an error */ if (conn->in_release) return; /* skip releasing of silent calls as they have no transaction */ if (conn->silent_call) return; /* check if there is a pending operation */ if (conn->loc_operation || conn->sec_operation || conn->anch_operation) return; if (trans_has_conn(conn)) return; /* no more connections, asking to release the channel */ /* * We had stopped the LU expire timer T3212. Now we are about * to send the MS back to the idle state and this should lead * to restarting the timer. Set the new expiration time. */ if (conn->expire_timer_stopped) subscr_update_expire_lu(conn->subscr, conn->bts); conn->in_release = 1; gsm0808_clear(conn); if (conn->put_channel) { conn->put_channel = 0; subscr_put_channel(conn->subscr); } subscr_con_free(conn); }
static void handle_release(struct gsm_subscriber_connection *conn, struct bsc_api *bsc, struct gsm_lchan *lchan) { int destruct = 1; if (conn->secondary_lchan == lchan) { osmo_timer_del(&conn->T10); conn->secondary_lchan = NULL; bsc->assign_fail(conn, GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, NULL); } /* clear the connection now */ if (bsc->clear_request) destruct = bsc->clear_request(conn, 0); /* now give up all channels */ if (conn->lchan == lchan) conn->lchan = NULL; if (conn->ho_lchan == lchan) { bsc_clear_handover(conn, 0); conn->ho_lchan = NULL; } lchan->conn = NULL; gsm0808_clear(conn); if (destruct) subscr_con_free(conn); }
/* * GSM 08.08 § 3.1.9.1 and 3.2.1.21... * release our gsm_subscriber_connection and send message */ static int bssmap_handle_clear_command(struct osmo_bsc_sccp_con *conn, struct msgb *msg, unsigned int payload_length) { struct msgb *resp; /* TODO: handle the cause of this package */ if (conn->conn) { LOGP(DMSC, LOGL_INFO, "Releasing all transactions on %p\n", conn); gsm0808_clear(conn->conn); subscr_con_free(conn->conn); conn->conn = NULL; } /* send the clear complete message */ resp = gsm0808_create_clear_complete(); if (!resp) { LOGP(DMSC, LOGL_ERROR, "Sending clear complete failed.\n"); return -1; } bsc_queue_for_msc(conn, resp); return 0; }