aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-02-09 18:13:26 +0000
committerHarald Welte <laforge@gnumonks.org>2009-02-09 18:13:26 +0000
commit1fa60c8ab04653bae5ac29d8d93ad18b44f0f354 (patch)
tree35aa1e0c66c605576bb900347c465e9120a85fc0 /include
parent0b4c34e3ca22da724de308b8154a2730b53fc388 (diff)
* 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
Diffstat (limited to 'include')
-rw-r--r--include/openbsc/abis_nm.h1
-rw-r--r--include/openbsc/e1_input.h137
-rw-r--r--include/openbsc/gsm_data.h10
-rw-r--r--include/openbsc/subchan_demux.h57
-rw-r--r--include/openbsc/trau_frame.h1
-rw-r--r--include/openbsc/trau_mux.h41
6 files changed, 240 insertions, 7 deletions
diff --git a/include/openbsc/abis_nm.h b/include/openbsc/abis_nm.h
index 2df941e6e..e75f108b2 100644
--- a/include/openbsc/abis_nm.h
+++ b/include/openbsc/abis_nm.h
@@ -486,5 +486,6 @@ int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname,
u_int8_t win_size, int forced, gsm_cbfn *cbfn);
int abis_nm_bs11_set_ext_time(struct gsm_bts *bts);
int abis_nm_bs11_bsc_disconnect(struct gsm_bts *bts, int reconnect);
+int abis_nm_bs11_restart(struct gsm_bts *bts);
#endif /* _NM_H */
diff --git a/include/openbsc/e1_input.h b/include/openbsc/e1_input.h
new file mode 100644
index 000000000..29c29d081
--- /dev/null
+++ b/include/openbsc/e1_input.h
@@ -0,0 +1,137 @@
+#ifndef _E1_INPUT_H
+#define _E1_INPUT_H
+
+#include <stdlib.h>
+
+#include <openbsc/linuxlist.h>
+#include <openbsc/gsm_data.h>
+#include <openbsc/msgb.h>
+#include <openbsc/select.h>
+#include <openbsc/subchan_demux.h>
+
+#define NUM_E1_TS 32
+
+enum e1inp_sign_type {
+ E1INP_SIGN_NONE,
+ E1INP_SIGN_OML,
+ E1INP_SIGN_RSL,
+};
+
+struct e1inp_ts;
+
+struct e1inp_sign_link {
+ /* list of signalling links */
+ struct llist_head list;
+
+ /* to which timeslot do we belong? */
+ struct e1inp_ts *ts;
+
+ enum e1inp_sign_type type;
+
+ /* trx for msg->trx of received msgs */
+ struct gsm_bts_trx *trx;
+
+ /* msgb queue of to-be-transmitted msgs */
+ struct llist_head tx_list;
+
+ /* SAPI and TEI on the E1 TS */
+ u_int8_t sapi;
+ u_int8_t tei;
+
+ union {
+ struct {
+ u_int8_t channel;
+ } misdn;
+ } driver;
+};
+
+enum e1inp_ts_type {
+ E1INP_TS_TYPE_NONE,
+ E1INP_TS_TYPE_SIGN,
+ E1INP_TS_TYPE_TRAU,
+};
+
+/* A timeslot in the E1 interface */
+struct e1inp_ts {
+ enum e1inp_ts_type type;
+ int num;
+
+ /* to which line do we belong ? */
+ struct e1inp_line *line;
+
+ union {
+ struct {
+ struct llist_head sign_links;
+ } sign;
+ struct {
+ /* subchannel demuxer for frames from E1 */
+ struct subch_demux demux;
+ /* subchannel muxer for frames to E1 */
+ struct subch_mux mux;
+ } trau;
+ };
+ union {
+ struct {
+ /* mISDN driver has one fd for each ts */
+ struct bsc_fd fd;
+ } misdn;
+ } driver;
+};
+
+struct e1inp_driver {
+ struct llist_head list;
+ const char *name;
+ int (*want_write)(struct e1inp_ts *ts);
+};
+
+struct e1inp_line {
+ struct llist_head list;
+ unsigned int num;
+ const char *name;
+
+ /* array of timestlots */
+ struct e1inp_ts ts[NUM_E1_TS];
+
+ struct e1inp_driver *driver;
+ void *driver_data;
+};
+
+/* register a driver with the E1 core */
+int e1inp_driver_register(struct e1inp_driver *drv);
+
+/* register a line with the E1 core */
+int e1inp_line_register(struct e1inp_line *line);
+
+/* find a sign_link for given TEI and SAPI in a TS */
+struct e1inp_sign_link *
+e1inp_lookup_sign_link(struct e1inp_ts *ts, u_int8_t tei,
+ u_int8_t sapi);
+
+/* create a new signalling link in a E1 timeslot */
+struct e1inp_sign_link *
+e1inp_sign_link_create(struct e1inp_ts *ts, enum e1inp_sign_type type,
+ struct gsm_bts_trx *trx, u_int8_t tei,
+ u_int8_t sapi);
+
+/* configure and initialize one e1inp_ts */
+int e1inp_ts_config(struct e1inp_ts *ts, struct e1inp_line *line,
+ enum e1inp_ts_type type);
+
+/* Call from the Stack: configuration of this TS has changed */
+int e1inp_update_ts(struct e1inp_ts *ts);
+
+/* Receive a packet from the E1 driver */
+int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
+ u_int8_t tei, u_int8_t sapi);
+
+/* called by driver if it wants to transmit on a given TS */
+struct msgb *e1inp_tx_ts(struct e1inp_ts *e1i_ts,
+ struct e1inp_sign_link **sign_link);
+
+/* called by driver in case some kind of link state event */
+int e1inp_event(struct e1inp_ts *ts, int evt, u_int8_t tei, u_int8_t sapi);
+
+/* called by TRAU muxer to obtain the destination mux entity */
+struct subch_mux *e1inp_get_mux(u_int8_t e1_nr, u_int8_t ts_nr);
+
+#endif /* _E1_INPUT_H */
diff --git a/include/openbsc/gsm_data.h b/include/openbsc/gsm_data.h
index 75b3db516..b96ec402d 100644
--- a/include/openbsc/gsm_data.h
+++ b/include/openbsc/gsm_data.h
@@ -166,6 +166,8 @@ struct gsm_bts_trx {
struct gsm_bts *bts;
/* number of this TRX in the BTS */
u_int8_t nr;
+ /* how do we talk RSL with this TRX? */
+ struct e1inp_sign_link *rsl_link;
u_int16_t arfcn;
struct gsm_bts_trx_ts ts[TRX_NR_TS];
@@ -215,6 +217,8 @@ struct gsm_bts {
u_int8_t location_area_code;
/* type of BTS */
enum gsm_bts_type type;
+ /* how do we talk OML with this TRX? */
+ struct e1inp_sign_link *oml_link;
/* Abis network management O&M handle */
struct abis_nm_h *nmh;
@@ -255,10 +259,8 @@ const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
enum gsm_e1_event {
EVT_E1_NONE,
- EVT_E1_OML_UP,
- EVT_E1_RSL_UP,
- EVT_E1_OML_DN,
- EVT_E1_RSL_DN,
+ EVT_E1_TEI_UP,
+ EVT_E1_TEI_DN,
};
#endif
diff --git a/include/openbsc/subchan_demux.h b/include/openbsc/subchan_demux.h
index 373cf4a30..23c903204 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 */
diff --git a/include/openbsc/trau_frame.h b/include/openbsc/trau_frame.h
index 7f0a2e69b..5923d4ac1 100644
--- a/include/openbsc/trau_frame.h
+++ b/include/openbsc/trau_frame.h
@@ -59,6 +59,7 @@ struct decoded_trau_frame {
int decode_trau_frame(struct decoded_trau_frame *fr, const u_int8_t *trau_bits);
int encode_trau_frame(u_int8_t *trau_bits, const struct decoded_trau_frame *fr);
int trau_frame_up2down(struct decoded_trau_frame *fr);
+u_int8_t *trau_idle_frame(void);
#endif /* _TRAU_FRAME_H */
diff --git a/include/openbsc/trau_mux.h b/include/openbsc/trau_mux.h
new file mode 100644
index 000000000..43836dbc5
--- /dev/null
+++ b/include/openbsc/trau_mux.h
@@ -0,0 +1,41 @@
+/* Simple TRAU frame reflector to route voice calls */
+
+/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+/* The "TRAU mux map" defines which particular 16kbit sub-slot (in which E1
+ * timeslot on which E1 interface) should be directly muxed to which other
+ * sub-slot. Entries in the mux map are always bi-directional.
+ *
+ * The idea of all this is to directly switch voice channels in the BSC
+ * from one phone to another. We do this right now since we don't support
+ * any external interface for voice channels, and in the future as an
+ * optimization to routing them externally.
+ */
+
+/* map a TRAU mux map entry */
+int trau_mux_map(const struct gsm_e1_subslot *src,
+ const struct gsm_e1_subslot *dst);
+
+/* unmap a TRAU mux map entry */
+int trau_mux_unmap(const struct gsm_e1_subslot *ss);
+
+/* 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);