[PATCH 4/4] Add function to update TRAU muxer after assignment or handover

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Andreas Eversberg jolly at eversberg.eu
Thu Dec 5 15:02:39 UTC 2013


From: Andreas Eversberg <andreas at eversberg.eu>

E1 based BTS use TRAU muxer to decode TRAU frames. After changing
channel from one timeslot to another (due to handover or assignment),
the TRAU muxer must be updated. The call reference of the call is
disconnected from the old channel and connected to the new channel.
---
 openbsc/include/openbsc/gsm_data.h  |   14 ++++++++++++++
 openbsc/include/openbsc/trau_mux.h  |    3 +++
 openbsc/src/libbsc/bsc_api.c        |    5 +++++
 openbsc/src/libbsc/handover_logic.c |    7 +++++--
 openbsc/src/libmsc/gsm_04_08.c      |   12 +++++++++---
 openbsc/src/libtrau/trau_mux.c      |   18 ++++++++++++++++++
 6 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 7c3ca84..41fe328 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -382,6 +382,20 @@ static inline int is_nokia_bts(struct gsm_bts *bts)
 	return 0;
 }
 
+static inline int is_e1_bts(struct gsm_bts *bts)
+{
+	switch (bts->type) {
+	case GSM_BTS_TYPE_BS11:
+	case GSM_BTS_TYPE_RBS2000:
+	case GSM_BTS_TYPE_NOKIA_SITE:
+		return 1;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 enum gsm_auth_policy gsm_auth_policy_parse(const char *arg);
 const char *gsm_auth_policy_name(enum gsm_auth_policy policy);
 
diff --git a/openbsc/include/openbsc/trau_mux.h b/openbsc/include/openbsc/trau_mux.h
index 2c01b06..667f623 100644
--- a/openbsc/include/openbsc/trau_mux.h
+++ b/openbsc/include/openbsc/trau_mux.h
@@ -51,5 +51,8 @@ int trau_recv_lchan(struct gsm_lchan *lchan, uint32_t callref);
 /* send trau from application */
 int trau_send_frame(struct gsm_lchan *lchan, struct gsm_data_frame *frame);
 
+/* switch trau muxer to new lchan */
+int switch_trau_mux(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan);
+
 /* callback invoked if we receive TRAU frames */
 int subch_cb(struct subch_demux *dmx, int ch, uint8_t *data, int len, void *_priv);
diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c
index 86d2493..e567038 100644
--- a/openbsc/src/libbsc/bsc_api.c
+++ b/openbsc/src/libbsc/bsc_api.c
@@ -31,6 +31,7 @@
 #include <openbsc/handover.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_04_08.h>
+#include <openbsc/trau_mux.h>
 
 #include <osmocom/gsm/protocol/gsm_08_08.h>
 
@@ -419,6 +420,10 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn,
 		return;
 	}
 
+	/* switch TRAU muxer for E1 based BTS from one channel to another */
+	if (is_e1_bts(conn->bts))
+		switch_trau_mux(conn->lchan, conn->secondary_lchan);
+
 	/* swap channels */
 	osmo_timer_del(&conn->T10);
 
diff --git a/openbsc/src/libbsc/handover_logic.c b/openbsc/src/libbsc/handover_logic.c
index 9cf26af..36a758b 100644
--- a/openbsc/src/libbsc/handover_logic.c
+++ b/openbsc/src/libbsc/handover_logic.c
@@ -39,6 +39,7 @@
 #include <openbsc/signal.h>
 #include <osmocom/core/talloc.h>
 #include <openbsc/transaction.h>
+#include <openbsc/trau_mux.h>
 
 struct bsc_handover {
 	struct llist_head list;
@@ -264,6 +265,10 @@ static int ho_gsm48_ho_compl(struct gsm_lchan *new_lchan)
 
 	osmo_timer_del(&ho->T3103);
 
+	/* switch TRAU muxer for E1 based BTS from one channel to another */
+	if (is_e1_bts(new_lchan->conn->bts))
+		switch_trau_mux(ho->old_lchan, new_lchan);
+
 	/* Replace the ho lchan with the primary one */
 	if (ho->old_lchan != new_lchan->conn->lchan)
 		LOGP(DHO, LOGL_ERROR, "Primary lchan changed during handover.\n");
@@ -278,8 +283,6 @@ static int ho_gsm48_ho_compl(struct gsm_lchan *new_lchan)
 	rsl_lchan_set_state(ho->old_lchan, LCHAN_S_INACTIVE);
 	lchan_release(ho->old_lchan, 0, RSL_REL_LOCAL_END);
 
-	/* do something to re-route the actual speech frames ! */
-
 	llist_del(&ho->list);
 	talloc_free(ho);
 
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 775fe66..4dedd67 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -1612,6 +1612,9 @@ static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable)
 	lchan = trans->conn->lchan;
 	bts = lchan->ts->trx->bts;
 
+	/* store receive state */
+	trans->tch_recv = enable;
+
 	switch (bts->type) {
 	case GSM_BTS_TYPE_NANOBTS:
 	case GSM_BTS_TYPE_OSMO_SYSMO:
@@ -1619,10 +1622,8 @@ static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable)
 			LOGP(DCC, LOGL_ERROR, "Error: RTP proxy is disabled\n");
 			return -EINVAL;
 		}
