Skip to content
Snippets Groups Projects
chan_voicemngr.h 9.66 KiB
Newer Older
  • Learn to ignore specific revisions
  • /* IOPSYS Software Solutions AB
     * Asterisk Channel for FXS and DECT
    
    #ifndef CHAN_VOICEMNGR_H
    #define CHAN_VOICEMNGR_H
    
    #define CALL_STATUS_MAX_LEN 14
    
    Yalu Zhang's avatar
    Yalu Zhang committed
    // RTP payload type
    #define RTP_PT_PCMU 0
    #define RTP_PT_G726 2
    #define RTP_PT_G723 4
    #define RTP_PT_PCMA 8
    #define RTP_PT_G722 9
    #define RTP_PT_CN   13
    #define RTP_PT_G729 18
    #define RTP_PT_DTMF 101
    
    
    #define DEFAULT_PTIME 20 //ms
    
    
    #define NOT_INITIALIZED    -1
    #define MAX_NUM_LINEID     30
    
    #define PACKET_BUFFER_SIZE 1024
    
    #define MAX_SIP_CLIENTS    5
    
    
    #define BEGIN 0
    #define CONT  1
    #define END   2
    
    
    #define DEFAULT_CALL_WAITING_TIMEOUT         20   // In seconds
    #define DEFAULT_CALL_WAITING_TONE_INVTERVAL  5    // In seconds
    #define DEFAULT_R4_HANGUP_TIMEOUT            5000 // In milliseconds
    #define DEFAULT_ONHOLD_HANGUP_TIMEOUT        20   // In seconds
    
    
    // RTP header info
    #define RTP_VERSION     2
    #define RTP_MARKER_BIT  (1<<7)
    
    
    enum chan_voicemngr_channel_state {
    
    	CALLENDED,
    	RINGING,
    	CALLWAITING,
    	ONHOLD,
    	TRANSFERING,
    	RINGBACK,
    	AWAITONHOOK,
    	ALLOCATED,
    };
    
    
    enum LINE_EVENT { // Events from low level line (endpoint etc.)
    
    	EVENT_DTMF0,
    	EVENT_DTMF1,
    	EVENT_DTMF2,
    	EVENT_DTMF3,
    	EVENT_DTMF4,
    	EVENT_DTMF5,
    	EVENT_DTMF6,
    	EVENT_DTMF7,
    	EVENT_DTMF8,
    	EVENT_DTMF9,
    	EVENT_DTMFA,
    	EVENT_DTMFB,
    	EVENT_DTMFC,
    	EVENT_DTMFD,
    	EVENT_DTMFH,
    	EVENT_DTMFS,
    	EVENT_OFFHOOK,
    	EVENT_ONHOOK,
    	EVENT_FLASH,
    
    	EVENT_SWITCH,
    	EVENT_JOIN,
    	EVENT_RELEASE,
    
    	EVENT_LINE_CALL_MODE_SINGLE,
    	EVENT_LINE_CALL_MODE_MULTIPLE,
    
    	EVENT_LAST,
    };
    
    enum endpoint_type {
    	FXS,
    	FXO,
    	DECT,
    };
    
    
    enum CALL_DIRECTION {
    	INCOMING_CALL,
    	OUTGOING_CALL,
    };
    
    
    enum LINE_CALL_MODE {
    	LINE_CALL_MODE_SINGLE,
    	LINE_CALL_MODE_MULTIPLE,
    };
    
    
    
    typedef enum dialtone_state {
    	DIALTONE_OFF = 0,
    	DIALTONE_ON,
    	DIALTONE_CONGESTION,
    	DIALTONE_SPECIAL_CONDITION,
    
    	DIALTONE_UNOBTAINABLE,
    	DIALTONE_HOWLER,
    
    Wenpeng Song's avatar
    Wenpeng Song committed
    	DIALTONE_MWI_OFF,
    
    	DIALTONE_LAST,
    } dialtone_state;
    
    
    struct line_stats_t {
    	uint32_t rxpkts;
    	uint32_t txpkts;
    	uint32_t rxbytes;
    	uint32_t txbytes;
    
    	uint32_t pktslost;
    
    	uint32_t total_overruns;
    	uint32_t total_underruns;
    
    /*
     * Common part of RTCP header according to https://datatracker.ietf.org/doc/html/rfc1889#section-6.3.1
     */
    #define RTCP_SR      200
    #define RTCP_RR      201
    #define RTCP_SDES    202
    
    #define RTCP_XR      207
    struct __attribute__((packed)) rtcp_header_t {
    	uint8_t  v_p_rc; // Version, padding and reception report count
    	uint8_t  pt;     // Packet type
    	/* The length of RTCP packet in 32-bit words minus 1, including the header and padding if any.
    	 * For a compound RTCP packet which contains more than one payload type, e.g. SR + SDES + XR, length is
    	 * just for one single RTCP packet instead of all packets. */
    	uint16_t length;
    	uint32_t ssrc;   // Synchronization source identifier for the originator
    };
    #define RTCP_PKT_END(header)                    ((uint8_t *)(header) + (ntohs((header)->length) + 1) * 4)
    #define RTCP_GET_VERSION(header)                ((header)->v_p_rc >> 6)
    
    #define RTCP_GET_RC(header)                	((header)->v_p_rc & 0x1F)
    
    #define RTCP_SR_GET_INTERARRIVAL_JITTER(header) ntohl(*((uint32_t *)(header) + 10))
    
    #define RTCP_RR_GET_INTERARRIVAL_JITTER(header) ntohl(*((uint32_t *)(header) + 5))
    
    #define RTCP_XR_GET_ROUND_TRIP_DELAY(header)    ntohs(*((uint16_t *)(header) + 12))
    
    struct chan_voicemngr_subchannel {
    
    	int call_id;			/* The call_id of connection assigned by pjsip */
    
    	struct ast_channel *owner;	/* Channel we belong to, possibly NULL */
    
    	int connection_id;		/* Current connection id, may be -1 */
    
    	enum chan_voicemngr_channel_state channel_state;	/* Channel states */
    
    	enum CALL_DIRECTION call_direction;		// Direction of call for the subchannel : 0 = incoming, 1 = outgoing
    
    	unsigned int connection_init;	/* State for endpoint id connection initialization */
    	struct ast_frame fr;		/* Frame */
    
    	uint16_t sequence_number;	/* Endpoint RTP sequence number state */
    
    	unsigned int time_stamp;	/* Endpoint RTP time stamp state */
    
    	unsigned int period;		/* Endpoint RTP period */
    
    	int dtmf_pt;
    
    	int codec;			/* Used codec */
    
    	struct chan_voicemngr_pvt *parent;	/* chan_voicemngr_line owning this subchannel */
    
    	int cw_timer_id;			/* Current call waiting timer id, -1 if no active timer */
    	int cw_tone_timer_id;		/* Current call waiting beep timer id, -1 if no active timer */
    
    	int r4_hangup_timer_id;		/* Current R4 hangup timer id, -1 if no active timer */
    	int onhold_hangup_timer_id;	/* Current onhold hangup timer id, -1 if no active timer */
    	int conference_initiator;       /* True if this subchannel is the original leg in a 3-way conference */
    	char *conference_id;            /* uuid of the conference initiated by this subchannel */
    
    	int conf_timer_id;              /* Current conference call timer id, -1 if no active timer */
    	rtp_statistics rtp_stats;	/* RTP statistics for currently hanging up channel */
    
    	unsigned int ingressRtcpPackets;
    	unsigned int egressRtcpPackets;
    	unsigned int ingressRtcpXrPackets;
    	unsigned int egressRtcpXrPackets;
    
    	unsigned int farEndInterarrivalJitter;
    	unsigned int receiveInterarrivalJitter;
    	unsigned long int totalFarEndInterarrivalJitter;
    	unsigned long int totalReceiveInterarrivalJitter;
    
    	unsigned int localAvgRoundTripDelay;
    	unsigned int remoteAvgRoundTripDelay;
    
    	char blind_xfer_target[32];	/* Transfer target for unattended call transfer */
    
    	int sip_client_id;	/* The SIP client used for the current call: -1 = not set, 0 = internal call, 1..MAX_SIP_CLIENTS = sip client id*/
    
    struct chan_voicemngr_channel_tech {
    	int (* signal_ringing)(struct chan_voicemngr_pvt *p);
    	int (* signal_ringing_callerid_pending)(struct chan_voicemngr_pvt *p);
    
    	int (* signal_callerid)(struct ast_channel *chan, struct chan_voicemngr_subchannel *s, int callwt);
    
    	int (* stop_ringing)(struct chan_voicemngr_pvt *p);
    	int (* stop_ringing_callerid_pending)(struct chan_voicemngr_pvt *p);
    	int (* release)(struct chan_voicemngr_pvt *p);
    
    struct chan_voicemngr_pvt {
    
    	ast_mutex_t lock;
    	int fd;							/* Raw file descriptor for this device */
    	int line_id;				/* Maps to the correct port */
    	char dtmfbuf[AST_MAX_EXTENSION];/* DTMF buffer per channel */
    	int dtmf_len;					/* Length of DTMF buffer */
    	int dtmf_first;					/* DTMF control state, button pushes generate 2 events, one on button down and one on button up */
    	struct ast_format_cap * lastformat;            /* Last output format */
    	struct ast_format_cap * lastinput;             /* Last input format */
    
    	struct chan_voicemngr_pvt *next;			/* Next channel in list */
    
    	char offset[AST_FRIENDLY_OFFSET];
    	char buf[PHONE_MAX_BUF];					/* Static buffer for reading frames */
    	char context_direct[AST_MAX_EXTENSION];
    	char context[AST_MAX_EXTENSION];
    	char obuf[PHONE_MAX_BUF * 2];
    	char ext[AST_MAX_EXTENSION];
    	char language[MAX_LANGUAGE];
    	char cid_num[AST_MAX_EXTENSION];
    	char cid_name[AST_MAX_EXTENSION];
    
    	char extensionCallStatus[CALL_STATUS_MAX_LEN];
    
    	struct chan_voicemngr_subchannel *sub[NUM_SUBCHANNELS];	/* List of sub-channels, needed for callwaiting and 3-way support */
    
    	int hf_detected;			/* Hook flash detected */
    	dialtone_state dialtone;		/* Set by manager command */
    
    	struct chan_voicemngr_channel_tech *tech;
    
    
    	int interdigit_timer_id;		/* Id of timer that tracks interdigit timeout */
    	int autodial_timer_id;			/* Id of timer that tracks autodial timeout */
    	int dialtone_timeout_timer_id;	/* Id of timer that tracks dialtone timeout */
    	int onhold_hangup_timer_id;		/* Id of timer that tracks onhold hangup timeout */
    
    	int emergency;                  /* Emergency call flag for local handling: ignore flash-hook, deny any incoming calls */
    
    
    #define VOICEMNGR_CHAN_FLAG_ATTENDED_TRANSFER	0x1
    	unsigned int flags;
    
    	CHAN_VOICEMNGR_UNKNOWN,
    	CHAN_VOICEMNGR_AUDIO,
    	CHAN_VOICEMNGR_RTCP_SR,
    	CHAN_VOICEMNGR_RTCP_RR
    
    };
    
    /* Mapping of DTMF to char/name/intval */
    typedef struct DTMF_CHARNAME_MAP
    {
    	enum LINE_EVENT	event;
    	char	name[12];
    	char	c;
    	int		i;
    } DTMF_CHARNAME_MAP;
    
    
    
    typedef enum flash_spec {
    	FLASH_SPEC_UK = 0,
    	FLASH_SPEC_ETSI,
    } flash_spec;
    
    
    typedef struct DIALTONE_MAP
    {
    	dialtone_state	state;
    
    } DIALTONE_MAP;
    
    static const DIALTONE_MAP dialtone_map[] =
    {
    
    	{DIALTONE_OFF, "off"},
    	{DIALTONE_ON, "on"},
    	{DIALTONE_CONGESTION, "congestion"},
    
    	{DIALTONE_SPECIAL_CONDITION, "special"},
    
    	{DIALTONE_UNOBTAINABLE, "number unobtainable"},
    	{DIALTONE_HOWLER, "howler"},
    
    	{DIALTONE_UNKNOWN, "unknown"},
    	{DIALTONE_MWI_OFF, "mwi_off"},
    
    	{DIALTONE_K_BREAK, "k-break"},
    
    };
    
    /* Struct for individual endpoint settings */
    typedef struct {
    
    	char language[MAX_LANGUAGE];
    	char cid_num[AST_MAX_EXTENSION];
    	char cid_name[AST_MAX_EXTENSION];
    	char context_direct[AST_MAX_EXTENSION]; //Context that will be checked for exact matches
    	char context[AST_MAX_EXTENSION]; //Default context for dialtone mode
    	char autodial_ext[AST_MAX_EXTENSION];
    	int autodial_timeoutmsec;
    	int ringsignal;
    	int timeoutmsec;
    
    	int interdigitopenmsec;
    	int minimumnumberdigits;
    	char terminationdigit;
    
    	int period;
    	int hangup_xfer;
    	int dialtone_timeoutmsec;
    
    	int offhook_nu_timeoutmsec;
    	int offhook_silence_timeoutmsec;
    
    	int do_not_disturb;
    
    	int anonymouscallenable;
    
    	int calleridenable;
    	int calleridnameenable;
    
    	int mwi_enabled;
    
    	char emergency_numbers_list[AST_MAX_EXTENSION];
    
    
    /* Caller ID */
    #define CLID_MAX_DATE	10
    
    #define CLID_MAX_NUMBER	21
    
    #define CLID_MAX_NAME	16
    typedef struct CLID_STRING
    {
    	char date[CLID_MAX_DATE];
    	char number_name[CLID_MAX_NUMBER + CLID_MAX_NAME + 4]; // 4 = comma, quotation marks and null terminator
    } CLID_STRING;
    
    
    #endif /* CHAN_VOICEMNGR_H */