#pragma once #include #include #include #include #include #include #include enum { ISDNTAP_NODE = _LAST_OSMOVTY_NODE + 1, LINE_NODE, }; /* number of octets in an information field */ #define Q921_N201 260 #define Q921_ADDR_SIZE 2 #define Q921_CTRL_SIZE 2 #define Q921_FCS_SIZE 2 #define HDLC_FRAME_SIZE (Q921_N201 + Q921_ADDR_SIZE + Q921_CTRL_SIZE + Q921_FCS_SIZE) struct isdntap_line; enum isdntap_ts_mode { E1_TS_TRACE_MODE_NONE, E1_TS_TRACE_MODE_RAW, /* RAW bitstream */ E1_TS_TRACE_MODE_HDLC, /* generic HDLC mode */ E1_TS_TRACE_MODE_ISDN_D, /* ISDN D-Channel (Q.921 + Q.931) */ }; /* one "complete" HDLC decoder state */ struct isdntap_hdlc_state { struct osmo_isdnhdlc_vars vars; uint8_t out[HDLC_FRAME_SIZE]; }; /* isdntap state for one timeslot */ struct isdntap_ts { struct isdntap_line *line; /* back-pointer */ uint8_t num; /* timeslot number */ enum isdntap_ts_mode mode; uint8_t gsmtap_subtype; // GSMTAP_E1T1_LAPD struct { /* two soft-HDLC instances, one for each direction */ struct isdntap_hdlc_state state[2]; } hdlc; union { struct { struct osmo_fd rx; /* RX-mirror file descriptor */ struct osmo_fd tx; /* TX-mirror file descriptor */ int channo; /* DAHDI channel number for this TS */ } dahdi; } driver; union { struct { struct osmo_wqueue rx; struct osmo_wqueue tx; } file; } output; }; /* isdntap state for one line/span */ struct isdntap_line { struct llist_head list; /* member in list of all isdntap_lines */ const char *name; /* human-readable name */ struct isdntap_instance *inst; /* back-pointer */ struct gsmtap_inst *gti; /* gsmtap instance through which we log */ void *priv; /* private back-pointer (e.g. to e1d line) */ struct isdntap_ts ts[32]; /* per-timeslot state */ /* signalling state */ struct { } q921; struct { DECLARE_HASHTABLE(call_state, 8); } q931; struct rate_ctr_group *ctrs; union { struct { const char *name; const char *spantype; int spanno; int basechan; int channels; } dahdi; } driver; }; struct isdntap_driver { const char *name; int (*line_open)(struct isdntap_line *line); void (*line_close)(struct isdntap_line *line); int (*ts_open)(struct isdntap_ts *ts); void (*ts_close)(struct isdntap_ts *ts); }; /* drivers feed data into the isdntap core via this API */ int isdntap_ts_rx_dchan(struct isdntap_ts *ts, const uint8_t *buf, size_t len, bool net2user); int isdntap_ts_rx_bchan(struct isdntap_ts *ts, const uint8_t *buf, size_t len, bool net2user); /* DAHDI driver */ extern const struct isdntap_driver dahdi_driver; struct isdntap_instance { struct llist_head lines; struct { const char *output_path; } cfg; }; struct isdntap_line *isdntap_line_find(struct isdntap_instance *itd, const char *name); struct isdntap_line *isdntap_line_new(struct isdntap_instance *itd, const char *name); void isdntap_vty_init(struct isdntap_instance *itd); int isdntap_ts_start_bchan(struct isdntap_ts *ts, const char *call_label); void isdntap_ts_stop_bchan(struct isdntap_ts *ts);