-		/* in case, we don't have a RTP socket yet, we note this
-		 * in the transaction and try later */
+		/* in case, we don't have a RTP socket yet, we try later */
 		if (!lchan->abis_ip.rtp_socket) {
-			trans->tch_recv = enable;
 			DEBUGP(DCC, "queue tch_recv_mncc request (%d)\n", enable);
 			return 0;
 		}
@@ -1641,6 +1642,11 @@ static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable)
 	case GSM_BTS_TYPE_BS11:
 	case GSM_BTS_TYPE_RBS2000:
 	case GSM_BTS_TYPE_NOKIA_SITE:
+		/* in case we don't have a TCH with correct mode, we try later */
+		if (lchan->tch_mode == GSM48_CMODE_SIGN) {
+			DEBUGP(DCC, "queue tch_recv_mncc request (%d)\n", enable);
+			return 0;
+		}
 		if (enable)
 			return trau_recv_lchan(lchan, callref);
 		return trau_mux_unmap(NULL, callref);
diff --git a/openbsc/src/libtrau/trau_mux.c b/openbsc/src/libtrau/trau_mux.c
index 9272ac0..d25e78f 100644
--- a/openbsc/src/libtrau/trau_mux.c
+++ b/openbsc/src/libtrau/trau_mux.c
@@ -30,6 +30,7 @@
 #include <openbsc/debug.h>
 #include <osmocom/core/talloc.h>
 #include <openbsc/trau_upqueue.h>
+#include <openbsc/transaction.h>
 
 /* this corresponds to the bit-lengths of the individual codec
  * parameters as indicated in Table 1.1 of TS 06.10 */
@@ -327,3 +328,20 @@ int trau_send_frame(struct gsm_lchan *lchan, struct gsm_data_frame *frame)
 	return subchan_mux_enqueue(mx, dst_e1_ss->e1_ts_ss, trau_bits_out,
 				   TRAU_FRAME_BITS);
 }
+
+/* switch trau muxer to new lchan */
+int switch_trau_mux(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan)
+{
+	struct gsm_network *net = old_lchan->ts->trx->bts->network;
+	struct gsm_trans *trans;
+
+	/* look up transaction with TCH frame receive enabled */
+	llist_for_each_entry(trans, &net->trans_list, entry) {
+		if (trans->conn && trans->conn->lchan == old_lchan && trans->tch_recv) {
+			/* switch */
+			trau_recv_lchan(new_lchan, trans->callref);
+		}
+	}
+
+	return 0;
+}
-- 
1.7.3.4





More information about the OpenBSC mailing list