aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/Makefile.am2
-rw-r--r--openbsc/include/openbsc/a_reset.h (renamed from openbsc/include/openbsc/osmo_bsc_reset.h)36
-rw-r--r--openbsc/include/openbsc/bsc_msc.h4
-rw-r--r--openbsc/include/openbsc/osmo_bsc_sigtran.h6
-rw-r--r--openbsc/src/libcommon-cs/Makefile.am1
-rw-r--r--openbsc/src/libcommon-cs/a_reset.c (renamed from openbsc/src/osmo-bsc/osmo_bsc_reset.c)92
-rw-r--r--openbsc/src/osmo-bsc/Makefile.am1
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_bssap.c4
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_sigtran.c33
9 files changed, 102 insertions, 77 deletions
diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am
index e1ae6d2d8..4a5223666 100644
--- a/openbsc/include/openbsc/Makefile.am
+++ b/openbsc/include/openbsc/Makefile.am
@@ -67,7 +67,7 @@ noinst_HEADERS = \
openbscdefines.h \
osmo_bsc.h \
osmo_bsc_grace.h \
- osmo_bsc_reset.h \
+ a_reset.h \
osmo_bsc_rf.h \
osmo_msc.h \
osmo_bsc_sigtran.h \
diff --git a/openbsc/include/openbsc/osmo_bsc_reset.h b/openbsc/include/openbsc/a_reset.h
index 578f763e6..124cf13f1 100644
--- a/openbsc/include/openbsc/osmo_bsc_reset.h
+++ b/openbsc/include/openbsc/a_reset.h
@@ -18,17 +18,43 @@
*
*/
+#pragma once
+
+
+
+/* Reset context data (callbacks, state machine etc...) */
+struct a_reset_ctx {
+
+ /* FSM instance, which handles the reset procedure */
+ struct osmo_fsm_inst *fsm;
+
+ /* Connection failure counter. When this counter
+ * reaches a certain threshold, the reset procedure
+ * will be triggered */
+ int conn_loss_counter;
+
+ /* A human readable name to display in the logs */
+ char name[256];
+
+ /* Callback function to be called when a connection
+ * failure is detected and a rest must occur */
+ void (*cb)(void *priv);
+
+ /* Privated data for the callback function */
+ void *priv;
+};
+
/* Create and start state machine which handles the reset/reset-ack procedure */
-void start_reset_fsm(struct bsc_msc_data *msc);
+void a_reset_start(struct a_reset_ctx *reset);
/* Confirm that we sucessfully received a reset acknowlege message */
-void reset_ack_confirm(struct bsc_msc_data *msc);
+void a_reset_ack_confirm(struct a_reset_ctx *reset);
/* Report a failed connection */
-void report_conn_fail(struct bsc_msc_data *msc);
+void a_reset_conn_fail(struct a_reset_ctx *reset);
/* Report a successful connection */
-void report_conn_success(struct bsc_msc_data *msc);
+void a_reset_conn_success(struct a_reset_ctx *reset);
/* Check if we have a connection to a specified msc */
-bool sccp_conn_ready(struct bsc_msc_data *msc);
+bool a_reset_conn_ready(struct a_reset_ctx *reset);
diff --git a/openbsc/include/openbsc/bsc_msc.h b/openbsc/include/openbsc/bsc_msc.h
index b80729c3a..a7c881b84 100644
--- a/openbsc/include/openbsc/bsc_msc.h
+++ b/openbsc/include/openbsc/bsc_msc.h
@@ -25,6 +25,7 @@
#include <osmocom/core/write_queue.h>
#include <osmocom/core/timer.h>
#include <osmocom/sigtran/sccp_sap.h>
+#include <openbsc/a_reset.h>
#include <netinet/in.h>
@@ -60,8 +61,7 @@ struct bsc_msc_connection {
struct osmo_sccp_user *sccp_user;
struct osmo_sccp_addr g_calling_addr;
struct osmo_sccp_addr g_called_addr;
- struct osmo_fsm_inst *fsm_reset;
- unsigned int msc_conn_loss_count;
+ struct a_reset_ctx reset;
int conn_id_counter;
};
diff --git a/openbsc/include/openbsc/osmo_bsc_sigtran.h b/openbsc/include/openbsc/osmo_bsc_sigtran.h
index 92d8ba64e..caeea6092 100644
--- a/openbsc/include/openbsc/osmo_bsc_sigtran.h
+++ b/openbsc/include/openbsc/osmo_bsc_sigtran.h
@@ -38,11 +38,5 @@ int osmo_bsc_sigtran_send(struct osmo_bsc_sccp_con *conn, struct msgb *msg);
* locally, when a connection is closed by the MSC */
int osmo_bsc_sigtran_del_conn(struct osmo_bsc_sccp_con *sccp);
-/* Send reset to MSC */
-void osmo_bsc_sigtran_tx_reset(struct bsc_msc_data *msc);
-
-/* close all open connections */
-void osmo_bsc_sigtran_reset(struct bsc_msc_data *msc);
-
/* Initalize osmo sigtran backhaul */
int osmo_bsc_sigtran_init(struct llist_head *mscs);
diff --git a/openbsc/src/libcommon-cs/Makefile.am b/openbsc/src/libcommon-cs/Makefile.am
index f3921ba5f..21c27455d 100644
--- a/openbsc/src/libcommon-cs/Makefile.am
+++ b/openbsc/src/libcommon-cs/Makefile.am
@@ -16,5 +16,6 @@ AM_CFLAGS = \
noinst_LIBRARIES = libcommon-cs.a
libcommon_cs_a_SOURCES = \
+ a_reset.c \
common_cs.c \
common_cs_vty.c
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_reset.c b/openbsc/src/libcommon-cs/a_reset.c
index 0baf08089..94d215562 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_reset.c
+++ b/openbsc/src/libcommon-cs/a_reset.c
@@ -34,8 +34,8 @@
#define BAD_CONNECTION_THRESOLD 3 /* connection failures */
enum fsm_states {
- ST_DISC, /* Disconnected from MSC */
- ST_CONN, /* We have a confirmed connection to the MSC */
+ ST_DISC, /* Disconnected from remote end */
+ ST_CONN, /* We have a confirmed connection */
};
static const struct value_string fsm_state_names[] = {
@@ -45,7 +45,7 @@ static const struct value_string fsm_state_names[] = {
};
enum fsm_evt {
- EV_RESET_ACK, /* got reset acknowlegement from the MSC */
+ EV_RESET_ACK, /* got reset acknowlegement from remote end */
EV_N_DISCONNECT, /* lost a connection */
EV_N_CONNECT, /* made a successful connection */
};
@@ -60,34 +60,35 @@ static const struct value_string fsm_evt_names[] = {
/* Disconnected state */
static void fsm_disc_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
- struct bsc_msc_data *msc = (struct bsc_msc_data *)data;
+ struct a_reset_ctx *reset = (struct a_reset_ctx *)data;
+ OSMO_ASSERT(reset);
- LOGP(DMSC, LOGL_NOTICE, "fsm-state (msc-reset): %s, fsm-event: %s, MSC No.: %i\n",
- get_value_string(fsm_state_names, ST_DISC), get_value_string(fsm_evt_names, event), msc->nr);
- msc->msc_con->msc_conn_loss_count = 0;
+ LOGP(DMSC, LOGL_NOTICE, "(%s) fsm-state (msc-reset): %s, fsm-event: %s\n", reset->name,
+ get_value_string(fsm_state_names, ST_CONN), get_value_string(fsm_evt_names, event));
+
+ reset->conn_loss_counter = 0;
osmo_fsm_inst_state_chg(fi, ST_CONN, 0, 0);
}
/* Connected state */
static void fsm_conn_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
- struct bsc_msc_data *msc = (struct bsc_msc_data *)data;
-
- LOGP(DMSC, LOGL_NOTICE, "fsm-state (msc-reset): %s, fsm-event: %s, MSC No.: %i\n",
- get_value_string(fsm_state_names, ST_CONN), get_value_string(fsm_evt_names, event), msc->nr);
+ struct a_reset_ctx *reset = (struct a_reset_ctx *)data;
+ OSMO_ASSERT(reset);
- OSMO_ASSERT(msc);
+ LOGP(DMSC, LOGL_NOTICE, "(%s) fsm-state (msc-reset): %s, fsm-event: %s\n", reset->name,
+ get_value_string(fsm_state_names, ST_CONN), get_value_string(fsm_evt_names, event));
switch (event) {
case EV_N_DISCONNECT:
- if (msc->msc_con->msc_conn_loss_count >= BAD_CONNECTION_THRESOLD) {
- LOGP(DMSC, LOGL_NOTICE, "SIGTRAN connection to MSC No.: %i down, reconnecting...\n", msc->nr);
+ if (reset->conn_loss_counter >= BAD_CONNECTION_THRESOLD) {
+ LOGP(DMSC, LOGL_NOTICE, "(%s) SIGTRAN connection down, reconnecting...\n", reset->name);
osmo_fsm_inst_state_chg(fi, ST_DISC, RESET_RESEND_INTERVAL, RESET_RESEND_TIMER_NO);
} else
- msc->msc_con->msc_conn_loss_count++;
+ reset->conn_loss_counter++;
break;
case EV_N_CONNECT:
- msc->msc_con->msc_conn_loss_count = 0;
+ reset->conn_loss_counter = 0;
break;
}
}
@@ -95,13 +96,12 @@ static void fsm_conn_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
/* Timer callback to retransmit the reset signal */
static int fsm_reset_ack_timeout_cb(struct osmo_fsm_inst *fi)
{
- struct bsc_msc_data *msc = (struct bsc_msc_data *)fi->priv;
+ struct a_reset_ctx *reset = (struct a_reset_ctx *)fi->priv;
- LOGP(DMSC, LOGL_NOTICE, "reset-ack timeout (T%i) in state %s, MSC No.: %i, resending...\n", fi->T,
- get_value_string(fsm_state_names, fi->state), msc->nr);
+ LOGP(DMSC, LOGL_NOTICE, "(%s) reset-ack timeout (T%i) in state %s, resending...\n", reset->name, fi->T,
+ get_value_string(fsm_state_names, fi->state));
- osmo_bsc_sigtran_reset(msc);
- osmo_bsc_sigtran_tx_reset(msc);
+ reset->cb(reset->priv);
osmo_fsm_inst_state_chg(fi, ST_DISC, RESET_RESEND_INTERVAL, RESET_RESEND_TIMER_NO);
return 0;
@@ -132,58 +132,54 @@ static struct osmo_fsm fsm = {
};
/* Create and start state machine which handles the reset/reset-ack procedure */
-void start_reset_fsm(struct bsc_msc_data *msc)
+void a_reset_start(struct a_reset_ctx *reset)
{
- OSMO_ASSERT(msc);
- OSMO_ASSERT(msc->msc_con);
+ OSMO_ASSERT(reset);
osmo_fsm_register(&fsm);
- msc->msc_con->fsm_reset = osmo_fsm_inst_alloc(&fsm, NULL, NULL, LOGL_DEBUG, "FSM RESET INST");
- OSMO_ASSERT(msc->msc_con->fsm_reset);
+ reset->fsm = osmo_fsm_inst_alloc(&fsm, NULL, NULL, LOGL_DEBUG, "FSM RESET INST");
+ OSMO_ASSERT(reset->fsm);
- msc->msc_con->fsm_reset->priv = msc;
+ reset->fsm->priv = reset;
/* kick off reset-ack sending mechanism */
- osmo_fsm_inst_state_chg(msc->msc_con->fsm_reset, ST_DISC, RESET_RESEND_INTERVAL, RESET_RESEND_TIMER_NO);
+ osmo_fsm_inst_state_chg(reset->fsm, ST_DISC, RESET_RESEND_INTERVAL, RESET_RESEND_TIMER_NO);
}
/* Confirm that we sucessfully received a reset acknowlege message */
-void reset_ack_confirm(struct bsc_msc_data *msc)
+void a_reset_ack_confirm(struct a_reset_ctx *reset)
{
- OSMO_ASSERT(msc);
- OSMO_ASSERT(msc->msc_con);
- OSMO_ASSERT(msc->msc_con->fsm_reset);
+ OSMO_ASSERT(reset);
+ OSMO_ASSERT(reset->fsm);
- osmo_fsm_inst_dispatch(msc->msc_con->fsm_reset, EV_RESET_ACK, msc);
+ osmo_fsm_inst_dispatch(reset->fsm, EV_RESET_ACK, reset);
}
/* Report a failed connection */
-void report_conn_fail(struct bsc_msc_data *msc)
+void a_reset_conn_fail(struct a_reset_ctx *reset)
{
- OSMO_ASSERT(msc);
- OSMO_ASSERT(msc->msc_con);
- OSMO_ASSERT(msc->msc_con->fsm_reset);
+ OSMO_ASSERT(reset);
+ OSMO_ASSERT(reset->fsm);
- osmo_fsm_inst_dispatch(msc->msc_con->fsm_reset, EV_N_DISCONNECT, msc);
+ osmo_fsm_inst_dispatch(reset->fsm, EV_N_DISCONNECT, reset);
}
/* Report a successful connection */
-void report_conn_success(struct bsc_msc_data *msc)
+void a_reset_conn_success(struct a_reset_ctx *reset)
{
- OSMO_ASSERT(msc);
- OSMO_ASSERT(msc->msc_con);
- OSMO_ASSERT(msc->msc_con->fsm_reset);
+ OSMO_ASSERT(reset);
+ OSMO_ASSERT(reset->fsm);
- osmo_fsm_inst_dispatch(msc->msc_con->fsm_reset, EV_N_CONNECT, msc);
+ osmo_fsm_inst_dispatch(reset->fsm, EV_N_CONNECT, reset);
}
/* Check if we have a connection to a specified msc */
-bool sccp_conn_ready(struct bsc_msc_data *msc)
+bool a_reset_conn_ready(struct a_reset_ctx *reset)
{
- OSMO_ASSERT(msc);
- OSMO_ASSERT(msc->msc_con);
- OSMO_ASSERT(msc->msc_con->fsm_reset);
- if (msc->msc_con->fsm_reset->state == ST_CONN)
+ OSMO_ASSERT(reset);
+ OSMO_ASSERT(reset->fsm);
+
+ if (reset->fsm->state == ST_CONN)
return true;
return false;
diff --git a/openbsc/src/osmo-bsc/Makefile.am b/openbsc/src/osmo-bsc/Makefile.am
index 6aa27d2ef..a12e174da 100644
--- a/openbsc/src/osmo-bsc/Makefile.am
+++ b/openbsc/src/osmo-bsc/Makefile.am
@@ -31,7 +31,6 @@ osmo_bsc_SOURCES = \
osmo_bsc_api.c \
osmo_bsc_grace.c \
osmo_bsc_msc.c \
- osmo_bsc_reset.c \
osmo_bsc_sigtran.c \
osmo_bsc_filter.c \
osmo_bsc_bssap.c \
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
index 739f93c05..f08811498 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
@@ -31,7 +31,7 @@
#include <osmocom/gsm/gsm0808.h>
#include <osmocom/gsm/gsm0808_utils.h>
#include <openbsc/osmo_bsc_sigtran.h>
-#include <openbsc/osmo_bsc_reset.h>
+#include <openbsc/a_reset.h>
#include <osmocom/core/byteswap.h>
#define IP_V4_ADDR_LEN 4
@@ -198,7 +198,7 @@ static int bssmap_handle_reset_ack(struct bsc_msc_data *msc,
/* Inform the FSM that controls the RESET/RESET-ACK procedure
* that we have successfully received the reset-ack message */
- reset_ack_confirm(msc);
+ a_reset_ack_confirm(&msc->msc_con->reset);
return 0;
}
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_sigtran.c b/openbsc/src/osmo-bsc/osmo_bsc_sigtran.c
index 10ae6c85d..7afe71ee3 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_sigtran.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_sigtran.c
@@ -31,7 +31,7 @@
#include <openbsc/osmo_bsc.h>
#include <openbsc/osmo_bsc_grace.h>
#include <openbsc/osmo_bsc_sigtran.h>
-#include <openbsc/osmo_bsc_reset.h>
+#include <openbsc/a_reset.h>
#include <openbsc/gsm_04_80.h>
/* A pointer to a list with all involved MSCs
@@ -76,7 +76,7 @@ static int pick_free_conn_id(struct bsc_msc_data *msc)
}
/* Send reset to MSC */
-void osmo_bsc_sigtran_tx_reset(struct bsc_msc_data *msc)
+static void osmo_bsc_sigtran_tx_reset(struct bsc_msc_data *msc)
{
struct msgb *msg;
LOGP(DMSC, LOGL_NOTICE, "Sending RESET to MSC No.: %i\n", msc->nr);
@@ -169,7 +169,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
/* Incoming data is a sign of a vital connection */
bsc_con = get_bsc_conn_by_conn_id(scu_prim->u.disconnect.conn_id);
if (bsc_con)
- report_conn_success(bsc_con->msc);
+ a_reset_conn_success(&bsc_con->msc->msc_con->reset);
rc = handle_data_from_msc(scu_prim->u.data.conn_id, oph->msg);
break;
@@ -189,7 +189,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
/* We might have a connectivity problem. Maybe we need to go
* through the reset procedure again? */
if (scu_prim->u.disconnect.cause == 0)
- report_conn_fail(bsc_con->msc);
+ a_reset_conn_fail(&bsc_con->msc->msc_con->reset);
rc = osmo_bsc_sigtran_del_conn(bsc_con);
}
@@ -216,7 +216,7 @@ enum bsc_con osmo_bsc_sigtran_new_conn(struct gsm_subscriber_connection *conn, s
LOGP(DMSC, LOGL_NOTICE, "Initalizing resources for new SIGTRAN connection to MSC No.: %i...\n", msc->nr);
- if (sccp_conn_ready(msc) == false) {
+ if (a_reset_conn_ready(&msc->msc_con->reset) == false) {
LOGP(DMSC, LOGL_ERROR, "MSC is not connected. Dropping.\n");
return BSC_CON_REJECT_NO_LINK;
}
@@ -261,7 +261,7 @@ int osmo_bsc_sigtran_open_conn(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
msc = conn->msc;
- if (sccp_conn_ready(msc) == false) {
+ if (a_reset_conn_ready(&msc->msc_con->reset) == false) {
LOGP(DMSC, LOGL_ERROR, "MSC is not connected. Dropping.\n");
return -EINVAL;
}
@@ -288,7 +288,7 @@ int osmo_bsc_sigtran_send(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
msc = conn->msc;
- if (sccp_conn_ready(msc) == false) {
+ if (a_reset_conn_ready(&msc->msc_con->reset) == false) {
LOGP(DMSC, LOGL_ERROR, "MSC is not connected. Dropping.\n");
return -EINVAL;
}
@@ -319,7 +319,7 @@ int osmo_bsc_sigtran_del_conn(struct osmo_bsc_sccp_con *conn)
/* This bahaviour might be caused by a bad connection. Maybe we
* will have to go through the reset procedure again */
- report_conn_fail(conn->msc);
+ a_reset_conn_fail(&conn->msc->msc_con->reset);
}
llist_del(&conn->entry);
@@ -348,20 +348,26 @@ static void bsc_notify_msc_lost(struct osmo_bsc_sccp_con *con)
}
-/* close all open connections */
-void osmo_bsc_sigtran_reset(struct bsc_msc_data *msc)
+/* Callback function: Close all open connections */
+static void osmo_bsc_sigtran_reset_cb(void *priv)
{
struct osmo_bsc_sccp_con *conn;
struct osmo_bsc_sccp_con *conn_temp;
+ struct bsc_msc_data *msc = (struct bsc_msc_data*) priv;
+ OSMO_ASSERT(msc);
+
+ /* Close all open connections */
llist_for_each_entry_safe(conn, conn_temp, &active_connections, entry) {
if (conn->conn)
gsm0808_clear(conn->conn);
bsc_notify_msc_lost(conn);
osmo_bsc_sigtran_del_conn(conn);
}
-
msc->msc_con->conn_id_counter = 0;
+
+ /* Send reset to MSC */
+ osmo_bsc_sigtran_tx_reset(msc);
}
/* Initalize osmo sigtran backhaul */
@@ -389,7 +395,10 @@ int osmo_bsc_sigtran_init(struct llist_head *mscs)
osmo_sccp_user_bind(msc->msc_con->sccp, msc_name, sccp_sap_up, SCCP_SSN_BSSAP);
/* Start MSC reset procedure */
- start_reset_fsm(msc);
+ msc->msc_con->reset.priv = msc;
+ msc->msc_con->reset.cb = osmo_bsc_sigtran_reset_cb;
+ snprintf(msc->msc_con->reset.name,sizeof(msc->msc_con->reset.name),"MSC No. %u",msc->nr);
+ a_reset_start(&msc->msc_con->reset);
}
return 0;