126 lines
3.1 KiB
C
126 lines
3.1 KiB
C
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <osmocom/core/select.h>
|
|
#include <osmocom/core/hashtable.h>
|
|
#include <osmocom/core/isdnhdlc.h>
|
|
#include <osmocom/core/write_queue.h>
|
|
#include <osmocom/vty/command.h>
|
|
|
|
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);
|