diff -Nur openbsc.10_debug/include/openbsc/gsm_data.h openbsc.11_trau/include/openbsc/gsm_data.h
--- openbsc.10_debug/include/openbsc/gsm_data.h	2009-05-21 09:35:56.000000000 +0200
+++ openbsc.11_trau/include/openbsc/gsm_data.h	2009-05-21 10:26:00.000000000 +0200
@@ -139,8 +139,10 @@
 	struct gsm_bts_trx_ts *ts;
 	/* The logical subslot number in the TS */
 	u_int8_t nr;
-	/* The lotical channel type */
+	/* The logical channel type */
 	enum gsm_chan_t type;
+	/* The traffic */
+	enum gsm_chan_t tch_mode;
 	/* Power levels for MS and BTS */
 	u_int8_t bs_power;
 	u_int8_t ms_power;
diff -Nur openbsc.10_debug/include/openbsc/trau_mux.h openbsc.11_trau/include/openbsc/trau_mux.h
--- openbsc.10_debug/include/openbsc/trau_mux.h	2009-05-21 07:20:43.000000000 +0200
+++ openbsc.11_trau/include/openbsc/trau_mux.h	2009-05-21 10:23:32.000000000 +0200
@@ -36,8 +36,14 @@
 			const struct gsm_lchan *dst);
 
 /* unmap a TRAU mux map entry */
-int trau_mux_unmap(const struct gsm_e1_subslot *ss);
+int trau_mux_unmap(const struct gsm_e1_subslot *ss, u_int32_t callref);
 
 /* we get called by subchan_demux */
 int trau_mux_input(struct gsm_e1_subslot *src_e1_ss,
 		   const u_int8_t *trau_bits, int num_bits);
