osmo-isdntap/src/isdntap.h

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);