#include #include #include #include #include #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 TONES_TYPE_MORSEGERMAN 4 #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; /* metering/AOC-D/AOC-S */ int aocd; int aocs; /* 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; int time_no_sec; 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 osmo_timer_list 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 osmo_timer_list 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 osmo_timer_list 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]; /* metering/AOC-D/AOC-S */ struct osmo_timer_list metering_unit_timer; int metering_info_received; struct timeval metering_unit_period; uint16_t metering_connect_units; uint16_t metering_total_units; /* 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 aocd, int aocs, int time_no_sec); 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);