diff options
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/include/openbsc/Makefile.am | 2 | ||||
-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.h | 4 | ||||
-rw-r--r-- | openbsc/include/openbsc/osmo_bsc_sigtran.h | 6 | ||||
-rw-r--r-- | openbsc/src/libcommon-cs/Makefile.am | 1 | ||||
-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.am | 1 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_bssap.c | 4 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_sigtran.c | 33 |
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; |