* add trau_mux implementation to relay from one incoming TRAU
  channel to another one (simple voice call switching)
* add a way more generic E1 input layer, abstracting out the misdn
  low-level interface. This also adds infrastructure for multiple TRX
  in one BTS, as well as multiple BTS on one E1 link
* add a E1 subchannel multiplexer for sending multiple 16kbit sub-channels
  one one 64kBps E1 channel
* add TRAU IDLE frame generation
* terminate bsc_hack in case there is a E1 / mISDN init error
* introduce 'e1_config.c' file with static configuration of our
  E1 setup (which TRX/BTS is configured for which TEI/SAPI/E1). This should
  later become a config file rather than a compiled C file.

WARNING: all this compiles but is not tested yet.  Expect fix-up committs over
the next hours or so

diff --git a/include/openbsc/subchan_demux.h b/include/openbsc/subchan_demux.h
index 373cf4a..23c9032 100644
--- a/include/openbsc/subchan_demux.h
+++ b/include/openbsc/subchan_demux.h
@@ -1,6 +1,6 @@
 #ifndef _SUBCH_DEMUX_H
 #define _SUBCH_DEMUX_H
-/* A E1 sub-channel demultiplexer with TRAU frame sync */
+/* A E1 sub-channel (de)multiplexer with TRAU frame sync */
 
 /* (C) 2009 by Harald Welte <laforge@gnumonks.org>
  * All Rights Reserved
@@ -22,26 +22,77 @@
  */
 
 #include <sys/types.h>
+#include <openbsc/linuxlist.h>
 
 #define NR_SUBCH	4
 #define TRAU_FRAME_SIZE	40
 #define TRAU_FRAME_BITS	(TRAU_FRAME_SIZE*8)
 
-struct subch {
+/***********************************************************************/
+/* DEMULTIPLEXER */
+/***********************************************************************/
+
+struct demux_subch {
 	u_int8_t out_bitbuf[TRAU_FRAME_BITS];
 	u_int8_t out_idx; /* next bit to be written in out_bitbuf */
 };
 
 struct subch_demux {
+	/* bitmask of currently active subchannels */
 	u_int8_t chan_activ;
-	struct subch subch[NR_SUBCH];
+	/* one demux_subch struct for every subchannel */
+	struct demux_subch subch[NR_SUBCH];
+	/* callback to be called once we have received a complete
+	 * frame on a given subchannel */
 	int (*out_cb)(struct subch_demux *dmx, int ch, u_int8_t *data, int len,
 		      void *);
+	/* user-provided data, transparently passed to out_cb() */
 	void *data;
 };
 
+/* initialize one demultiplexer instance */
 int subch_demux_init(struct subch_demux *dmx);
+
+/* feed 'len' number of muxed bytes into the demultiplexer */
 int subch_demux_in(struct subch_demux *dmx, u_int8_t *data, int len);
+
+/* activate decoding/processing for one subchannel */
 int subch_demux_activate(struct subch_demux *dmx, int subch);
+
+/* deactivate decoding/processing for one subchannel */
 int subch_demux_deactivate(struct subch_demux *dmx, int subch);
+
+/***********************************************************************/
+/* MULTIPLEXER */
+/***********************************************************************/
+
+/* one element in the tx_queue of a muxer sub-channel */
+struct subch_txq_entry {
+	struct llist_head list;
+
+	unsigned int bit_len;	/* total number of bits in 'bits' */
+	unsigned int next_bit;	/* next bit to be transmitted */
+
+	u_int8_t bits[0];	/* one bit per byte */
+};
+
+struct mux_subch {
+	struct llist_head tx_queue;
+};
+
+/* structure representing one instance of the subchannel muxer */
+struct subch_mux {
+	struct mux_subch subch[NR_SUBCH];
+};
+
+/* initialize a subchannel muxer instance */
+int subchan_mux_init(struct subch_mux *mx);
+
+/* request the output of 'len' multiplexed bytes */
+int subchan_mux_out(struct subch_mux *mx, u_int8_t *data, int len);
+
+/* enqueue some data into one sub-channel of the muxer */
+int subchan_mux_enqueue(struct subch_mux *mx, int s_nr, const u_int8_t *data,
+			int len);
+
 #endif /* _SUBCH_DEMUX_H */