blob: 9c3fe5603a61ead68570e061ac7a580173c8eb9f [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>
Pau Espin Pedrol5196cd52020-07-14 17:52:09 +02008#include <osmocom/core/use_count.h>
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +02009#include <osmocom/core/timer.h>
10#include <osmocom/core/msgb.h>
11#include <osmocom/core/select.h>
Harald Welteb3952c62020-06-20 22:07:36 +020012#include <osmocom/gsm/i460_mux.h>
Pablo Neira Ayuso177094b2011-06-07 12:21:51 +020013#include <osmocom/abis/subchan_demux.h>
Andreas Eversberga7ff0012011-09-26 11:29:30 +020014#include <osmocom/abis/lapd.h>
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020015
16#define NUM_E1_TS 32
Jacob Erlbeck86dae842014-01-16 18:10:37 +010017#define E1INP_USE_DEFAULT (-1)
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020018
Harald Welteb5af0992020-01-12 12:59:52 +010019#define LOGPITS(e1ts, ss, level, fmt, args ...) \
20 LOGP(ss, level, "E1TS(%u:%u) " fmt, (e1ts)->line->num, (e1ts)->num, ## args)
21
22#define LOGPIL(e1l, ss, level, fmt, args ...) \
23 LOGP(ss, level, "E1L(%u) " fmt, (e1l)->num, ## args)
24
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020025enum e1inp_sign_type {
26 E1INP_SIGN_NONE,
27 E1INP_SIGN_OML,
28 E1INP_SIGN_RSL,
Harald Welte46fc7e22014-08-18 19:04:26 +020029 E1INP_SIGN_OSMO, /* IPA CCM OSMO sub-type */
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020030};
31const char *e1inp_signtype_name(enum e1inp_sign_type tp);
Arran Cudbard-Bell67b81eb2016-11-02 11:48:24 -040032extern const struct value_string e1inp_sign_type_names[5];
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020033
Harald Weltef2737fc2011-08-16 14:30:10 +020034enum e1inp_ctr {
35 E1I_CTR_HDLC_ABORT,
36 E1I_CTR_HDLC_BADFCS,
37 E1I_CTR_HDLC_OVERR,
38 E1I_CTR_ALARM,
39 E1I_CTR_REMOVED,
40};
41
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020042struct e1inp_ts;
Harald Weltefe05cf52011-09-26 23:18:41 +020043struct vty;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020044
45struct e1inp_sign_link {
46 /* list of signalling links */
47 struct llist_head list;
48
49 /* to which timeslot do we belong? */
50 struct e1inp_ts *ts;
51
52 enum e1inp_sign_type type;
53
Pau Espin Pedrol837fb6e2020-07-15 15:09:36 +020054 /* trx for msg->trx of received msgs */
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020055 struct gsm_bts_trx *trx;
56
57 /* msgb queue of to-be-transmitted msgs */
58 struct llist_head tx_list;
59
60 /* SAPI and TEI on the E1 TS */
61 uint8_t sapi;
62 uint8_t tei;
63
64 union {
65 struct {
66 uint8_t channel;
67 } misdn;
68 } driver;
69};
70
71enum e1inp_ts_type {
72 E1INP_TS_TYPE_NONE,
73 E1INP_TS_TYPE_SIGN,
74 E1INP_TS_TYPE_TRAU,
Harald Weltea0108e72016-07-27 21:44:50 +020075 E1INP_TS_TYPE_RAW,
Harald Welte7a228eb2016-07-28 11:09:31 +020076 E1INP_TS_TYPE_HDLC,
Harald Welteb3952c62020-06-20 22:07:36 +020077 E1INP_TS_TYPE_I460,
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020078};
79const char *e1inp_tstype_name(enum e1inp_ts_type tp);
Harald Welteb3952c62020-06-20 22:07:36 +020080extern const struct value_string e1inp_ts_type_names[];
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020081
82/* A timeslot in the E1 interface */
83struct e1inp_ts {
84 enum e1inp_ts_type type;
85 int num;
86
87 /* to which line do we belong ? */
88 struct e1inp_line *line;
89
Harald Weltefd44a5f2011-08-21 00:48:54 +020090 /* LAPD instance, if any */
91 struct lapd_instance *lapd;
92
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +020093 union {
94 struct {
95 /* list of all signalling links on this TS */
96 struct llist_head sign_links;
97 /* delay for the queue */
98 int delay;
99 /* timer when to dequeue next frame */
100 struct osmo_timer_list tx_timer;
101 } sign;
102 struct {
103 /* subchannel demuxer for frames from E1 */
104 struct subch_demux demux;
105 /* subchannel muxer for frames to E1 */
106 struct subch_mux mux;
107 } trau;
Harald Weltea0108e72016-07-27 21:44:50 +0200108 struct {
109 /* call-back for every received frame */
110 void (*recv_cb)(struct e1inp_ts *ts, struct msgb *msg);
111 /* queue of pending to-be-transmitted msgbs */
112 struct llist_head tx_queue;
113 } raw;
Harald Welte7a228eb2016-07-28 11:09:31 +0200114 struct {
115 /* call-back for every received frame */
116 void (*recv_cb)(struct e1inp_ts *ts, struct msgb *msg);
117 /* queue of pending to-be-transmitted msgbs */
118 struct llist_head tx_queue;
119 } hdlc;
Harald Welteb3952c62020-06-20 22:07:36 +0200120 struct {
121 struct osmo_i460_timeslot i460_ts;
122 } i460;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200123 };
124 union {
125 struct {
126 /* mISDN driver has one fd for each ts */
127 struct osmo_fd fd;
128 } misdn;
129 struct {
130 /* ip.access driver has one fd for each ts */
131 struct osmo_fd fd;
Eric Wildef1f3272019-07-10 18:10:31 +0200132 /* ipa keep-alive */
133 struct osmo_fsm_inst* ka_fsm;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200134 } ipaccess;
135 struct {
136 /* DAHDI driver has one fd for each ts */
137 struct osmo_fd fd;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200138 } dahdi;
Pablo Neira Ayuso7e0d0062011-08-19 11:36:15 +0200139 struct {
Sylvain Munautb559a532019-05-09 11:14:26 +0200140 /* osmo-e1d driver has one fd for each ts */
141 struct osmo_fd fd;
142 } e1d;
143 struct {
Pablo Neira Ayuso7e0d0062011-08-19 11:36:15 +0200144 struct osmo_fd fd;
145 } rs232;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200146 } driver;
Jacob Erlbeck98af3c32014-03-31 10:53:32 +0200147
148 struct msgb *pending_msg;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200149};
150
151struct gsm_e1_subslot {
152 /* Number of E1 link */
153 uint8_t e1_nr;
154 /* Number of E1 TS inside E1 link */
155 uint8_t e1_ts;
156 /* Sub-slot within the E1 TS, 0xff if full TS */
157 uint8_t e1_ts_ss;
158};
159
160enum e1inp_line_role {
161 E1INP_LINE_R_NONE,
162 E1INP_LINE_R_BSC,
163 E1INP_LINE_R_BTS,
164 E1INP_LINE_R_MAX
165};
166
167struct e1inp_driver {
168 struct llist_head list;
169 const char *name;
170 int (*want_write)(struct e1inp_ts *ts);
Pablo Neira Ayuso4e862cb2011-08-19 18:43:38 +0200171 int (*line_update)(struct e1inp_line *line);
Pablo Neira Ayusoadd3ec82011-07-05 14:45:46 +0200172 void (*close)(struct e1inp_sign_link *link);
Harald Weltefe05cf52011-09-26 23:18:41 +0200173 void (*vty_show)(struct vty *vty, struct e1inp_line *line);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200174 int default_delay;
Jacob Erlbeck86dae842014-01-16 18:10:37 +0100175 int has_keepalive;
Neels Hofmeyr0db1d432016-02-22 13:29:09 +0100176 const char *bind_addr;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200177};
178
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200179struct e1inp_line_ops {
Pablo Neira Ayuso4e862cb2011-08-19 18:43:38 +0200180 union {
181 struct {
182 enum e1inp_line_role role; /* BSC or BTS mode. */
183 const char *addr; /* IP address .*/
184 void *dev; /* device parameters. */
185 } ipa;
186 struct {
187 const char *port; /* e.g. /dev/ttyUSB0 */
188 unsigned int delay;
189 } rs232;
190 } cfg;
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200191
Pablo Neira Ayusoc9c4fd32011-06-30 12:19:42 +0200192 struct e1inp_sign_link * (*sign_link_up)(void *unit_info, struct e1inp_line *line, enum e1inp_sign_type type);
193 void (*sign_link_down)(struct e1inp_line *line);
Pau Espin Pedroled122f32018-08-28 18:25:02 +0200194 /* Called when a new message arrives. -EBADF must be returned if the osmo_fd in link (msg->dst) is destroyed. */
Pablo Neira Ayusodbd82fb2011-07-05 15:29:23 +0200195 int (*sign_link)(struct msgb *msg);
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200196};
197
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200198struct e1inp_line {
199 struct llist_head list;
Pau Espin Pedrol5196cd52020-07-14 17:52:09 +0200200 int refcnt; /* unusued, kept for ABI compat, use_count is used instead */
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200201
202 unsigned int num;
203 const char *name;
Harald Weltec2889512011-09-13 23:49:04 +0100204 unsigned int port_nr;
Alexander Couzensbeb10ef2016-11-01 22:05:13 +0100205 char *sock_path;
Harald Weltef2737fc2011-08-16 14:30:10 +0200206 struct rate_ctr_group *rate_ctr;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200207
Eric Wildef1f3272019-07-10 18:10:31 +0200208 /* tcp keepalive configuration */
Jacob Erlbeck86dae842014-01-16 18:10:37 +0100209 int keepalive_num_probes; /* 0: disable, num, or E1INP_USE_DEFAULT */
210 int keepalive_idle_timeout; /* secs, or E1INP_USE_DEFAULT */
211 int keepalive_probe_interval; /* secs or E1INP_USE_DEFAULT */
212
Eric Wildef1f3272019-07-10 18:10:31 +0200213 /* ipa ping/pong keepalive params */
214 struct ipa_keepalive_params *ipa_kap;
215
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200216 /* array of timestlots */
217 struct e1inp_ts ts[NUM_E1_TS];
Harald Weltec2889512011-09-13 23:49:04 +0100218 unsigned int num_ts;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200219
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200220 const struct e1inp_line_ops *ops;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200221
222 struct e1inp_driver *driver;
223 void *driver_data;
Pau Espin Pedrol5196cd52020-07-14 17:52:09 +0200224
225 struct osmo_use_count use_count;
Keith2672a2a2020-11-12 06:59:37 +0100226
227 /* file name and file descriptor of pcap for this line */
228 char *pcap_file;
229 int pcap_fd;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200230};
Pau Espin Pedrolb5cfc6b2018-10-02 21:22:18 +0200231#define e1inp_line_ipa_oml_ts(line) (&line->ts[0])
232#define e1inp_line_ipa_rsl_ts(line, trx_id) (&line->ts[1 + (trx_id)])
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200233
Harald Weltecc2241b2011-07-19 16:06:06 +0200234/* SS_L_INPUT signals */
Pablo Neira Ayuso332a3572011-08-16 17:31:20 +0200235enum e1inp_signal_input {
Pablo Neira Ayusode668912011-08-16 17:26:23 +0200236 S_L_INP_NONE,
237 S_L_INP_TEI_UP,
238 S_L_INP_TEI_DN,
239 S_L_INP_TEI_UNKNOWN,
240 S_L_INP_LINE_INIT,
241 S_L_INP_LINE_ALARM,
242 S_L_INP_LINE_NOALARM,
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200243};
244
Harald Weltecac78fe2017-05-25 19:13:13 +0200245extern const struct value_string e1inp_signal_names[];
246
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200247/* register a driver with the E1 core */
248int e1inp_driver_register(struct e1inp_driver *drv);
249
250/* fine a previously registered driver */
251struct e1inp_driver *e1inp_driver_find(const char *name);
252
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200253/* get a line by its ID */
Pablo Neira Ayuso3832c4f2011-07-07 17:47:26 +0200254struct e1inp_line *e1inp_line_find(uint8_t e1_nr);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200255
256/* create a line in the E1 input core */
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200257struct e1inp_line *e1inp_line_create(uint8_t e1_nr, const char *driver_name);
258
Pablo Neira Ayuso3832c4f2011-07-07 17:47:26 +0200259/* clone one existing E1 input line */
Pau Espin Pedrol5196cd52020-07-14 17:52:09 +0200260struct e1inp_line *e1inp_line_clone(void *ctx, struct e1inp_line *line, const char *use);
Pablo Neira Ayuso3832c4f2011-07-07 17:47:26 +0200261
262/* increment refcount use of E1 input line */
Pau Espin Pedrol5196cd52020-07-14 17:52:09 +0200263void e1inp_line_get(struct e1inp_line *line) OSMO_DEPRECATED("Use e1inp_line_get2() instead");
Pablo Neira Ayuso3832c4f2011-07-07 17:47:26 +0200264
265/* decrement refcount use of E1 input line, release if unused */
Pau Espin Pedrol5196cd52020-07-14 17:52:09 +0200266void e1inp_line_put(struct e1inp_line *line) OSMO_DEPRECATED("Use e1inp_line_put2() instead");
267
268/* Convenience macros for struct foo instances. These are strict about use count errors. */
269#define e1inp_line_get2(line, USE) OSMO_ASSERT( osmo_use_count_get_put(&(line)->use_count, USE, 1) == 0 );
270#define e1inp_line_put2(line, USE) OSMO_ASSERT( osmo_use_count_get_put(&(line)->use_count, USE, -1) == 0 );
Pablo Neira Ayuso3832c4f2011-07-07 17:47:26 +0200271
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200272/* bind operations to one E1 input line */
273void e1inp_line_bind_ops(struct e1inp_line *line, const struct e1inp_line_ops *ops);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200274
275/* find a sign_link for given TEI and SAPI in a TS */
276struct e1inp_sign_link *
277e1inp_lookup_sign_link(struct e1inp_ts *ts, uint8_t tei,
278 uint8_t sapi);
279
280/* create a new signalling link in a E1 timeslot */
281struct e1inp_sign_link *
282e1inp_sign_link_create(struct e1inp_ts *ts, enum e1inp_sign_type type,
283 struct gsm_bts_trx *trx, uint8_t tei,
284 uint8_t sapi);
285
Pablo Neira Ayuso211d2ca2011-06-07 17:15:10 +0200286/* configure and initialize one signalling e1inp_ts */
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200287int e1inp_ts_config_sign(struct e1inp_ts *ts, struct e1inp_line *line);
Pablo Neira Ayuso211d2ca2011-06-07 17:15:10 +0200288
289/* configure and initialize one timeslot dedicated to TRAU frames. */
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200290int e1inp_ts_config_trau(struct e1inp_ts *ts, struct e1inp_line *line,
Pablo Neira Ayuso211d2ca2011-06-07 17:15:10 +0200291 int (*trau_rcv_cb)(struct subch_demux *dmx, int ch,
Harald Welte5226e5b2020-05-07 23:09:16 +0200292 const ubit_t *data, int len, void *_priv));
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200293
Harald Weltea0108e72016-07-27 21:44:50 +0200294/* configure and initialize one timeslot dedicated to RAW frames */
295int e1inp_ts_config_raw(struct e1inp_ts *ts, struct e1inp_line *line,
296 void (*raw_recv_cb)(struct e1inp_ts *ts,
297 struct msgb *msg));
298
Harald Welte7a228eb2016-07-28 11:09:31 +0200299/* configure and initialize one timeslot dedicated to HDLC frames */
300int e1inp_ts_config_hdlc(struct e1inp_ts *ts, struct e1inp_line *line,
301 void (*hdlc_recv_cb)(struct e1inp_ts *ts,
302 struct msgb *msg));
303
Harald Welteb9031882020-05-02 21:09:15 +0200304/* obtain a string identifier/name for the given timeslot */
305void e1inp_ts_name(char *out, size_t out_len, const struct e1inp_ts *ts);
306
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200307/* Receive a packet from the E1 driver */
308int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
309 uint8_t tei, uint8_t sapi);
Harald Weltefd44a5f2011-08-21 00:48:54 +0200310int e1inp_rx_ts_lapd(struct e1inp_ts *e1i_ts, struct msgb *msg);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200311
312/* called by driver if it wants to transmit on a given TS */
313struct msgb *e1inp_tx_ts(struct e1inp_ts *e1i_ts,
314 struct e1inp_sign_link **sign_link);
315
316/* called by driver in case some kind of link state event */
317int e1inp_event(struct e1inp_ts *ts, int evt, uint8_t tei, uint8_t sapi);
318
Andreas Eversberga7ff0012011-09-26 11:29:30 +0200319/* L2->L3 */
320void e1inp_dlsap_up(struct osmo_dlsap_prim *odp, uint8_t tei, uint8_t sapi,
321 void *rx_cbdata);
322
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200323/* Write LAPD frames to the fd. */
Keith2672a2a2020-11-12 06:59:37 +0100324OSMO_DEPRECATED("Use e1_set_pcap_fd2() instead")
Pablo Neira Ayuso2e11f5c2013-07-05 15:08:18 +0200325int e1_set_pcap_fd(int fd);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200326
Keith2672a2a2020-11-12 06:59:37 +0100327int e1_set_pcap_fd2(struct e1inp_line *line, int fd);
328
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200329/* called by TRAU muxer to obtain the destination mux entity */
330struct subch_mux *e1inp_get_mux(uint8_t e1_nr, uint8_t ts_nr);
331
Harald Welte84f67b22013-06-30 13:13:59 +0200332/* on an IPA BTS, the BTS needs to establish the RSL connection much
333 * later than the OML connection. */
334int e1inp_ipa_bts_rsl_connect(struct e1inp_line *line,
335 const char *rem_addr, uint16_t rem_port);
336
Andreas Eversbergf422a752014-01-21 14:54:41 +0100337int e1inp_ipa_bts_rsl_connect_n(struct e1inp_line *line,
338 const char *rem_addr, uint16_t rem_port,
339 uint8_t trx_id);
340
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200341void e1inp_sign_link_destroy(struct e1inp_sign_link *link);
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200342int e1inp_line_update(struct e1inp_line *line);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200343
Pablo Neira Ayuso262aee82011-07-05 19:17:08 +0200344int e1inp_vty_init(void);
345
Alexander Couzensbeb10ef2016-11-01 22:05:13 +0100346/* activate superchannel or deactive to use timeslots. only valid for unixsocket driver */
347void e1inp_ericsson_set_altc(struct e1inp_line *unixlinue, int superchannel);
348
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200349extern struct llist_head e1inp_driver_list;
350extern struct llist_head e1inp_line_list;
351
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200352/* XXX */
353struct input_signal_data {
Pau Espin Pedrol41792072018-10-03 13:18:37 +0200354 enum e1inp_sign_type link_type;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200355 uint8_t tei;
356 uint8_t sapi;
Harald Weltef35d8892016-10-16 15:33:52 +0200357 uint8_t ts_nr;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200358 struct gsm_bts_trx *trx;
359 struct e1inp_line *line;
360};
361
Pablo Neira Ayuso96e72632011-06-26 19:08:05 +0200362int abis_sendmsg(struct msgb *msg);
Holger Hans Peter Freyther180ce7e2012-02-03 20:06:15 +0100363int abis_rsl_sendmsg(struct msgb *msg);
Pablo Neira Ayuso96e72632011-06-26 19:08:05 +0200364
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200365#endif /* _E1_INPUT_H */