From 61692adb2b0cd090c8fb8c81376a28bca099d079 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Fri, 20 May 2016 21:59:55 +0200 Subject: Implement IuCS (large refactoring and addition) osmo-nitb becomes osmo-msc add DIUCS debug log constant add iucs.[hc] add msc vty, remove nitb vty add libiudummy, to avoid linking Iu deps in tests Use new msc_tx_dtap() instead of gsm0808_submit_dtap() libmgcp: add mgcpgw client API bridge calls via mgcpgw mgcp: hack RAB success from nano3G: patch first RTP payload The ip.access nano3G needs the first RTP payload's first two bytes to read hex 'e400', or it will reject the RAB assignment. Add flag patched_first_rtp_payload to mgcp_rtp_state to detect the first RTP payload on a stream, and overwrite its first bytes with e400. This should probably be configurable, but seems to not harm other femto cells (as long as we patch only the first RTP payload in each stream). Only do this when sending to the BTS side. Change-Id: Ie13ff348117e892d41b8355ab6c24915301eaeaf --- openbsc/src/libmsc/osmo_msc.c | 72 +++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 44 deletions(-) (limited to 'openbsc/src/libmsc/osmo_msc.c') diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c index ab53b0be7..bfe5343cf 100644 --- a/openbsc/src/libmsc/osmo_msc.c +++ b/openbsc/src/libmsc/osmo_msc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -40,24 +41,6 @@ static void msc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci) gsm411_sapi_n_reject(conn); } -static bool keep_conn(struct gsm_subscriber_connection *conn) -{ - /* TODO: what about a silent call? */ - - if (!conn->conn_fsm) { - DEBUGP(DMM, "No conn_fsm, release conn\n"); - return false; - } - - switch (conn->conn_fsm->state) { - case SUBSCR_CONN_S_NEW: - case SUBSCR_CONN_S_ACCEPTED: - return true; - default: - return false; - } -} - static void subscr_conn_bump(struct gsm_subscriber_connection *conn) { if (!conn) @@ -65,39 +48,32 @@ static void subscr_conn_bump(struct gsm_subscriber_connection *conn) if (!conn->conn_fsm) return; if (!(conn->conn_fsm->state == SUBSCR_CONN_S_ACCEPTED - || conn->conn_fsm->state == SUBSCR_CONN_S_COMMUNICATING)) + || conn->conn_fsm->state == SUBSCR_CONN_S_COMMUNICATING)) { + DEBUGP(DMM, "%s: bump: conn still being established (%s)\n", + vlr_subscr_name(conn->vsub), + osmo_fsm_inst_state_name(conn->conn_fsm)); return; + } osmo_fsm_inst_dispatch(conn->conn_fsm, SUBSCR_CONN_E_BUMP, NULL); } /* receive a Level 3 Complete message and return MSC_CONN_ACCEPT or * MSC_CONN_REJECT */ -enum msc_compl_l3_rc msc_compl_l3(struct gsm_subscriber_connection *conn, - struct msgb *msg, uint16_t chosen_channel) +int msc_compl_l3(struct gsm_subscriber_connection *conn, + struct msgb *msg, uint16_t chosen_channel) { - /* Ownership of the gsm_subscriber_connection is still a bit mucky - * between libbsc and libmsc. In libmsc, we use ref counting, but not - * in libbsc. This will become simpler with the MSCSPLIT. */ - - /* reserve for the duration of this function */ msc_subscr_conn_get(conn); - gsm0408_dispatch(conn, msg); - if (!keep_conn(conn)) { - DEBUGP(DMM, "compl_l3: Discarding conn\n"); - /* keep the use_count reserved, libbsc will discard. If we - * released the ref count and discarded here, libbsc would - * double-free. And we will not change bsc_api semantics. */ - return MSC_CONN_REJECT; - } - DEBUGP(DMM, "compl_l3: Keeping conn\n"); - /* Bump whether the conn wants to be closed */ subscr_conn_bump(conn); /* If this should be kept, the conn->conn_fsm has placed a use_count */ msc_subscr_conn_put(conn); + + /* Always return acceptance, because even if the conn was not accepted, + * we assumed ownership of it and the caller shall not interfere with + * that. We may even already have discarded the conn. */ return MSC_CONN_ACCEPT; #if 0 @@ -119,7 +95,7 @@ enum msc_compl_l3_rc msc_compl_l3(struct gsm_subscriber_connection *conn, } /* Receive a DTAP message from BSC */ -static void msc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) +void msc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) { msc_subscr_conn_get(conn); gsm0408_dispatch(conn, msg); @@ -158,8 +134,8 @@ static void msc_classmark_chg(struct gsm_subscriber_connection *conn, } /* Receive a CIPHERING MODE COMPLETE from BSC */ -static void msc_ciph_m_compl(struct gsm_subscriber_connection *conn, - struct msgb *msg, uint8_t alg_id) +void msc_cipher_mode_compl(struct gsm_subscriber_connection *conn, + struct msgb *msg, uint8_t alg_id) { struct gsm48_hdr *gh = msgb_l3(msg); unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); @@ -277,7 +253,7 @@ static struct bsc_api msc_handler = { .assign_compl = msc_assign_compl, .assign_fail = msc_assign_fail, .classmark_chg = msc_classmark_chg, - .cipher_mode_compl = msc_ciph_m_compl, + .cipher_mode_compl = msc_cipher_mode_compl, .conn_cleanup = msc_subscr_con_cleanup, }; @@ -285,6 +261,10 @@ struct bsc_api *msc_bsc_api() { return &msc_handler; } +/* Signal the connection's FSM to gracefully terminate the connection by a + * SUBSCR_CONN_E_CN_CLOSE event. + * \param cause a GSM_CAUSE_* constant, e.g. GSM_CAUSE_AUTH_FAILED. + */ void msc_subscr_conn_close(struct gsm_subscriber_connection *conn, uint32_t cause) { @@ -335,8 +315,12 @@ void _msc_subscr_conn_put(struct gsm_subscriber_connection *conn, "%s: MSC conn use - 1 == %u\n", vlr_subscr_name(conn->vsub), conn->use_count); - if (conn->use_count == 0) { - gsm0808_clear(conn); - bsc_subscr_con_free(conn); - } + if (conn->use_count == 0) + msc_subscr_con_free(conn); +} + +void msc_stop_paging(struct vlr_subscr *vsub) +{ + DEBUGP(DPAG, "Paging can stop for %s\n", vlr_subscr_name(vsub)); + /* tell BSCs and RNCs to stop paging? How? */ } -- cgit v1.2.3