aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc/osmo_bsc_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osmo-bsc/osmo_bsc_api.c')
-rw-r--r--src/osmo-bsc/osmo_bsc_api.c86
1 files changed, 51 insertions, 35 deletions
diff --git a/src/osmo-bsc/osmo_bsc_api.c b/src/osmo-bsc/osmo_bsc_api.c
index d48398f49..ef20c247e 100644
--- a/src/osmo-bsc/osmo_bsc_api.c
+++ b/src/osmo-bsc/osmo_bsc_api.c
@@ -32,24 +32,23 @@
#include <osmocom/bsc/osmo_bsc_sigtran.h>
-#define return_when_not_connected(conn) \
- if (conn->sccp.state != SUBSCR_SCCP_ST_CONNECTED) {\
- LOGP(DMSC, LOGL_ERROR, "MSC Connection not present.\n"); \
- return; \
- }
+/* Check if we have a proper connection to the MSC */
+static bool msc_connected(struct gsm_subscriber_connection *conn)
+{
+ /* No subscriber conn at all */
+ if (!conn)
+ return false;
-#define return_when_not_connected_val(conn, ret) \
- if (conn->sccp.state != SUBSCR_SCCP_ST_CONNECTED) {\
- LOGP(DMSC, LOGL_ERROR, "MSC Connection not present.\n"); \
- return ret; \
- }
+ /* Connection to MSC not established */
+ if (!conn->sccp.msc)
+ return false;
-#define queue_msg_or_return(resp) \
- if (!resp) { \
- LOGP(DMSC, LOGL_ERROR, "Failed to allocate response.\n"); \
- return; \
- } \
- osmo_bsc_sigtran_send(conn, resp);
+ /* Reset procedure not (yet) executed */
+ if (a_reset_conn_ready(conn->sccp.msc->a.reset) == false)
+ return false;
+
+ return true;
+}
static int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause);
static int complete_layer3(struct gsm_subscriber_connection *conn,
@@ -149,24 +148,33 @@ static int bsc_filter_data(struct gsm_subscriber_connection *conn,
static void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci)
{
+ int rc;
struct msgb *resp;
- return_when_not_connected(conn);
+ if (!msc_connected(conn))
+ return;
+
LOGP(DMSC, LOGL_NOTICE, "Tx MSC SAPI N REJECT DLCI=0x%02x\n", dlci);
-
resp = gsm0808_create_sapi_reject(dlci);
- queue_msg_or_return(resp);
+ rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp);
+ if (rc != 0)
+ msgb_free(resp);
}
static void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn,
struct msgb *msg, uint8_t chosen_encr)
{
+ int rc;
struct msgb *resp;
- return_when_not_connected(conn);
+ if (!msc_connected(conn))
+ return;
+
LOGP(DMSC, LOGL_DEBUG, "CIPHER MODE COMPLETE from MS, forwarding to MSC\n");
resp = gsm0808_create_cipher_complete(msg, chosen_encr);
- queue_msg_or_return(resp);
+ rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp);
+ if (rc != 0)
+ msgb_free(resp);
}
static void bsc_send_ussd_no_srv(struct gsm_subscriber_connection *conn,
@@ -394,7 +402,9 @@ static int handle_cc_setup(struct gsm_subscriber_connection *conn,
static void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg)
{
int lu_cause;
- return_when_not_connected(conn);
+
+ if (!msc_connected(conn))
+ return;
LOGP(DMSC, LOGL_INFO, "Tx MSC DTAP LINK_ID=0x%02x\n", link_id);
@@ -425,8 +435,9 @@ static void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_
uint8_t chosen_channel, uint8_t encr_alg_id,
uint8_t speech_model)
{
- return_when_not_connected(conn);
-
+ if (!msc_connected(conn))
+ return;
+
conn->lchan->abis_ip.ass_compl.rr_cause = rr_cause;
conn->lchan->abis_ip.ass_compl.chosen_channel = chosen_channel;
conn->lchan->abis_ip.ass_compl.encr_alg_id = encr_alg_id;
@@ -453,20 +464,18 @@ static void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_
static void bsc_assign_fail(struct gsm_subscriber_connection *conn,
uint8_t cause, uint8_t *rr_cause)
{
- struct msgb *resp;
- return_when_not_connected(conn);
-
LOGP(DMSC, LOGL_INFO, "Tx MSC ASSIGN FAIL\n");
-
- resp = gsm0808_create_assignment_failure(cause, rr_cause);
- queue_msg_or_return(resp);
+ osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_RR_ASS_FAIL, NULL);
}
static int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
{
+ int rc;
struct msgb *resp;
- return_when_not_connected_val(conn, 1);
+ if (!msc_connected(conn))
+ return 1;
+
LOGP(DMSC, LOGL_INFO, "Tx MSC CLEAR REQUEST\n");
resp = gsm0808_create_clear_rqst(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE);
@@ -475,7 +484,10 @@ static int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t ca
return 1;
}
- osmo_bsc_sigtran_send(conn, resp);
+ rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp);
+ if (rc != 0)
+ msgb_free(resp);
+
return 1;
}
@@ -483,12 +495,16 @@ static void bsc_cm_update(struct gsm_subscriber_connection *conn,
const uint8_t *cm2, uint8_t cm2_len,
const uint8_t *cm3, uint8_t cm3_len)
{
+ int rc;
struct msgb *resp;
- return_when_not_connected(conn);
+ if (!msc_connected(conn))
+ return;
+
resp = gsm0808_create_classmark_update(cm2, cm2_len, cm3, cm3_len);
-
- queue_msg_or_return(resp);
+ rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp);
+ if (rc != 0)
+ msgb_free(resp);
}
static void bsc_mr_config(struct gsm_subscriber_connection *conn,