aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2017-06-12 17:40:01 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-06-18 17:50:09 +0200
commit738cc1106c0273a918350f495a6a746d06fc2e2a (patch)
tree2d887c4ffd9d6dbca354371875d68236f08d4d16 /openbsc/src
parent2abf6b020090788b03d0d1d9207acd62d6a6abcb (diff)
libcommon-cs: genralize a interface reset fsm
The AoIP standard also describes an MSC->BSC reset procedure. We currently do not implement it. However, the fsm that is used to issue the reset request from the bsc side is not generalized. This patch generalizes the code in order to be able to use the same code on the MSC side to perform a reset procedure from there.
Diffstat (limited to 'openbsc/src')
-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
5 files changed, 68 insertions, 63 deletions
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;