#include "../libtimer/timer.h" #include "../libosmocc/endpoint.h" #include "../libsample/sample.h" #include "../libjitter/jitter.h" #include "../libdtmf/dtmf_decode.h" #include "../libph_socket/ph_socket.h" #include "callerid.h" #include "tones.h" enum pstn_state { PSTN_STATE_OOS = 0, /* out of service */ PSTN_STATE_NULL, /* no call */ PSTN_STATE_EST_LE, /* requested establisment, waiting for reply */ PSTN_STATE_EST_AN, /* not used here */ PSTN_STATE_ACTIVE, /* path active */ PSTN_STATE_DISC_REQ, /* requested disconnect, waiting for reply */ PSTN_STATE_BLOCKED, /* not used here */ }; enum pstn_event { PSTN_EVENT_EST_REQ = 0x00, /* establishment towards interface */ PSTN_EVENT_EST_ACK_IND = 0x03, /* establishment acknowledge from interface */ PSTN_EVENT_EST_IND = 0x01, /* establishment from interface */ PSTN_EVENT_EST_ACK_REQ = 0x02, /* establishment acknowledge towards interface */ PSTN_EVENT_SIG_REQ = 0x10, /* line signal towards interface */ PSTN_EVENT_SIG_IND = 0x11, /* line signal from interface */ PSTN_EVENT_PARAM_REQ = 0x20, /* parameter request towards interface */ PSTN_EVENT_DISC_REQ = 0x30, /* disconnect towards interface (ACTIVE sate) */ PSTN_EVENT_DISC_CPL_REQ = 0x32, /* disconnect towards interface (PATH INITIATED states) */ PSTN_EVENT_DISC_CPL_IND = 0x33, /* disconnect from interface */ }; enum pstn_v5_ie { PSTN_V5_IE_CADENCED_RINGING = 0x01, PSTN_V5_IE_PULSED_SIGNAL = 0x02, PSTN_V5_IE_STEADY_SIGNAL = 0x03, PSTN_V5_IE_DIGIT_SIGNAL = 0x04, }; enum pstn_v5_signal { PSTN_V5_STEADY_SIGNAL_OFF_HOOK = 0x04, PSTN_V5_STEADY_SIGNAL_ON_HOOK = 0x05, PSTN_V5_STEADY_SIGNAL_STOP_RING = 0x0e, PSTN_V5_PULSED_SIGNAL_ON_HOOK = 0x7c, }; enum timer_ident { TIMER_IDENT_DIALING, TIMER_IDENT_RELEASE, TIMER_IDENT_HOOKFLASH, }; #define PSTN_CALL_ACTIVE 0 #define PSTN_CALL_HOLD 1 enum pstn_call_state { CALL_STATE_NULL = 0, CALL_STATE_ENBLOCK, CALL_STATE_ALERTING_SUB, CALL_STATE_OVERLAP_NET, CALL_STATE_PROCEEDING_NET, CALL_STATE_ALERTING_NET, CALL_STATE_ACTIVE, CALL_STATE_HOLD, CALL_STATE_DISCONNECT_NET, }; enum pstn_cid_state { PSTN_CID_STATE_OFF = 0, PSTN_CID_STATE_WAIT1, PSTN_CID_STATE_SEND, PSTN_CID_STATE_WAIT2, }; enum tones_type { TONES_TYPE_AMERICAN, TONES_TYPE_GERMAN, TONES_TYPE_OLDGERMAN, }; struct pstn; struct call { struct pstn *pstn; uint32_t cc_callref; enum pstn_call_state state; int subscriber_index; /* subscriber the calls is associated with */ const char *sdp; osmo_cc_session_t *cc_session; osmo_cc_session_codec_t *codec; int on_hold; /* track hold/retrieval notification */ }; typedef struct pstn { osmo_cc_endpoint_t cc_ep; /* settings */ char law; /* 'a'-law or 'u'-law */ const char *name; const char **subscribers; /* subscriber number (caller ID of PSTN port) */ int subscriber_num; /* number of subscribers and tinging types (incoming) */ int serving_location; /* who we serve when sending causes towards interface */ int tx_delay; /* delay to be used for fax/modem jitter buffering */ int clip; /* send caller ID */ int clip_date; /* send date with caller ID */ int cid_bell; /* use V.23 or Bell 202 FSK tones */ int cid_dtmf; /* use DTMF instead of FSK caller ID */ int enblock; /* receive digits before transmitting them via SETUP message (timeout as given) */ int recall; /* support recall / waiting call */ int *ringing_types_incoming;/* cadenced rining on incoming call */ int ringing_type_hold; /* cadenced rining on waiting call */ enum tones_type tones_type; /* what tone set to use */ /* states */ enum pstn_state state; struct timer timer; /* timer for enblock dialing */ enum timer_ident timer_ident; /* why is the timer running */ char dialing[33]; /* register for en-block dialing */ int dtmf_on; /* we are listening to DTMF */ int pulse_on; /* we take pulses */ enum pstn_cid_state callerid_state; /* transmitting callerid */ int callerid_wait1; /* wait (number of samples) until transmitting caller ID */ int callerid_wait2; /* wait (number of samples) after transmitting caller ID */ int b_transmitting; /* transmitting on b-channel */ /* v5 interface */ ph_socket_t ph_socket; /* osmo-cc states (active and hold ) */ struct call *call[2]; /* audio states */ int audio_path; /* (early/late) audio is connected */ jitter_t tx_dejitter; /* jitter buffer */ dtmf_dec_t dtmf_dec; /* DTMF tone detection */ struct isdn_tone isdn_tone; /* tone generator */ callerid_t callerid; /* caller ID transmission */ uint8_t tx_buffer[160]; /* transmit audio buffer */ int tx_buffer_pos; /* current position in transmit audio buffer */ } pstn_t; void pstn_destroy(pstn_t *pstn_ep); pstn_t *pstn_create(void); int pstn_init(pstn_t *pstn, const char *name, const char *socketname, const char **subscribers, int subscriber_num, uint8_t serving_location, int tx_delay, int clip, int cid_bell, int cid_dtmf, int clip_date, int enblock, int recall, int *ringing_types_incoming, int ringing_type_hold, enum tones_type tones_type, char law); void cc_message(osmo_cc_endpoint_t *ep, uint32_t callref, osmo_cc_msg_t *msg); void rtp_work(pstn_t *pstn_ep); void pstn_work(pstn_t *pstn_ep);