diff options
-rw-r--r-- | include/osmocom/bsc/gsm_08_08.h | 2 | ||||
-rw-r--r-- | src/osmo-bsc/gsm_04_08_rr.c | 16 | ||||
-rw-r--r-- | src/osmo-bsc/gsm_08_08.c | 18 | ||||
-rw-r--r-- | tests/bsc/bsc_test.c | 2 | ||||
-rw-r--r-- | tests/gsm0408/gsm0408_test.c | 4 | ||||
-rw-r--r-- | tests/handover/handover_test.c | 2 |
6 files changed, 23 insertions, 21 deletions
diff --git a/include/osmocom/bsc/gsm_08_08.h b/include/osmocom/bsc/gsm_08_08.h index 80da297a3..da5e2f1ac 100644 --- a/include/osmocom/bsc/gsm_08_08.h +++ b/include/osmocom/bsc/gsm_08_08.h @@ -8,7 +8,7 @@ struct gsm_subscriber_connection; void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, uint8_t dlci, enum gsm0808_cause cause); void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_encr); -int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg, uint16_t chosen_channel); +int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel); void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg); void bsc_cm_update(struct gsm_subscriber_connection *conn, const uint8_t *cm2, uint8_t cm2_len, diff --git a/src/osmo-bsc/gsm_04_08_rr.c b/src/osmo-bsc/gsm_04_08_rr.c index a7bba0d4e..49ec84860 100644 --- a/src/osmo-bsc/gsm_04_08_rr.c +++ b/src/osmo-bsc/gsm_04_08_rr.c @@ -1015,7 +1015,6 @@ static void dispatch_dtap(struct gsm_subscriber_connection *conn, int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id) { struct gsm_lchan *lchan; - int rc; lchan = msg->lchan; if (!lchan_may_receive_data(lchan)) { @@ -1028,21 +1027,8 @@ int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id) * MSC */ dispatch_dtap(lchan->conn, link_id, msg); } else { - /* allocate a new connection */ - lchan->conn = bsc_subscr_con_allocate(msg->lchan->ts->trx->bts->network); - if (!lchan->conn) { - lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL); - return -1; - } - lchan->conn->lchan = lchan; - /* fwd via bsc_api to send COMPLETE L3 INFO to MSC */ - rc = bsc_compl_l3(lchan->conn, msg, 0); - if (rc < 0) { - osmo_fsm_inst_dispatch(lchan->conn->fi, GSCON_EV_A_DISC_IND, NULL); - return rc; - } - /* conn shall release lchan on teardown, also if this Layer 3 Complete is rejected. */ + return bsc_compl_l3(lchan, msg, 0); } return 0; diff --git a/src/osmo-bsc/gsm_08_08.c b/src/osmo-bsc/gsm_08_08.c index 9d22e3f41..f290a48e4 100644 --- a/src/osmo-bsc/gsm_08_08.c +++ b/src/osmo-bsc/gsm_08_08.c @@ -25,6 +25,7 @@ #include <osmocom/bsc/paging.h> #include <osmocom/bsc/gsm_08_08.h> #include <osmocom/bsc/codec_pref.h> +#include <osmocom/bsc/lchan_fsm.h> #include <osmocom/bsc/gsm_04_08_rr.h> #include <osmocom/bsc/a_reset.h> @@ -428,8 +429,9 @@ static void parse_powercap(struct gsm_subscriber_connection *conn, struct msgb * } /*! MS->MSC: New MM context with L3 payload. */ -int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg, uint16_t chosen_channel) +int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel) { + struct gsm_subscriber_connection *conn; struct bsc_msc_data *msc; struct msgb *create_l3; struct gsm0808_speech_codec_list scl; @@ -440,6 +442,7 @@ int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg, uint1 struct osmo_mobile_identity mi; struct gsm48_hdr *gh; uint8_t pdisc, mtype; + bool release_lchan = true; if (msgb_l3len(msg) < sizeof(*gh)) { LOGP(DRSL, LOGL_ERROR, "There is no GSM48 header here.\n"); @@ -461,6 +464,15 @@ int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg, uint1 */ } + /* allocate a new connection */ + conn = bsc_subscr_con_allocate(bsc_gsmnet); + if (!conn) { + LOG_COMPL_L3(pdisc, mtype, LOGL_ERROR, "Failed to allocate conn\n"); + goto early_fail; + } + gscon_change_primary_lchan(conn, lchan); + gscon_update_id(conn); + log_set_context(LOG_CTX_BSC_SUBSCR, conn->bsub); /* find the MSC link we want to use */ @@ -511,8 +523,12 @@ int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg, uint1 goto early_fail; } rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_CONN_REQ, create_l3); + if (!rc) + release_lchan = false; early_fail: + if (release_lchan) + lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL); log_set_context(LOG_CTX_BSC_SUBSCR, NULL); return rc; } diff --git a/tests/bsc/bsc_test.c b/tests/bsc/bsc_test.c index d9996081e..6a6ff8bac 100644 --- a/tests/bsc/bsc_test.c +++ b/tests/bsc/bsc_test.c @@ -225,7 +225,7 @@ struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *ne void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, uint8_t dlci, enum gsm0808_cause cause) {} void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_encr) {} -int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg, uint16_t chosen_channel) +int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel) { return 0; } void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) {} void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_cause) {} diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c index 35531f81a..8ee29f70b 100644 --- a/tests/gsm0408/gsm0408_test.c +++ b/tests/gsm0408/gsm0408_test.c @@ -952,8 +952,8 @@ void gscon_submit_rsl_dtap(struct gsm_subscriber_connection *conn, bool lchan_may_receive_data(struct gsm_lchan *lchan) { return true; } -int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg, - uint16_t chosen_channel) { return 0; } +int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel) +{ return 0; } void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) {} diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c index 78e8daf96..ba0ec21b9 100644 --- a/tests/handover/handover_test.c +++ b/tests/handover/handover_test.c @@ -1796,7 +1796,7 @@ int osmo_bsc_sigtran_send(struct gsm_subscriber_connection *conn, struct msgb *m int osmo_bsc_sigtran_open_conn(struct gsm_subscriber_connection *conn, struct msgb *msg) { return 0; } void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, uint8_t dlci, enum gsm0808_cause cause) {} void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_encr) {} -int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg, uint16_t chosen_channel) +int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel) { return 0; } void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) {} void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_cause) {} |