+
+/* add a trau receiver */
+int trau_recv_lchan(struct gsm_lchan *lchan, u_int32_t callref);
+
+/* send trau from application */
+int trau_send_lchan(struct gsm_lchan *lchan, struct decoded_trau_frame *tf);
diff -Nur openbsc.10_debug/src/abis_rsl.c openbsc.11_trau/src/abis_rsl.c
--- openbsc.10_debug/src/abis_rsl.c	2009-05-21 09:43:41.000000000 +0200
+++ openbsc.11_trau/src/abis_rsl.c	2009-05-21 10:23:32.000000000 +0200
@@ -475,10 +475,21 @@
 	/* FIXME: what to do with data calls ? */
 	cm.dtx_dtu = 0x00;
 	switch (lchan->type) {
+	// todo more modes
 	case GSM_LCHAN_TCH_F:
 		cm.spd_ind = RSL_CMOD_SPD_SPEECH;
 		cm.chan_rt = RSL_CMOD_CRT_TCH_Bm;
-		cm.chan_rate = RSL_CMOD_SP_GSM2;
+		switch(lchan->tch_mode) {
+		case GSM48_CMODE_SPEECH_V1:
+			cm.chan_rate = RSL_CMOD_SP_GSM1;
+			break;
+		case GSM48_CMODE_SPEECH_EFR:
+			cm.chan_rate = RSL_CMOD_SP_GSM2;
+			break;
+		default:
+			DEBUGP(DRSL, "Unimplemented channel modification\n");
+			return -1;
+		}
 		break;
 	default:
 		DEBUGP(DRSL, "Unimplemented channel modification\n");
diff -Nur openbsc.10_debug/src/e1_config.c openbsc.11_trau/src/e1_config.c
--- openbsc.10_debug/src/e1_config.c	2009-05-21 07:20:44.000000000 +0200
+++ openbsc.11_trau/src/e1_config.c	2009-05-21 10:36:44.000000000 +0200
@@ -5,6 +5,7 @@
 
 #include <openbsc/gsm_data.h>
 #include <openbsc/e1_input.h>
+#include <openbsc/trau_frame.h>
 #include <openbsc/trau_mux.h>
 #include <openbsc/misdn.h>
 
diff -Nur openbsc.10_debug/src/e1_input.c openbsc.11_trau/src/e1_input.c
--- openbsc.10_debug/src/e1_input.c	2009-05-21 08:47:45.000000000 +0200
+++ openbsc.11_trau/src/e1_input.c	2009-05-21 10:37:23.000000000 +0200
@@ -42,6 +42,7 @@
 #include <openbsc/abis_rsl.h>
 #include <openbsc/linuxlist.h>
 #include <openbsc/subchan_demux.h>
+#include <openbsc/trau_frame.h>
 #include <openbsc/trau_mux.h>
 
 #define NUM_E1_TS	32
diff -Nur openbsc.10_debug/src/gsm_04_08.c openbsc.11_trau/src/gsm_04_08.c
--- openbsc.10_debug/src/gsm_04_08.c	2009-05-21 09:47:20.000000000 +0200
+++ openbsc.11_trau/src/gsm_04_08.c	2009-05-21 10:30:56.000000000 +0200
@@ -42,6 +42,7 @@
 #include <openbsc/chan_alloc.h>
 #include <openbsc/paging.h>
 #include <openbsc/signal.h>
+#include <openbsc/trau_frame.h>
 #include <openbsc/trau_mux.h>
 
 #define GSM48_ALLOC_SIZE	1024
@@ -635,6 +636,7 @@
 
 	DEBUGP(DRR, "-> CHANNEL MODE MODIFY mode=0x%02x\n", mode);
 
+	lchan->tch_mode = mode;
 	msg->lchan = lchan;
 	gh->proto_discr = GSM48_PDISC_RR;
 	gh->msg_type = GSM48_MT_RR_CHAN_MODE_MODIF;
diff -Nur openbsc.10_debug/src/trau_mux.c openbsc.11_trau/src/trau_mux.c
--- openbsc.10_debug/src/trau_mux.c	2009-05-21 07:20:44.000000000 +0200
+++ openbsc.11_trau/src/trau_mux.c	2009-05-21 10:36:59.000000000 +0200
@@ -36,7 +36,15 @@
 	struct gsm_e1_subslot src, dst;
 };
 
+struct upqueue_entry {
+	struct llist_head list;
+	struct gsm_network *net;
+	struct gsm_e1_subslot src;
+	u_int32_t callref;
+};
+
 static LLIST_HEAD(ss_map);
+static LLIST_HEAD(ss_upqueue);
 
 /* map one particular subslot to another subslot */
 int trau_mux_map(const struct gsm_e1_subslot *src,
@@ -52,8 +60,8 @@
 		dst->e1_nr, dst->e1_ts, dst->e1_ts_ss);
 
 	/* make sure to get rid of any stale old mappings */
-	trau_mux_unmap(src);
-	trau_mux_unmap(dst);
+	trau_mux_unmap(src, 0);
+	trau_mux_unmap(dst, 0);
 
 	memcpy(&me->src, src, sizeof(me->src));
 	memcpy(&me->dst, dst, sizeof(me->dst));
@@ -75,14 +83,26 @@
 
 
 /* unmap one particular subslot from another subslot */
