Newer
Older
/* IOPSYS Software Solutions AB
* Asterisk Channel for FXS and DECT
#ifndef CHAN_VOICEMNGR_H
#define CHAN_VOICEMNGR_H
#define PHONE_MAX_BUF 480
#define CALL_STATUS_MAX_LEN 14
// 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 NOT_INITIALIZED -1
#define MAX_NUM_LINEID 30
#define PACKET_BUFFER_SIZE 1024
#define NUM_SUBCHANNELS 2
#define MAX_SIP_CLIENTS 5
#define BEGIN 0
#define CONT 1
#define END 2

Yalu Zhang
committed
#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 {
ONHOOK,
OFFHOOK,
DIALING,
CALLING,
INCALL,
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_CALL_REJECT,
EVENT_DECT_UNAVAILABLE,
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,
DIALTONE_LAST,
} dialtone_state;
struct line_stats_t {
uint32_t rxpkts;
uint32_t txpkts;
uint32_t rxbytes;
uint32_t txbytes;
Grzegorz Sluja
committed
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_BYE 203
#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 */
enum ast_sip_dtmf_mode dtmf_mode;
int codec; /* Used codec */
struct chan_voicemngr_pvt *parent; /* chan_voicemngr_line owning this subchannel */

Yalu Zhang
committed
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 */
Wenpeng Song
committed
int updated_codec;
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*/
int congestion_timer_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);
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 */

Yalu Zhang
committed
#define VOICEMNGR_CHAN_FLAG_ATTENDED_TRANSFER 0x1
unsigned int flags;
};
enum rtp_type {
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;
char str[24];
} 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"},
{DIALTONE_LAST, "-"},
};
/* 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 anonymouscallenable;
int calleridenable;
int calleridnameenable;
flash_spec flashSpec;
char emergency_numbers_list[AST_MAX_EXTENSION];
} channel_settings;
/* Caller ID */
#define CLID_MAX_DATE 10
#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 */