aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc/gsm_08_08.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osmo-bsc/gsm_08_08.c')
-rw-r--r--src/osmo-bsc/gsm_08_08.c18
1 files changed, 17 insertions, 1 deletions
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;
}