osmo-cc-misdn-endpoint/src/isdn/isdn.h

214 lines
6.3 KiB
C

#include <pthread.h>
#include "../libtimer/timer.h"
#include "../libosmocc/endpoint.h"
#include "../libosmocc/helper.h"
#include "../libsample/sample.h"
#include "../libjitter/jitter.h"
#include "../libph_socket/ph_socket.h"
#define B_MODE_TRANSPARENT 0
#define B_MODE_HDLC 1
#define B_STATE_IDLE 0 /* not open */
#define B_STATE_ACTIVATING 1 /* DL_ESTABLISH sent */
#define B_STATE_ACTIVE 2 /* channel active */
#define B_STATE_DEACTIVATING 3 /* DL_RELEASE sent */
#define B_EVENT_USE 0 /* activate bchannel */
#define B_EVENT_ACTIVATED 1 /* DL_ESTABLISH received */
#define B_EVENT_DROP 2 /* deactivate bchannel */
#define B_EVENT_DEACTIVATED 3 /* DL_RELEASE received */
#define B_EVENT_TIMEOUT 4 /* timeout happed during (de)activation */
#define TONES_TYPE_AMERICAN 1
#define TONES_TYPE_GERMAN 2
#define TONES_TYPE_OLDGERMAN 3
#define DIRECTION_ORIGINATOR 0
#define DIRECTION_TERMINATOR 1
enum isdn_state {
ISDN_STATE_IDLE = 0, /* no call */
ISDN_STATE_IN_SETUP, /* incoming connection */
ISDN_STATE_OUT_SETUP, /* outgoing connection */
ISDN_STATE_IN_OVERLAP, /* more informatiopn needed */
ISDN_STATE_OUT_OVERLAP, /* more informatiopn needed */
ISDN_STATE_IN_PROCEEDING,/* call is proceeding */
ISDN_STATE_OUT_PROCEEDING,/* call is proceeding */
ISDN_STATE_IN_ALERTING, /* call is ringing */
ISDN_STATE_OUT_ALERTING,/* call is ringing */
ISDN_STATE_IN_CONNECTING,/* wait for ack after answer */
ISDN_STATE_OUT_CONNECTING,/* wait for ack after answer */
ISDN_STATE_CONNECT, /* call is connected and transmission is enabled */
ISDN_STATE_IN_DISCONNECT,/* incoming disconnected */
ISDN_STATE_OUT_DISCONNECT,/* outgoing disconnected */
ISDN_STATE_OUT_RELEASE, /* call released */
ISDN_STATE_SUSPENDED, /* call suspended */
};
struct isdn;
struct b_timer_inst {
struct isdn *isdn_ep;
int index;
};
struct msn_list {
struct msn_list *next;
char msn[0];
};
struct select_channel {
struct select_channel *next;
int channel;
};
struct call_list;
typedef struct isdn {
struct call_list *call_list;
struct msn_list *msn_list;
/* settings */
char law;
struct select_channel *out_channel; /* list of outgoing channels to select */
struct select_channel *in_channel; /* the same for incoming channels */
int out_channel_exclusive; /* force channel */
int serving_location; /* who we serve when sending causes towards interface */
const char *timeouts;
int tx_delay;
int tx_gain;
int rx_gain;
const char *pipeline;
int dtmf;
int local_tones;
/* osmo-cc */
struct osmo_cc_endpoint cc_ep;
/* mISDN */
char *portname;
int portnum;
int ntmode;
int ptp;
int pri;
int l1hold;
int l2hold;
int l2sock;
void *l2inst;
ph_socket_t *ph_socket;
pthread_mutex_t upqueue_lock;
struct mqueue upqueue;
int upqueue_initialized;
struct mlayer3 *ml3;
int los, ais, rdi, slip_rx, slip_tx;
int l1link; /* current state */
int l2link; /* current state */
struct timer l2establish_timer;
int b_num;
int b_reserved;
int b_mode[128];
int b_state[128];
int b_sock[128];
struct call_list *b_call[128];
struct timer b_timer[128];
struct b_timer_inst b_timer_inst[128];
uint8_t b_buffer[128][160];
int b_buffer_pos[128];
unsigned char l2mask[16]; /* 128 bits for each tei */
} isdn_t;
typedef struct call_list {
struct call_list *next;
isdn_t *isdn_ep;
/* mISDN states */
uint32_t l3_pid;
uint16_t l3_ces;
int tx_gain;
int rx_gain;
int mute;
int txdata;
int tx_delay;
int echo;
uint32_t bridge;
int tone;
int rxoff;
int dtmf;
int dtmf_threshold;
const char *pipeline;
/* osmo-cc states */
uint32_t cc_callref;
osmo_cc_session_t *cc_session;
osmo_cc_session_codec_t *codec;
const char *sdp;
char codec_law;
int codec_negotiated;
int audio_path;
/* bchannel states */
int b_index;
int b_channel;
int b_exclusive;
int b_reserve;
int b_mode;
/* call states */
int direction; /* originator or terminator of call */
enum isdn_state state;
int any_dialing; /* if any digit was dialed, we track this for dial tone */
int channel_negotiated;
int send_local_tones; /* using locally generated tones, because upper layer does not provide them */
int send_remote_tones; /* using remote tones, as we received a progress indicator 1 or 8 from upper layer */
int proceeding_sent;
int sending_complete; /* send proceeding when osmo-cc requests overlap */
int setup_comp_req_channel_assignment; /* must assign channel on setup comp req */
uint8_t collect_cause, collect_location;
int hold; /* if call is on hold */
int conference_3pty; /* if call is the active call in a 3pty conference */
int park_len;
uint8_t park_callid[8];
/* bridge states */
int local_bridge; /* if local peer can bridge */
int remote_bridge; /* if remote peer can bridge */
/* jitter buffer for 3pty call */
jitter_t dejitter;
} call_t;
int check_mISDN_dsp(void);
/* channel selection */
int hunt_bchannel_in(isdn_t *isdn_ep, int channel, int exclusive);
int hunt_bchannel_out(isdn_t *isdn_ep, int *channel, int *exclusive);
int open_bchannel_in(call_t *call, int channel, int exclusive);
int open_bchannel_out(call_t *call, unsigned int cmd, int channel, int exclusive);
/* isdn instance */
isdn_t *isdn_create(void);
void isdn_destroy(isdn_t *isdn_ep);
int isdn_initialize(isdn_t *isdn_ep, ph_socket_t *ph_socket, char law, const char *portname, int ntmode, int ptp, int layer1hold, int layer2hold, const char *channel_out, const char *channel_in, const char *timeouts, int tx_delay, int tx_gain, int rx_gain, const char *pipeline, int dtmf, int local_tones, int serving_location);
int isdn_open(isdn_t *isdn_ep);
void isdn_close(isdn_t *isdn_ep);
void isdn_add_msn(isdn_t *isdn_ep, const char *msn);
int isdn_dchannel_work(isdn_t *isdn_ep);
void isdn_bchannel_work(isdn_t *isdn_ep);
void isdn_rtp_work(isdn_t *isdn_ep);
/* call instance */
call_t *call_create(isdn_t *isdn_ep, int direction, int channel, int exclusive, int mode);
void call_destroy(call_t *call);
/* channel allocation and handling */
void bchannel_tone(call_t *call, int tone);
void bchannel_bridge(call_t *call, uint32_t bridge);
void bchannel_event(isdn_t *isdn_ep, int index, int event);
int seize_bchannel(call_t *call, int channel, int exclusive);
void drop_bchannel(call_t *call);
void bchannel_send(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint8_t *data, int len);