osmo-cc-pstn-endpoint/src/pstn/pstn.h

171 lines
5.7 KiB
C

#include "../libtimer/timer.h"
#include "../libselect/select.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_NORMAL = 0x00,
PSTN_V5_STEADY_SIGNAL_REVERSED = 0x01,
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_INIT_RING = 0x79,
PSTN_V5_PULSED_SIGNAL_REG_RECAL = 0x76,
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_method {
CID_METHOD_NONE = 0,
CID_METHOD_PULSE,
CID_METHOD_STOP,
CID_METHOD_DTAS,
CID_METHOD_DTAS_LR,
};
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 */
};
struct dial_hint {
struct dial_hint *next;
size_t length;
char *from, *to;
};
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 */
enum pstn_cid_method 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) */
struct dial_hint dial_hints; /* list of numbers that are complete */
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 reversed; /* if polarity is reversed */
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;
int add_dial_hint(const char *arg);
void purge_dial_hints(void);
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, enum pstn_cid_method 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);