blob: cf8677bf8f663b2066ac9cbdfa7186cd2215b876 [file] [log] [blame]
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +02001#ifndef _E1_INPUT_H
2#define _E1_INPUT_H
3
4#include <stdlib.h>
5#include <netinet/in.h>
6
7#include <osmocom/core/linuxlist.h>
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +02008#include <osmocom/core/timer.h>
9#include <osmocom/core/msgb.h>
10#include <osmocom/core/select.h>
Pablo Neira Ayuso177094b2011-06-07 12:21:51 +020011#include <osmocom/abis/subchan_demux.h>
Andreas Eversberga7ff0012011-09-26 11:29:30 +020012#include <osmocom/abis/lapd.h>
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020013
14#define NUM_E1_TS 32
Jacob Erlbeck86dae842014-01-16 18:10:37 +010015#define E1INP_USE_DEFAULT (-1)
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020016
17enum e1inp_sign_type {
18 E1INP_SIGN_NONE,
19 E1INP_SIGN_OML,
20 E1INP_SIGN_RSL,
21};
22const char *e1inp_signtype_name(enum e1inp_sign_type tp);
23
Harald Weltef2737fc2011-08-16 14:30:10 +020024enum e1inp_ctr {
25 E1I_CTR_HDLC_ABORT,
26 E1I_CTR_HDLC_BADFCS,
27 E1I_CTR_HDLC_OVERR,
28 E1I_CTR_ALARM,
29 E1I_CTR_REMOVED,
30};
31
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020032struct e1inp_ts;
Harald Weltefe05cf52011-09-26 23:18:41 +020033struct vty;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020034
35struct e1inp_sign_link {
36 /* list of signalling links */
37 struct llist_head list;
38
39 /* to which timeslot do we belong? */
40 struct e1inp_ts *ts;
41
42 enum e1inp_sign_type type;
43
44 /* trx for msg->trx of received msgs */
45 struct gsm_bts_trx *trx;
46
47 /* msgb queue of to-be-transmitted msgs */
48 struct llist_head tx_list;
49
50 /* SAPI and TEI on the E1 TS */
51 uint8_t sapi;
52 uint8_t tei;
53
54 union {
55 struct {
56 uint8_t channel;
57 } misdn;
58 } driver;
59};
60
61enum e1inp_ts_type {
62 E1INP_TS_TYPE_NONE,
63 E1INP_TS_TYPE_SIGN,
64 E1INP_TS_TYPE_TRAU,
65};
66const char *e1inp_tstype_name(enum e1inp_ts_type tp);
67
68/* A timeslot in the E1 interface */
69struct e1inp_ts {
70 enum e1inp_ts_type type;
71 int num;
72
73 /* to which line do we belong ? */
74 struct e1inp_line *line;
75
Harald Weltefd44a5f2011-08-21 00:48:54 +020076 /* LAPD instance, if any */
77 struct lapd_instance *lapd;
78
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020079 union {
80 struct {
81 /* list of all signalling links on this TS */
82 struct llist_head sign_links;
83 /* delay for the queue */
84 int delay;
85 /* timer when to dequeue next frame */
86 struct osmo_timer_list tx_timer;
87 } sign;
88 struct {
89 /* subchannel demuxer for frames from E1 */
90 struct subch_demux demux;
91 /* subchannel muxer for frames to E1 */
92 struct subch_mux mux;
93 } trau;
94 };
95 union {
96 struct {
97 /* mISDN driver has one fd for each ts */
98 struct osmo_fd fd;
99 } misdn;
100 struct {
101 /* ip.access driver has one fd for each ts */
102 struct osmo_fd fd;
103 } ipaccess;
104 struct {
105 /* DAHDI driver has one fd for each ts */
106 struct osmo_fd fd;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200107 } dahdi;
Pablo Neira Ayuso7e0d0062011-08-19 11:36:15 +0200108 struct {
109 struct osmo_fd fd;
110 } rs232;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200111 } driver;
Jacob Erlbeck98af3c32014-03-31 10:53:32 +0200112
113 struct msgb *pending_msg;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200114};
115
116struct gsm_e1_subslot {
117 /* Number of E1 link */
118 uint8_t e1_nr;
119 /* Number of E1 TS inside E1 link */
120 uint8_t e1_ts;
121 /* Sub-slot within the E1 TS, 0xff if full TS */
122 uint8_t e1_ts_ss;
123};
124
125enum e1inp_line_role {
126 E1INP_LINE_R_NONE,
127 E1INP_LINE_R_BSC,
128 E1INP_LINE_R_BTS,
129 E1INP_LINE_R_MAX
130};
131
132struct e1inp_driver {
133 struct llist_head list;
134 const char *name;
135 int (*want_write)(struct e1inp_ts *ts);
Pablo Neira Ayuso4e862cb2011-08-19 18:43:38 +0200136 int (*line_update)(struct e1inp_line *line);
Pablo Neira Ayusoadd3ec82011-07-05 14:45:46 +0200137 void (*close)(struct e1inp_sign_link *link);
Harald Weltefe05cf52011-09-26 23:18:41 +0200138 void (*vty_show)(struct vty *vty, struct e1inp_line *line);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200139 int default_delay;
Jacob Erlbeck86dae842014-01-16 18:10:37 +0100140 int has_keepalive;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200141};
142
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200143struct e1inp_line_ops {
Pablo Neira Ayuso4e862cb2011-08-19 18:43:38 +0200144 union {
145 struct {
146 enum e1inp_line_role role; /* BSC or BTS mode. */
147 const char *addr; /* IP address .*/
148 void *dev; /* device parameters. */
149 } ipa;
150 struct {
151 const char *port; /* e.g. /dev/ttyUSB0 */
152 unsigned int delay;
153 } rs232;
154 } cfg;
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200155
Pablo Neira Ayusoc9c4fd32011-06-30 12:19:42 +0200156 struct e1inp_sign_link * (*sign_link_up)(void *unit_info, struct e1inp_line *line, enum e1inp_sign_type type);
157 void (*sign_link_down)(struct e1inp_line *line);
Pablo Neira Ayusodbd82fb2011-07-05 15:29:23 +0200158 int (*sign_link)(struct msgb *msg);
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200159};
160
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200161struct e1inp_line {
162 struct llist_head list;
163 int refcnt;
164
165 unsigned int num;
166 const char *name;
Harald Weltec2889512011-09-13 23:49:04 +0100167 unsigned int port_nr;
Harald Weltef2737fc2011-08-16 14:30:10 +0200168 struct rate_ctr_group *rate_ctr;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200169
Jacob Erlbeck86dae842014-01-16 18:10:37 +0100170 /* keepalive configuration */
171 int keepalive_num_probes; /* 0: disable, num, or E1INP_USE_DEFAULT */
172 int keepalive_idle_timeout; /* secs, or E1INP_USE_DEFAULT */
173 int keepalive_probe_interval; /* secs or E1INP_USE_DEFAULT */
174
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200175 /* array of timestlots */
176 struct e1inp_ts ts[NUM_E1_TS];
Harald Weltec2889512011-09-13 23:49:04 +0100177 unsigned int num_ts;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200178
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200179 const struct e1inp_line_ops *ops;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200180
181 struct e1inp_driver *driver;
182 void *driver_data;
183};
184
Harald Weltecc2241b2011-07-19 16:06:06 +0200185/* SS_L_INPUT signals */
Pablo Neira Ayuso332a3572011-08-16 17:31:20 +0200186enum e1inp_signal_input {
Pablo Neira Ayusode668912011-08-16 17:26:23 +0200187 S_L_INP_NONE,
188 S_L_INP_TEI_UP,
189 S_L_INP_TEI_DN,
190 S_L_INP_TEI_UNKNOWN,
191 S_L_INP_LINE_INIT,
192 S_L_INP_LINE_ALARM,
193 S_L_INP_LINE_NOALARM,
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200194};
195
196/* register a driver with the E1 core */
197int e1inp_driver_register(struct e1inp_driver *drv);
198
199/* fine a previously registered driver */
200struct e1inp_driver *e1inp_driver_find(const char *name);
201
202/* register a line with the E1 core */
203int e1inp_line_register(struct e1inp_line *line);
204
205/* get a line by its ID */
Pablo Neira Ayuso3832c4f2011-07-07 17:47:26 +0200206struct e1inp_line *e1inp_line_find(uint8_t e1_nr);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200207
208/* create a line in the E1 input core */
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200209struct e1inp_line *e1inp_line_create(uint8_t e1_nr, const char *driver_name);
210
Pablo Neira Ayuso3832c4f2011-07-07 17:47:26 +0200211/* clone one existing E1 input line */
212struct e1inp_line *e1inp_line_clone(void *ctx, struct e1inp_line *line);
213
214/* increment refcount use of E1 input line */
215void e1inp_line_get(struct e1inp_line *line);
216
217/* decrement refcount use of E1 input line, release if unused */
218void e1inp_line_put(struct e1inp_line *line);
219
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200220/* bind operations to one E1 input line */
221void e1inp_line_bind_ops(struct e1inp_line *line, const struct e1inp_line_ops *ops);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200222
223/* find a sign_link for given TEI and SAPI in a TS */
224struct e1inp_sign_link *
225e1inp_lookup_sign_link(struct e1inp_ts *ts, uint8_t tei,
226 uint8_t sapi);
227
228/* create a new signalling link in a E1 timeslot */
229struct e1inp_sign_link *
230e1inp_sign_link_create(struct e1inp_ts *ts, enum e1inp_sign_type type,
231 struct gsm_bts_trx *trx, uint8_t tei,
232 uint8_t sapi);
233
Pablo Neira Ayuso211d2ca2011-06-07 17:15:10 +0200234/* configure and initialize one signalling e1inp_ts */
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200235int e1inp_ts_config_sign(struct e1inp_ts *ts, struct e1inp_line *line);
Pablo Neira Ayuso211d2ca2011-06-07 17:15:10 +0200236
237/* configure and initialize one timeslot dedicated to TRAU frames. */
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200238int e1inp_ts_config_trau(struct e1inp_ts *ts, struct e1inp_line *line,
Pablo Neira Ayuso211d2ca2011-06-07 17:15:10 +0200239 int (*trau_rcv_cb)(struct subch_demux *dmx, int ch,
240 uint8_t *data, int len, void *_priv));
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200241
242/* Call from the Stack: configuration of this TS has changed */
243int e1inp_update_ts(struct e1inp_ts *ts);
244
245/* Receive a packet from the E1 driver */
246int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
247 uint8_t tei, uint8_t sapi);
Harald Weltefd44a5f2011-08-21 00:48:54 +0200248int e1inp_rx_ts_lapd(struct e1inp_ts *e1i_ts, struct msgb *msg);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200249
250/* called by driver if it wants to transmit on a given TS */
251struct msgb *e1inp_tx_ts(struct e1inp_ts *e1i_ts,
252 struct e1inp_sign_link **sign_link);
253
254/* called by driver in case some kind of link state event */
255int e1inp_event(struct e1inp_ts *ts, int evt, uint8_t tei, uint8_t sapi);
256
Andreas Eversberga7ff0012011-09-26 11:29:30 +0200257/* L2->L3 */
258void e1inp_dlsap_up(struct osmo_dlsap_prim *odp, uint8_t tei, uint8_t sapi,
259 void *rx_cbdata);
260
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200261/* Write LAPD frames to the fd. */
Pablo Neira Ayuso2e11f5c2013-07-05 15:08:18 +0200262int e1_set_pcap_fd(int fd);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200263
264/* called by TRAU muxer to obtain the destination mux entity */
265struct subch_mux *e1inp_get_mux(uint8_t e1_nr, uint8_t ts_nr);
266
Harald Welte84f67b22013-06-30 13:13:59 +0200267/* on an IPA BTS, the BTS needs to establish the RSL connection much
268 * later than the OML connection. */
269int e1inp_ipa_bts_rsl_connect(struct e1inp_line *line,
270 const char *rem_addr, uint16_t rem_port);
271
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200272void e1inp_sign_link_destroy(struct e1inp_sign_link *link);
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200273int e1inp_line_update(struct e1inp_line *line);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200274
Pablo Neira Ayuso262aee82011-07-05 19:17:08 +0200275int e1inp_vty_init(void);
276
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200277struct gsm_network;
278int ipaccess_setup(struct gsm_network *gsmnet);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200279
280extern struct llist_head e1inp_driver_list;
281extern struct llist_head e1inp_line_list;
282
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200283/* XXX */
284struct input_signal_data {
285 int link_type;
286 uint8_t tei;
287 uint8_t sapi;
288 struct gsm_bts_trx *trx;
289 struct e1inp_line *line;
290};
291
Pablo Neira Ayuso96e72632011-06-26 19:08:05 +0200292int abis_sendmsg(struct msgb *msg);
Holger Hans Peter Freyther180ce7e2012-02-03 20:06:15 +0100293int abis_rsl_sendmsg(struct msgb *msg);
Pablo Neira Ayuso96e72632011-06-26 19:08:05 +0200294
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200295#endif /* _E1_INPUT_H */