blob: b71c856d9ee04496b3904b9ec136aa5b01efc659 [file] [log] [blame]
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +02001#ifndef _SUBCH_DEMUX_H
2#define _SUBCH_DEMUX_H
3/* A E1 sub-channel (de)multiplexer with TRAU frame sync */
4
5/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#include <stdint.h>
24#include <osmocom/core/linuxlist.h>
25
26#define NR_SUBCH 4
27#define TRAU_FRAME_SIZE 40
28#define TRAU_FRAME_BITS (TRAU_FRAME_SIZE*8)
29
30/***********************************************************************/
31/* DEMULTIPLEXER */
32/***********************************************************************/
33
34struct demux_subch {
35 uint8_t out_bitbuf[TRAU_FRAME_BITS];
36 uint16_t out_idx; /* next bit to be written in out_bitbuf */
37 /* number of consecutive zeros that we have received (for sync) */
38 unsigned int consecutive_zeros;
39 /* are we in TRAU frame sync or not? */
40 unsigned int in_sync;
41};
42
43struct subch_demux {
44 /* bitmask of currently active subchannels */
45 uint8_t chan_activ;
46 /* one demux_subch struct for every subchannel */
47 struct demux_subch subch[NR_SUBCH];
48 /* callback to be called once we have received a complete
49 * frame on a given subchannel */
50 int (*out_cb)(struct subch_demux *dmx, int ch, uint8_t *data, int len,
51 void *);
52 /* user-provided data, transparently passed to out_cb() */
53 void *data;
54};
55
56/* initialize one demultiplexer instance */
57int subch_demux_init(struct subch_demux *dmx);
58
59/* feed 'len' number of muxed bytes into the demultiplexer */
60int subch_demux_in(struct subch_demux *dmx, uint8_t *data, int len);
61
62/* activate decoding/processing for one subchannel */
63int subch_demux_activate(struct subch_demux *dmx, int subch);
64
65/* deactivate decoding/processing for one subchannel */
66int subch_demux_deactivate(struct subch_demux *dmx, int subch);
67
68/***********************************************************************/
69/* MULTIPLEXER */
70/***********************************************************************/
71
72/* one element in the tx_queue of a muxer sub-channel */
73struct subch_txq_entry {
74 struct llist_head list;
75
76 unsigned int bit_len; /* total number of bits in 'bits' */
77 unsigned int next_bit; /* next bit to be transmitted */
78
79 uint8_t bits[0]; /* one bit per byte */
80};
81
82struct mux_subch {
83 struct llist_head tx_queue;
84};
85
86/* structure representing one instance of the subchannel muxer */
87struct subch_mux {
88 struct mux_subch subch[NR_SUBCH];
89};
90
91/* initialize a subchannel muxer instance */
92int subchan_mux_init(struct subch_mux *mx);
93
94/* request the output of 'len' multiplexed bytes */
95int subchan_mux_out(struct subch_mux *mx, uint8_t *data, int len);
96
97/* enqueue some data into one sub-channel of the muxer */
98int subchan_mux_enqueue(struct subch_mux *mx, int s_nr, const uint8_t *data,
99 int len);
100
101#endif /* _SUBCH_DEMUX_H */