Newer
Older
/*
* Data types and API prototypes that are exported by libvoice
*/
#include <sys/time.h>
#include <time.h>
#include <syslog.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
};

Yalu Zhang
committed
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
committed
VOICE_SIG_LAST
};
PCM_0,
PCM_1
};
enum VOICE_LINE_TYPE {
VOICE_LINE_UNKNOWN, // Invalid type
VOICE_LINE_FXS,
VOICE_LINE_DECT
};
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;
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
};
int line; // Logical line number which starts with 0
int connection_id; // Arbitrary number from Asterisk

Yalu Zhang
committed
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;
Grzegorz Sluja
committed
uint16_t jb_overruns;
uint16_t jb_underruns;
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;
} codecs[MAX_CODECS];
};
#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[];

Yalu Zhang
committed
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);
// Connection API
int voice_connection_deinit(void);

Yalu Zhang
committed
int voice_connection_create(int line, int connection);
int voice_connection_close(int line, int connection);

Yalu Zhang
committed
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);
int voice_line_init(int has_dect);
int voice_line_deinit(void);
int voice_line_is_ready(int line);
int voice_line_get_connection_count(int line);

Yalu Zhang
committed
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));

Yalu Zhang
committed
int voice_write_media_packet(const struct media_packet_t *packet);