blob: 3fbce5bee857346c371a90d543249730adc6551a [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,
Harald Welte46fc7e22014-08-18 19:04:26 +020021 E1INP_SIGN_OSMO, /* IPA CCM OSMO sub-type */
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020022};
23const char *e1inp_signtype_name(enum e1inp_sign_type tp);
Arran Cudbard-Bell67b81eb2016-11-02 11:48:24 -040024extern const struct value_string e1inp_sign_type_names[5];
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020025
Harald Weltef2737fc2011-08-16 14:30:10 +020026enum e1inp_ctr {
27 E1I_CTR_HDLC_ABORT,
28 E1I_CTR_HDLC_BADFCS,
29 E1I_CTR_HDLC_OVERR,
30 E1I_CTR_ALARM,
31 E1I_CTR_REMOVED,
32};
33
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020034struct e1inp_ts;
Harald Weltefe05cf52011-09-26 23:18:41 +020035struct vty;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020036
37struct e1inp_sign_link {
38 /* list of signalling links */
39 struct llist_head list;
40
41 /* to which timeslot do we belong? */
42 struct e1inp_ts *ts;
43
44 enum e1inp_sign_type type;
45
46 /* trx for msg->trx of received msgs */
47 struct gsm_bts_trx *trx;
48
49 /* msgb queue of to-be-transmitted msgs */
50 struct llist_head tx_list;
51
52 /* SAPI and TEI on the E1 TS */
53 uint8_t sapi;
54 uint8_t tei;
55
56 union {
57 struct {
58 uint8_t channel;
59 } misdn;
60 } driver;
61};
62
63enum e1inp_ts_type {
64 E1INP_TS_TYPE_NONE,
65 E1INP_TS_TYPE_SIGN,
66 E1INP_TS_TYPE_TRAU,
Harald Weltea0108e72016-07-27 21:44:50 +020067 E1INP_TS_TYPE_RAW,
Harald Welte7a228eb2016-07-28 11:09:31 +020068 E1INP_TS_TYPE_HDLC,
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020069};
70const char *e1inp_tstype_name(enum e1inp_ts_type tp);
Arran Cudbard-Bell67b81eb2016-11-02 11:48:24 -040071extern const struct value_string e1inp_ts_type_names[6];
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020072
73/* A timeslot in the E1 interface */
74struct e1inp_ts {
75 enum e1inp_ts_type type;
76 int num;
77
78 /* to which line do we belong ? */
79 struct e1inp_line *line;
80
Harald Weltefd44a5f2011-08-21 00:48:54 +020081 /* LAPD instance, if any */
82 struct lapd_instance *lapd;
83
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020084 union {
85 struct {
86 /* list of all signalling links on this TS */
87 struct llist_head sign_links;
88 /* delay for the queue */
89 int delay;
90 /* timer when to dequeue next frame */
91 struct osmo_timer_list tx_timer;
92 } sign;
93 struct {
94 /* subchannel demuxer for frames from E1 */
95 struct subch_demux demux;
96 /* subchannel muxer for frames to E1 */
97 struct subch_mux mux;
98 } trau;
Harald Weltea0108e72016-07-27 21:44:50 +020099 struct {
100 /* call-back for every received frame */
101 void (*recv_cb)(struct e1inp_ts *ts, struct msgb *msg);
102 /* queue of pending to-be-transmitted msgbs */
103 struct llist_head tx_queue;
104 } raw;
Harald Welte7a228eb2016-07-28 11:09:31 +0200105 struct {
106 /* call-back for every received frame */
107 void (*recv_cb)(struct e1inp_ts *ts, struct msgb *msg);
108 /* queue of pending to-be-transmitted msgbs */
109 struct llist_head tx_queue;
110 } hdlc;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200111 };
112 union {
113 struct {
114 /* mISDN driver has one fd for each ts */
115 struct osmo_fd fd;
116 } misdn;
117 struct {
118 /* ip.access driver has one fd for each ts */
119 struct osmo_fd fd;
120 } ipaccess;
121 struct {
122 /* DAHDI driver has one fd for each ts */
123 struct osmo_fd fd;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200124 } dahdi;
Pablo Neira Ayuso7e0d0062011-08-19 11:36:15 +0200125 struct {
126 struct osmo_fd fd;
127 } rs232;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200128 } driver;
Jacob Erlbeck98af3c32014-03-31 10:53:32 +0200129
130 struct msgb *pending_msg;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200131};
132
133struct gsm_e1_subslot {
134 /* Number of E1 link */
135 uint8_t e1_nr;
136 /* Number of E1 TS inside E1 link */
137 uint8_t e1_ts;
138 /* Sub-slot within the E1 TS, 0xff if full TS */
139 uint8_t e1_ts_ss;
140};
141
142enum e1inp_line_role {
143 E1INP_LINE_R_NONE,
144 E1INP_LINE_R_BSC,
145 E1INP_LINE_R_BTS,
146 E1INP_LINE_R_MAX
147};
148
149struct e1inp_driver {
150 struct llist_head list;
151 const char *name;
152 int (*want_write)(struct e1inp_ts *ts);
Pablo Neira Ayuso4e862cb2011-08-19 18:43:38 +0200153 int (*line_update)(struct e1inp_line *line);
Pablo Neira Ayusoadd3ec82011-07-05 14:45:46 +0200154 void (*close)(struct e1inp_sign_link *link);
Harald Weltefe05cf52011-09-26 23:18:41 +0200155 void (*vty_show)(struct vty *vty, struct e1inp_line *line);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200156 int default_delay;
Jacob Erlbeck86dae842014-01-16 18:10:37 +0100157 int has_keepalive;
Neels Hofmeyr0db1d432016-02-22 13:29:09 +0100158 const char *bind_addr;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200159};
160
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200161struct e1inp_line_ops {
Pablo Neira Ayuso4e862cb2011-08-19 18:43:38 +0200162 union {
163 struct {
164 enum e1inp_line_role role; /* BSC or BTS mode. */
165 const char *addr; /* IP address .*/
166 void *dev; /* device parameters. */
167 } ipa;
168 struct {
169 const char *port; /* e.g. /dev/ttyUSB0 */
170 unsigned int delay;
171 } rs232;
172 } cfg;
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200173
Pablo Neira Ayusoc9c4fd32011-06-30 12:19:42 +0200174 struct e1inp_sign_link * (*sign_link_up)(void *unit_info, struct e1inp_line *line, enum e1inp_sign_type type);
175 void (*sign_link_down)(struct e1inp_line *line);
Pablo Neira Ayusodbd82fb2011-07-05 15:29:23 +0200176 int (*sign_link)(struct msgb *msg);
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200177};
178
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200179struct e1inp_line {
180 struct llist_head list;
181 int refcnt;
182
183 unsigned int num;
184 const char *name;
Harald Weltec2889512011-09-13 23:49:04 +0100185 unsigned int port_nr;
Alexander Couzensbeb10ef2016-11-01 22:05:13 +0100186 char *sock_path;
Harald Weltef2737fc2011-08-16 14:30:10 +0200187 struct rate_ctr_group *rate_ctr;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200188
Jacob Erlbeck86dae842014-01-16 18:10:37 +0100189 /* keepalive configuration */
190 int keepalive_num_probes; /* 0: disable, num, or E1INP_USE_DEFAULT */
191 int keepalive_idle_timeout; /* secs, or E1INP_USE_DEFAULT */
192 int keepalive_probe_interval; /* secs or E1INP_USE_DEFAULT */
193
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200194 /* array of timestlots */
195 struct e1inp_ts ts[NUM_E1_TS];
Harald Weltec2889512011-09-13 23:49:04 +0100196 unsigned int num_ts;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200197
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200198 const struct e1inp_line_ops *ops;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200199
200 struct e1inp_driver *driver;
201 void *driver_data;
202};
203
Harald Weltecc2241b2011-07-19 16:06:06 +0200204/* SS_L_INPUT signals */
Pablo Neira Ayuso332a3572011-08-16 17:31:20 +0200205enum e1inp_signal_input {
Pablo Neira Ayusode668912011-08-16 17:26:23 +0200206 S_L_INP_NONE,
207 S_L_INP_TEI_UP,
208 S_L_INP_TEI_DN,
209 S_L_INP_TEI_UNKNOWN,
210 S_L_INP_LINE_INIT,
211 S_L_INP_LINE_ALARM,
212 S_L_INP_LINE_NOALARM,
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200213};
214
Harald Weltecac78fe2017-05-25 19:13:13 +0200215extern const struct value_string e1inp_signal_names[];
216
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200217/* register a driver with the E1 core */
218int e1inp_driver_register(struct e1inp_driver *drv);
219
220/* fine a previously registered driver */
221struct e1inp_driver *e1inp_driver_find(const char *name);
222
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200223/* get a line by its ID */
Pablo Neira Ayuso3832c4f2011-07-07 17:47:26 +0200224struct e1inp_line *e1inp_line_find(uint8_t e1_nr);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200225
226/* create a line in the E1 input core */
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200227struct e1inp_line *e1inp_line_create(uint8_t e1_nr, const char *driver_name);
228
Pablo Neira Ayuso3832c4f2011-07-07 17:47:26 +0200229/* clone one existing E1 input line */
230struct e1inp_line *e1inp_line_clone(void *ctx, struct e1inp_line *line);
231
232/* increment refcount use of E1 input line */
233void e1inp_line_get(struct e1inp_line *line);
234
235/* decrement refcount use of E1 input line, release if unused */
236void e1inp_line_put(struct e1inp_line *line);
237
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200238/* bind operations to one E1 input line */
239void e1inp_line_bind_ops(struct e1inp_line *line, const struct e1inp_line_ops *ops);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200240
241/* find a sign_link for given TEI and SAPI in a TS */
242struct e1inp_sign_link *
243e1inp_lookup_sign_link(struct e1inp_ts *ts, uint8_t tei,
244 uint8_t sapi);
245
246/* create a new signalling link in a E1 timeslot */
247struct e1inp_sign_link *
248e1inp_sign_link_create(struct e1inp_ts *ts, enum e1inp_sign_type type,
249 struct gsm_bts_trx *trx, uint8_t tei,
250 uint8_t sapi);
251
Pablo Neira Ayuso211d2ca2011-06-07 17:15:10 +0200252/* configure and initialize one signalling e1inp_ts */
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200253int e1inp_ts_config_sign(struct e1inp_ts *ts, struct e1inp_line *line);
Pablo Neira Ayuso211d2ca2011-06-07 17:15:10 +0200254
255/* configure and initialize one timeslot dedicated to TRAU frames. */
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200256int e1inp_ts_config_trau(struct e1inp_ts *ts, struct e1inp_line *line,
Pablo Neira Ayuso211d2ca2011-06-07 17:15:10 +0200257 int (*trau_rcv_cb)(struct subch_demux *dmx, int ch,
258 uint8_t *data, int len, void *_priv));
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200259
Harald Weltea0108e72016-07-27 21:44:50 +0200260/* configure and initialize one timeslot dedicated to RAW frames */
261int e1inp_ts_config_raw(struct e1inp_ts *ts, struct e1inp_line *line,
262 void (*raw_recv_cb)(struct e1inp_ts *ts,
263 struct msgb *msg));
264
Harald Welte7a228eb2016-07-28 11:09:31 +0200265/* configure and initialize one timeslot dedicated to HDLC frames */
266int e1inp_ts_config_hdlc(struct e1inp_ts *ts, struct e1inp_line *line,
267 void (*hdlc_recv_cb)(struct e1inp_ts *ts,
268 struct msgb *msg));
269
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200270/* Receive a packet from the E1 driver */
271int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
272 uint8_t tei, uint8_t sapi);
Harald Weltefd44a5f2011-08-21 00:48:54 +0200273int e1inp_rx_ts_lapd(struct e1inp_ts *e1i_ts, struct msgb *msg);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200274
275/* called by driver if it wants to transmit on a given TS */
276struct msgb *e1inp_tx_ts(struct e1inp_ts *e1i_ts,
277 struct e1inp_sign_link **sign_link);
278
279/* called by driver in case some kind of link state event */
280int e1inp_event(struct e1inp_ts *ts, int evt, uint8_t tei, uint8_t sapi);
281
Andreas Eversberga7ff0012011-09-26 11:29:30 +0200282/* L2->L3 */
283void e1inp_dlsap_up(struct osmo_dlsap_prim *odp, uint8_t tei, uint8_t sapi,
284 void *rx_cbdata);
285
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200286/* Write LAPD frames to the fd. */
Pablo Neira Ayuso2e11f5c2013-07-05 15:08:18 +0200287int e1_set_pcap_fd(int fd);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200288
289/* called by TRAU muxer to obtain the destination mux entity */
290struct subch_mux *e1inp_get_mux(uint8_t e1_nr, uint8_t ts_nr);
291
Harald Welte84f67b22013-06-30 13:13:59 +0200292/* on an IPA BTS, the BTS needs to establish the RSL connection much
293 * later than the OML connection. */
294int e1inp_ipa_bts_rsl_connect(struct e1inp_line *line,
295 const char *rem_addr, uint16_t rem_port);
296
Andreas Eversbergf422a752014-01-21 14:54:41 +0100297int e1inp_ipa_bts_rsl_connect_n(struct e1inp_line *line,
298 const char *rem_addr, uint16_t rem_port,
299 uint8_t trx_id);
300
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200301void e1inp_sign_link_destroy(struct e1inp_sign_link *link);
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200302int e1inp_line_update(struct e1inp_line *line);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200303
Pablo Neira Ayuso262aee82011-07-05 19:17:08 +0200304int e1inp_vty_init(void);
305
Alexander Couzensbeb10ef2016-11-01 22:05:13 +0100306/* activate superchannel or deactive to use timeslots. only valid for unixsocket driver */
307void e1inp_ericsson_set_altc(struct e1inp_line *unixlinue, int superchannel);
308
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200309extern struct llist_head e1inp_driver_list;
310extern struct llist_head e1inp_line_list;
311
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200312/* XXX */
313struct input_signal_data {
314 int link_type;
315 uint8_t tei;
316 uint8_t sapi;
Harald Weltef35d8892016-10-16 15:33:52 +0200317 uint8_t ts_nr;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200318 struct gsm_bts_trx *trx;
319 struct e1inp_line *line;
320};
321
Pablo Neira Ayuso96e72632011-06-26 19:08:05 +0200322int abis_sendmsg(struct msgb *msg);
Holger Hans Peter Freyther180ce7e2012-02-03 20:06:15 +0100323int abis_rsl_sendmsg(struct msgb *msg);
Pablo Neira Ayuso96e72632011-06-26 19:08:05 +0200324
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200325#endif /* _E1_INPUT_H */