diff options
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/include/openbsc/signal.h | 1 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_bssap.c | 43 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_sccp.c | 11 |
3 files changed, 53 insertions, 2 deletions
diff --git a/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h index 39319f1c9..6a365c5e7 100644 --- a/openbsc/include/openbsc/signal.h +++ b/openbsc/include/openbsc/signal.h @@ -220,6 +220,7 @@ enum signal_msc { S_MSC_LOST, S_MSC_CONNECTED, S_MSC_AUTHENTICATED, + S_MSC_RESET }; struct osmo_msc_data; diff --git a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c index c2c241732..4849e7491 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c @@ -25,6 +25,9 @@ #include <openbsc/gsm_subscriber.h> #include <openbsc/mgcp.h> #include <openbsc/paging.h> +#include <openbsc/signal.h> + +#include <osmocom/sccp/sccp.h> #include <osmocom/gsm/protocol/gsm_08_08.h> #include <osmocom/gsm/gsm0808.h> @@ -98,6 +101,43 @@ enum gsm48_chan_mode gsm88_to_chan_mode(enum gsm0808_permitted_speech speech) return GSM48_CMODE_SPEECH_AMR; } +static int bssmap_send_reset_ack(struct osmo_msc_data *msc) +{ + struct msgb *msg; + + msg = gsm0808_create_reset_ack(); + if (!msg) { + LOGP(DMSC, LOGL_ERROR, "Sending RESET_ACK failed.\n"); + return -1; + } + + sccp_write(msg, &sccp_ssn_bssap, &sccp_ssn_bssap, 0, msc->msc_con); + msgb_free(msg); + return 0; +} + + +/* GSM 08.08 / 3.2.1.23 */ + +static int bssmap_handle_reset(struct osmo_msc_data *msc, + struct msgb *msg, unsigned int length) +{ + struct msc_signal_data sig; + struct osmo_msc_data *data; + + LOGP(DMSC, LOGL_NOTICE, "RESET from MSC\n"); + + /* send a SC_MSC_RESET signal which will be picked up by + * osmo_bsc_sccp.c:handle_msc_signal() */ + data = (struct osmo_msc_data *) msc->msc_con->write_queue.bfd.data; + sig.data = data; + osmo_signal_dispatch(SS_MSC, S_MSC_RESET, &sig); + + /* FIXME: schedule timer T13/T16? and send RESET_ACK */ + bssmap_send_reset_ack(msc); + return 0; +} + static int bssmap_handle_reset_ack(struct osmo_msc_data *msc, struct msgb *msg, unsigned int length) { @@ -412,6 +452,9 @@ static int bssmap_rcvmsg_udt(struct osmo_msc_data *msc, case BSS_MAP_MSG_RESET_ACKNOWLEDGE: ret = bssmap_handle_reset_ack(msc, msg, length); break; + case BSS_MAP_MSG_RESET: + ret = bssmap_handle_reset(msc, msg, length); + break; case BSS_MAP_MSG_PAGING: ret = bssmap_handle_paging(msc, msg, length); break; diff --git a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c index 3533d6df0..e3d3e2ea4 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c @@ -133,7 +133,8 @@ static void sccp_cc_timeout(void *_data) if (data->sccp->connection_state >= SCCP_CONNECTION_STATE_ESTABLISHED) return; - LOGP(DMSC, LOGL_ERROR, "The connection was never established.\n"); + LOGP(DMSC, LOGL_ERROR, "The connection was never established\ + (No SCCP CC from MSC).\n"); bsc_sccp_force_free(data); } @@ -281,8 +282,14 @@ static int handle_msc_signal(unsigned int subsys, unsigned int signal, return 0; msc = signal_data; - if (signal == S_MSC_LOST) + switch (signal) { + case S_MSC_LOST: + case S_MSC_RESET: bsc_close_connections(msc->data->msc_con); + break; + default: + break; + } return 0; } |