Skip to content
Snippets Groups Projects
libvoice.h 9.43 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * Data types and API prototypes that are exported by libvoice
     */
    
    #ifndef __LIBVOICE_H
    #define __LIBVOICE_H
    
    
    #include <stdio.h>
    
    #include <sys/time.h>
    #include <time.h>
    
    #include <libpicoevent.h>
    
    #include "voice-types.h"
    
    #define MAX_CALLER_ID_LEN  120 // Max length of caller id string we accept
    #define MAX_KEYPAD_DIGITS  100 // Max number of simulated keypad presses we accept
    
    #define MAX_CODECS         20
    #define MAX_CODEC_NAMELEN  20
    
    #define MIN_CALLER_ID_LEN  14                   // Minimum string length to be valid.
    #define CLID_TIME_DELIM    8			// String index where time record ends.
    #define CLID_NUMB_REC      CLID_TIME_DELIM + 2  // String index where number starts.
    
    #define MAX_CALLER_NAME	   60 // Max length of caller's name to be displayed on the DECT handset
    
    
    #define DEBUG_LOOPBACK       0 // Debug - feed received audio back to transmitter
    
    enum VOICE_EVENT
    {
    	VOICE_EVT_START,
    	VOICE_EVT_DTMF0,                   /* DTMF Tone 0 */
    	VOICE_EVT_DTMF1,                   /* DTMF Tone 1 */
    	VOICE_EVT_DTMF2,                   /* DTMF Tone 2 */
    	VOICE_EVT_DTMF3,                   /* DTMF Tone 3 */
    	VOICE_EVT_DTMF4,                   /* DTMF Tone 4 */
    	VOICE_EVT_DTMF5,                   /* DTMF Tone 5 */
    	VOICE_EVT_DTMF6,                   /* DTMF Tone 6 */
    	VOICE_EVT_DTMF7,                   /* DTMF Tone 7 */
    	VOICE_EVT_DTMF8,                   /* DTMF Tone 8 */
    	VOICE_EVT_DTMF9,                   /* DTMF Tone 9 */
    	VOICE_EVT_DTMFS,                   /* DTMF Tone * */
    	VOICE_EVT_DTMFH,                   /* DTMF Tone # */
    	VOICE_EVT_DTMFA,                   /* DTMF Tone A */
    	VOICE_EVT_DTMFB,                   /* DTMF Tone B */
    	VOICE_EVT_DTMFC,                   /* DTMF Tone C */
    	VOICE_EVT_DTMFD,                   /* DTMF Tone D */
    	VOICE_EVT_OFFHOOK,                 /* Off-hook event */
    	VOICE_EVT_ONHOOK,                  /* On-hook event */
    	VOICE_EVT_FLASH,                   /* Hook-flash event */
    
    	// The following events are not handled at present
    
    	VOICE_EVT_RING_ON,                 /* Ring signal on detected */
    	VOICE_EVT_RING_OFF,                /* Ring signal off detected */
    	VOICE_EVT_RING_END,                /* Ring signal end detected */
    	VOICE_EVT_ENCODER_SWITCH,          /* Encoder switch event */
    	VOICE_EVT_DECODER_SWITCH,          /* Decoder switch event */
    	VOICE_EVT_DIALTONE,                /* Dial Tone Detection event */
    	VOICE_EVT_DIALTONE_END,            /* Dial Tone End event */
    	VOICE_EVT_INGRESS_DTMF,            /* Ingress DTMF generated */
    	VOICE_EVT_CUSTOMTONE,              /* Custom tone detect event */
    	VOICE_EVT_LT_RESULT,               /* SLIC/SLAC line testing result */
    	VOICE_EVT_END
    };
    
    
    enum DECT_EVENT {
    	DECT_EVT_SWITCH,
    	DECT_EVT_JOIN,
    	DECT_EVT_RELEASE,
    	DECT_EVT_END
    };
    
    
    enum VOICE_SIGNAL {
    	VOICE_SIG_DIAL,
    	VOICE_SIG_RINGBACK,
    	VOICE_SIG_STUTTER,
    	VOICE_SIG_UNOBTAINABLE,
    	VOICE_SIG_CALL_WAITING,
    	VOICE_SIG_BUSY,
    	VOICE_SIG_RINGING,
    	VOICE_SIG_CALLID_RINGING,
    	VOICE_SIG_CALLID,
    	VOICE_SIG_NETBUSY,
    	VOICE_SIG_DTMF0,
    	VOICE_SIG_DTMF1,
    	VOICE_SIG_DTMF2,
    	VOICE_SIG_DTMF3,
    	VOICE_SIG_DTMF4,
    	VOICE_SIG_DTMF5,
    	VOICE_SIG_DTMF6,
    	VOICE_SIG_DTMF7,
    	VOICE_SIG_DTMF8,
    	VOICE_SIG_DTMF9,
    	VOICE_SIG_DTMFH,
    	VOICE_SIG_DTMFS,
    	VOICE_SIG_DTMFA,
    	VOICE_SIG_DTMFB,
    	VOICE_SIG_DTMFC,
    	VOICE_SIG_DTMFD,
    	VOICE_SIG_INGRESS_DTMF, // Simulate phone keypad button pressing
    
    Yalu Zhang's avatar
    Yalu Zhang committed
    	VOICE_SIG_K_BREAK,
    
    	PCM_0,
    	PCM_1
    };
    
    enum VOICE_LINE_TYPE {
    	VOICE_LINE_UNKNOWN,  // Invalid type
    	VOICE_LINE_FXS,
    	VOICE_LINE_DECT
    };
    
    
    struct terminal_info_t {
    
    	enum VOICE_LINE_TYPE voice_ports[8];
    	int32_t num_voice_ports;
    
    	int32_t num_fxo;
    	int32_t num_fxs;
    	int32_t num_dect;
    };
    
    
    // Line configuration
    struct line_config_t {
    	uint16_t echo_cancel;
    	uint16_t silence;       // silence suppression
    	uint16_t comfort_noise;
    	int32_t txgain;         // Gain applies to voice and tones, in contrast to EPZCNXPARAM volume which applies to voice only
    	int32_t rxgain;
    
    Elena Vengerova's avatar
    Elena Vengerova committed
    	int32_t hookflash_min;
    	int32_t hookflash_max;
    
    	char *name;             // Human readable line name
    	int32_t config_loaded;  // 1 if configuration is loaded successfully
    };
    
    
    struct line_t {
    	enum VOICE_LINE_TYPE type;        // Line type
    	struct line_config_t line_conf;   // Line configuration
    	uint16_t simulated_hook;          // True if line use simulated hook events
    	uint16_t simulated_busy;          // True if line act as always off-hook and thus always busy
    	uint32_t simulated_busy_peer_id;  // ID of remote who gets the above busy message
    	uint16_t signaled_call_waiting;   // True if Call waiting has already been signaled to DECT
    	uint16_t conference_started;      // True if conference has just been setup by DECT handset
    
    	int pcm_callid[2];	  // -1: Invalid, 0: Obtaining, >0: Established
    
    	pe_list_t *pending_digits;        // List of keypad digits waiting to be sent
    
    	void *priv;                       // Platform dependent data
    };
    
    
    struct connection_t {
    
    	int line;          // Logical line number which starts with 0
    
    	int connection_id; // Arbitrary number from Asterisk
    
    	void *priv;        // Platform dependent data
    
    struct voice_event_t {
    	const char *name;
    	enum VOICE_EVENT event;
    };
    
    struct dect_event_t {
    	const char *name;
    	enum DECT_EVENT event;
    };
    
    struct voice_signal_t {
    	const char *name;
    	enum VOICE_SIGNAL signal;
    };
    
    
    struct rtp_stats_t {
    	uint16_t local_burst_density;
    	uint16_t remote_burst_density;
    	uint16_t local_burst_duration;
    	uint16_t remote_burst_duration;
    	uint16_t local_gap_density;
    	uint16_t remote_gap_density;
    	uint16_t local_gap_duration;
    	uint16_t remote_gap_duration;
    	uint16_t local_jb_rate;
    	uint16_t remote_jb_rate;
    	uint16_t local_jb_max;
    	uint16_t remote_jb_max;
    	uint16_t local_jb_nominal;
    	uint16_t remote_jb_nominal;
    	uint16_t local_jb_abs_max;
    	uint16_t remote_jb_abs_max;
    	uint32_t discarded;
    	uint32_t lost;
    	uint32_t rxpkts;
    	uint32_t txpkts;
    	uint16_t jb_avg;
    	uint32_t jitter;
    
    	uint16_t local_loss_rate;
    	uint16_t remote_loss_rate;
    
    struct codec_capability {
    	int num_codecs;
    	struct {
    		char uciName[MAX_CODEC_NAMELEN];
    		char codec[MAX_CODEC_NAMELEN];
    		int ptimeMin;
    		int ptimeMax;
    		int ptimeDefault;
    		int ptimeIncrement;
    		float bitRate;
    
    #define ENABLE_VOICE_DEBUG    0 // Enable/disable voice debug
    #if ENABLE_VOICE_DEBUG
    // log to file
    #define ENDPT_DBG(fmt, ...) do { \
    
    		FILE *fp = fopen("/tmp/voicemngr.log", "a"); \
    
    		if (fp) { \
    			struct timeval tv_now; \
    			struct tm tm_now; \
    			gettimeofday(&tv_now, NULL); \
    			localtime_r(&tv_now.tv_sec, &tm_now); \
    			fprintf(fp, "%04d-%02d-%02d %02d:%02d:%02d.%03d %s()@%s:%d: " fmt, \
    				1900 + tm_now.tm_year, tm_now.tm_mon + 1, tm_now.tm_mday, \
    				tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec, (int)(tv_now.tv_usec / 1000), \
    				__func__, __FILE__, __LINE__, ##__VA_ARGS__); \
    			fclose(fp); \
    		} \
    		printf(fmt, ##__VA_ARGS__); \
    	} while (0)
    #else
    
    #define ENDPT_DBG(format, ...)  voice_syslog(LOG_DEBUG, "%s:%d %s: " format, \
    		__FILE__, __LINE__, __func__, ##__VA_ARGS__)
    
    #endif
    #define CHECK_POINT() ENDPT_DBG("Check point at %s@%s:%d\n", __func__, __FILE__, __LINE__)
    
    
    #define ENDPT_INFO(...) voice_syslog(LOG_INFO, __VA_ARGS__)
    #define ENDPT_WARN(...) voice_syslog(LOG_WARNING, __VA_ARGS__)
    #define ENDPT_ERR(...)  voice_syslog(LOG_ERR, __VA_ARGS__)
    
    
    extern struct terminal_info_t terminal_info;
    extern struct line_t *lines;
    
    extern struct connection_t *connections;
    extern int max_num_connections;
    
    extern const struct voice_event_t event_map[];
    extern const struct dect_event_t dect_event_map[];
    
    extern const struct voice_signal_t signal_map[];
    
    
    extern void (*voice_cb_event_report)(int line, const char *event, int data);
    
    extern void (*voice_cb_egress_media)(const struct media_packet_t *packet, int size);
    
    
    int voice_connection_init(void);
    
    int voice_connection_deinit(void);
    
    int voice_connection_create(int line, int connection);
    int voice_connection_close(int line, int connection);
    
    int voice_connection_close_all(void);
    
    int voice_connection_conference_start(int line, int connection);
    int voice_connection_conference_stop(int line, int connection);
    int voice_connection_find(int line, int connection);
    
    int voice_connection_parm_update(int line, int connection, struct config_update_struct *data);
    
    // Line API
    
    int voice_line_preinit(void);
    
    int voice_line_init(int has_dect);
    
    int voice_line_deinit(void);
    
    int voice_line_is_ready(int line);
    
    int voice_line_is_offhook(int line);
    
    int voice_line_get_connection_count(int line);
    
    int voice_line_signal(int line, int connection, enum VOICE_SIGNAL signal, int start, void *data);
    
    int voice_line_simulate_hook(int line, enum VOICE_EVENT event);
    
    void voice_syslog(int level, const char *fmt, ...);
    
    int voice_engine_shutdown(void);
    
    int voice_get_min_tx_gain(void);
    int voice_get_max_tx_gain(void);
    int voice_get_min_rx_gain(void);
    int voice_get_max_rx_gain(void);
    
    int voice_get_terminal_info(const struct terminal_info_t *voice_port_cfg, struct terminal_info_t *terminal_info);
    
    void voice_hook_simulation_maintain(int line);
    
    int voice_get_rtp_stats(int line, int connection, int reset, struct rtp_stats_t *rtp_stats);
    
    int voice_get_codec_capability(struct codec_capability *pcodecs);
    
    int voice_set_country(const char *country_code);
    
    int voice_register_cb_event_report(void (*voice_cb_event_report)(int line, const char *event, int data));
    
    int voice_register_cb_egress_media(void (*cb_egress_media)(const struct media_packet_t *packet, int size));
    
    int voice_write_media_packet(const struct media_packet_t *packet);