aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/bsc/osmo_bsc_sccp.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/bsc/osmo_bsc_sccp.c')
-rw-r--r--openbsc/src/bsc/osmo_bsc_sccp.c288
1 files changed, 0 insertions, 288 deletions
diff --git a/openbsc/src/bsc/osmo_bsc_sccp.c b/openbsc/src/bsc/osmo_bsc_sccp.c
deleted file mode 100644
index 1abb47394..000000000
--- a/openbsc/src/bsc/osmo_bsc_sccp.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/* Interaction with the SCCP subsystem */
-/*
- * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2010 by On-Waves
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <openbsc/gsm_data.h>
-#include <openbsc/osmo_bsc.h>
-#include <openbsc/osmo_bsc_grace.h>
-#include <openbsc/osmo_msc_data.h>
-#include <openbsc/debug.h>
-#include <openbsc/ipaccess.h>
-#include <openbsc/signal.h>
-
-#include <osmocore/gsm0808.h>
-#include <osmocore/talloc.h>
-#include <osmocore/protocol/gsm_08_08.h>
-
-#include <osmocom/sccp/sccp.h>
-
-/* SCCP helper */
-#define SCCP_IT_TIMER 60
-
-static LLIST_HEAD(active_connections);
-
-static void free_queued(struct osmo_bsc_sccp_con *conn)
-{
- struct msgb *msg;
-
- while (!llist_empty(&conn->sccp_queue)) {
- /* this is not allowed to fail */
- msg = msgb_dequeue(&conn->sccp_queue);
- msgb_free(msg);
- }
-
- conn->sccp_queue_size = 0;
-}
-
-static void send_queued(struct osmo_bsc_sccp_con *conn)
-{
- struct msgb *msg;
-
- while (!llist_empty(&conn->sccp_queue)) {
- /* this is not allowed to fail */
- msg = msgb_dequeue(&conn->sccp_queue);
- sccp_connection_write(conn->sccp, msg);
- msgb_free(msg);
- conn->sccp_queue_size -= 1;
- }
-}
-
-static void msc_outgoing_sccp_data(struct sccp_connection *conn,
- struct msgb *msg, unsigned int len)
-{
- struct osmo_bsc_sccp_con *bsc_con =
- (struct osmo_bsc_sccp_con *) conn->data_ctx;
-
- bsc_handle_dt1(bsc_con, msg, len);
-}
-
-static void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state)
-{
- struct osmo_bsc_sccp_con *con_data;
-
- if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) {
- con_data = (struct osmo_bsc_sccp_con *) conn->data_ctx;
- if(con_data->conn) {
- LOGP(DMSC, LOGL_ERROR,
- "ERROR: The lchan is still associated\n.");
- gsm0808_clear(con_data->conn);
- subscr_con_free(con_data->conn);
- con_data->conn = NULL;
- }
-
- con_data->sccp = NULL;
- free_queued(con_data);
- sccp_connection_free(conn);
- bsc_delete_connection(con_data);
- } else if (conn->connection_state == SCCP_CONNECTION_STATE_ESTABLISHED) {
- LOGP(DMSC, LOGL_DEBUG, "Connection established: %p\n", conn);
- con_data = (struct osmo_bsc_sccp_con *) conn->data_ctx;
-
- bsc_del_timer(&con_data->sccp_cc_timeout);
- bsc_schedule_timer(&con_data->sccp_it_timeout, SCCP_IT_TIMER, 0);
-
- send_queued(con_data);
- }
-}
-
-static void bsc_sccp_force_free(struct osmo_bsc_sccp_con *data)
-{
- if (data->conn) {
- gsm0808_clear(data->conn);
- subscr_con_free(data->conn);
- data->conn = NULL;
- }
-
- free_queued(data);
- sccp_connection_force_free(data->sccp);
- data->sccp = NULL;
- bsc_delete_connection(data);
-}
-
-static void sccp_it_timeout(void *_data)
-{
- struct osmo_bsc_sccp_con *data =
- (struct osmo_bsc_sccp_con *) _data;
-
- sccp_connection_send_it(data->sccp);
- bsc_schedule_timer(&data->sccp_it_timeout, SCCP_IT_TIMER, 0);
-}
-
-static void sccp_cc_timeout(void *_data)
-{
- struct osmo_bsc_sccp_con *data =
- (struct osmo_bsc_sccp_con *) _data;
-
- if (data->sccp->connection_state >= SCCP_CONNECTION_STATE_ESTABLISHED)
- return;
-
- LOGP(DMSC, LOGL_ERROR, "The connection was never established.\n");
- bsc_sccp_force_free(data);
-}
-
-static void msc_sccp_write_ipa(struct sccp_connection *conn, struct msgb *msg, void *data)
-{
- struct gsm_network *net = (struct gsm_network *) data;
- msc_queue_write(net->msc_data->msc_con, msg, IPAC_PROTO_SCCP);
-}
-
-static int msc_sccp_accept(struct sccp_connection *connection, void *data)
-{
- LOGP(DMSC, LOGL_DEBUG, "Rejecting incoming SCCP connection.\n");
- return -1;
-}
-
-static int msc_sccp_read(struct msgb *msgb, unsigned int length, void *data)
-{
- struct gsm_network *net = (struct gsm_network *) data;
- return bsc_handle_udt(net, net->msc_data->msc_con, msgb, length);
-}
-
-int bsc_queue_for_msc(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
-{
- struct sccp_connection *sccp = conn->sccp;
-
- if (sccp->connection_state > SCCP_CONNECTION_STATE_ESTABLISHED) {
- LOGP(DMSC, LOGL_ERROR, "Connection closing, dropping packet on: %p\n", sccp);
- msgb_free(msg);
- } else if (sccp->connection_state == SCCP_CONNECTION_STATE_ESTABLISHED
- && conn->sccp_queue_size == 0) {
- sccp_connection_write(sccp, msg);
- msgb_free(msg);
- } else if (conn->sccp_queue_size > 10) {
- LOGP(DMSC, LOGL_ERROR, "Connection closing, dropping packet on: %p\n", sccp);
- msgb_free(msg);
- } else {
- LOGP(DMSC, LOGL_DEBUG, "Queueing packet on %p. Queue size: %d\n", sccp, conn->sccp_queue_size);
- conn->sccp_queue_size += 1;
- msgb_enqueue(&conn->sccp_queue, msg);
- }
-
- return 0;
-}
-
-int bsc_create_new_connection(struct gsm_subscriber_connection *conn)
-{
- struct gsm_network *net;
- struct osmo_bsc_sccp_con *bsc_con;
- struct sccp_connection *sccp;
-
- net = conn->bts->network;
- if (!net->msc_data->msc_con->is_authenticated) {
- LOGP(DMSC, LOGL_ERROR, "Not connected to a MSC. Not forwarding data.\n");
- return -1;
- }
-
- if (!bsc_grace_allow_new_connection(net)) {
- LOGP(DMSC, LOGL_NOTICE, "BSC in grace period. No new connections.\n");
- return -1;
- }
-
- sccp = sccp_connection_socket();
- if (!sccp) {
- LOGP(DMSC, LOGL_ERROR, "Failed to allocate memory.\n");
- return -ENOMEM;
- }
-
- bsc_con = talloc_zero(conn->bts, struct osmo_bsc_sccp_con);
- if (!bsc_con) {
- LOGP(DMSC, LOGL_ERROR, "Failed to allocate.\n");
- sccp_connection_free(sccp);
- return -1;
- }
-
- /* callbacks */
- sccp->state_cb = msc_outgoing_sccp_state;
- sccp->data_cb = msc_outgoing_sccp_data;
- sccp->data_ctx = bsc_con;
-
- /* prepare the timers */
- bsc_con->sccp_it_timeout.cb = sccp_it_timeout;
- bsc_con->sccp_it_timeout.data = bsc_con;
- bsc_con->sccp_cc_timeout.cb = sccp_cc_timeout;
- bsc_con->sccp_cc_timeout.data = bsc_con;
-
- INIT_LLIST_HEAD(&bsc_con->sccp_queue);
-
- bsc_con->sccp = sccp;
- bsc_con->msc_con = net->msc_data->msc_con;
- bsc_con->conn = conn;
- llist_add(&bsc_con->entry, &active_connections);
- conn->sccp_con = bsc_con;
- return 0;
-}
-
-int bsc_open_connection(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
-{
- bsc_schedule_timer(&conn->sccp_cc_timeout, 10, 0);
- sccp_connection_connect(conn->sccp, &sccp_ssn_bssap, msg);
- msgb_free(msg);
- return 0;
-}
-
-int bsc_delete_connection(struct osmo_bsc_sccp_con *sccp)
-{
- if (!sccp)
- return 0;
-
- if (sccp->conn)
- LOGP(DMSC, LOGL_ERROR, "Should have been cleared.\n");
-
- llist_del(&sccp->entry);
- bsc_del_timer(&sccp->sccp_it_timeout);
- bsc_del_timer(&sccp->sccp_cc_timeout);
- talloc_free(sccp);
- return 0;
-}
-
-static void bsc_close_connections(struct bsc_msc_connection *msc_con)
-{
- struct osmo_bsc_sccp_con *con, *tmp;
-
- llist_for_each_entry_safe(con, tmp, &active_connections, entry)
- bsc_sccp_force_free(con);
-}
-
-static int handle_msc_signal(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct osmo_msc_data *data;
-
- if (subsys != SS_MSC)
- return 0;
-
- data = (struct osmo_msc_data *) signal_data;
- if (signal == S_MSC_LOST)
- bsc_close_connections(data->msc_con);
-
- return 0;
-}
-
-int osmo_bsc_sccp_init(struct gsm_network *gsmnet)
-{
- sccp_set_log_area(DSCCP);
- sccp_system_init(msc_sccp_write_ipa, gsmnet);
- sccp_connection_set_incoming(&sccp_ssn_bssap, msc_sccp_accept, NULL);
- sccp_set_read(&sccp_ssn_bssap, msc_sccp_read, gsmnet);
-
- register_signal_handler(SS_MSC, handle_msc_signal, gsmnet);
-
- return 0;
-}