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

226 lines
6.6 KiB
C

#include <pthread.h>
#include "../libtimer/timer.h"
#include "../libselect/select.h"
#include "../libosmocc/endpoint.h"
#include "../libosmocc/helper.h"
#include "../libsample/sample.h"
#include "../libjitter/jitter.h"
#include "../libph_socket/ph_socket.h"
#include "tones.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 isdn;
struct isdn_b_sock {
int index;
struct isdn *isdn_ep;
struct osmo_fd ofd;
};
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 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;
int upqueue_pipe[2];
struct osmo_fd upqueue_ofd;
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];
struct isdn_b_sock 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 */
/* bridging */
int bridge_possible;
int bridge_cardnum;
int bridge_portnum;
/* clock for tone on hold */
struct timer clock_timer;
double last_time_clock;
} isdn_t;
typedef struct call_list {
struct call_list *next;
isdn_t *isdn_ep;
/* mISDN states */
uint32_t l3_pid;
uint16_t l3_ces;
/* tone states */
struct isdn_tone isdn_tone;
/* 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;
int b_transmitting;
double b_rx_time;
/* 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 can_bridge; /* last state sent to the server */
int bridge_enabled; /* last state received by the server */
int bridge_bank_tx;
int bridge_slot_tx;
int bridge_bank_rx;
int bridge_slot_rx;
/* jitter buffer for tx and 3pty call */
jitter_t tx_dejitter;
jitter_t conf_dejitter;
} call_t;
/* 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 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);
/* call instance */
call_t *call_create(isdn_t *isdn_ep, int direction, int channel, int exclusive, int mode);
void call_create_jitter(call_t *call, int data);
void call_destroy(call_t *call);
/* channel allocation and handling */
void bchannel_tone(call_t *call, int tone);
void bchannel_bridge(call_t *call, int pcm_bridge, int rx_slot, int tx_slot, int rx_bank, int tx_bank);
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 rtp_receive(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len);
void enable_hold_clock(isdn_t *isdn_ep);