-int trau_mux_unmap(const struct gsm_e1_subslot *ss)
+int trau_mux_unmap(const struct gsm_e1_subslot *ss, u_int32_t callref)
 {
 	struct map_entry *me, *me2;
+	struct upqueue_entry *ue, *ue2;
 
-	llist_for_each_entry_safe(me, me2, &ss_map, list) {
-		if (!memcmp(&me->src, ss, sizeof(*ss)) ||
-		    !memcmp(&me->dst, ss, sizeof(*ss))) {
-			llist_del(&me->list);
+	if (ss)
+		llist_for_each_entry_safe(me, me2, &ss_map, list) {
+			if (!memcmp(&me->src, ss, sizeof(*ss)) ||
+			    !memcmp(&me->dst, ss, sizeof(*ss))) {
+				llist_del(&me->list);
+				return 0;
+			}
+		}
+	llist_for_each_entry_safe(ue, ue2, &ss_upqueue, list) {
+		if (ue->callref == callref) {
+			llist_del(&ue->list);
+			return 0;
+		}
+		if (ss && !memcmp(&ue->src, ss, sizeof(*ss))) {
+			llist_del(&ue->list);
 			return 0;
 		}
 	}
@@ -104,6 +124,19 @@
 	return NULL;
 }
 
+/* look-up an enty in the TRAU upqueue */
+struct upqueue_entry *
+lookup_trau_upqueue(const struct gsm_e1_subslot *src)
+{
+	struct upqueue_entry *ue;
+
+	llist_for_each_entry(ue, &ss_upqueue, list) {
+		if (!memcmp(&ue->src, src, sizeof(*src)))
+			return ue;
+	}
+	return NULL;
+}
+
 /* we get called by subchan_demux */
 int trau_mux_input(struct gsm_e1_subslot *src_e1_ss,
 		   const u_int8_t *trau_bits, int num_bits)
@@ -114,6 +147,11 @@
 	struct subch_mux *mx;
 	int rc;
 
+	/* decode TRAU, change it to downlink, re-encode */
+	rc = decode_trau_frame(&tf, trau_bits);
+	if (rc)
+		return rc;
+
 	if (!dst_e1_ss)
 		return -EINVAL;
 
@@ -121,11 +159,6 @@
 	if (!mx)
 		return -EINVAL;
 
-	/* decode TRAU, change it to downlink, re-encode */
-	rc = decode_trau_frame(&tf, trau_bits);
-	if (rc)
-		return rc;
-
 	trau_frame_up2down(&tf);
 	encode_trau_frame(trau_bits_out, &tf);
 
@@ -133,3 +166,47 @@
 	return subchan_mux_enqueue(mx, dst_e1_ss->e1_ts_ss, trau_bits_out,
 				   TRAU_FRAME_BITS);
 }
+
+/* add receiver instance for lchan and callref */
+int trau_recv_lchan(struct gsm_lchan *lchan, u_int32_t callref)
+{
+	struct gsm_e1_subslot *src_ss;
+	struct upqueue_entry *ue = malloc(sizeof(*ue));
+
+	if (!ue)
+		return -ENOMEM;
+
+	src_ss = &lchan->ts->e1_link;
+
+	DEBUGP(DCC, "Setting up TRAU receiver (e1=%u,ts=%u,ss=%u) "
+		"and (callref 0x%x)\n",
+		src_ss->e1_nr, src_ss->e1_ts, src_ss->e1_ts_ss,
+		callref);
+
+	/* make sure to get rid of any stale old mappings */
+	trau_mux_unmap(src_ss, callref);
+
+	memcpy(&ue->src, src_ss, sizeof(ue->src));
+	ue->net = lchan->ts->trx->bts->network;
+	ue->callref = callref;
+	llist_add(&ue->list, &ss_upqueue);
+
+	return 0;
+}
+
+int trau_send_lchan(struct gsm_lchan *lchan, struct decoded_trau_frame *tf)
+{
+	u_int8_t trau_bits_out[TRAU_FRAME_BITS];
+	struct gsm_e1_subslot *dst_e1_ss = &lchan->ts->e1_link;
+	struct subch_mux *mx;
+
+	mx = e1inp_get_mux(dst_e1_ss->e1_nr, dst_e1_ss->e1_ts);
+	if (!mx)
+		return -EINVAL;
+
+	encode_trau_frame(trau_bits_out, tf);
+
+	/* and send it to the muxer */
+	return subchan_mux_enqueue(mx, dst_e1_ss->e1_ts_ss, trau_bits_out,
+				   TRAU_FRAME_BITS);
+}
