From 14c3e7436979cf3513e1e7cbf1cfb7dae99d0cd5 Mon Sep 17 00:00:00 2001 From: Philipp Maier Date: Mon, 29 Jan 2018 18:38:49 +0100 Subject: WIP: GSCON: Complete GSCON implementation (bsc_subscr_conn_fsm.c) - Remove old osmo_bsc_mgcp.c code - Use the fsm based MGW client API to handle MGCP - Integrate some error handling - Ensure that signalling, data and voice channels are distinguished - Make internal handover work again Closes: OS#2823 Closes: OS#2768 Closes: OS#2898 Change-Id: I42da6ce3bef95d7a1743c39c5640db5739333a61 --- src/osmo-bsc/osmo_bsc_api.c | 86 +++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 35 deletions(-) (limited to 'src/osmo-bsc/osmo_bsc_api.c') 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 -#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, -- cgit v1.2.3