Newer
Older
/*
* This file contains platform independent code only.
*/
#include <syslog.h>
#include <stdarg.h>
#include "libvoice-priv.h"
struct terminal_info_t terminal_info = { .num_voice_ports = 0, };
struct line_t *lines = NULL; // Array of phone lines including FXS and DECT
struct connection_t *connections = NULL;
int max_num_connections = 0;
const struct voice_event_t event_map[] = { // List of events from the voice engine
{ .name = "DTMF0", .event = VOICE_EVT_DTMF0 },
{ .name = "DTMF1", .event = VOICE_EVT_DTMF1 },
{ .name = "DTMF2", .event = VOICE_EVT_DTMF2 },
{ .name = "DTMF3", .event = VOICE_EVT_DTMF3 },
{ .name = "DTMF4", .event = VOICE_EVT_DTMF4 },
{ .name = "DTMF5", .event = VOICE_EVT_DTMF5 },
{ .name = "DTMF6", .event = VOICE_EVT_DTMF6 },
{ .name = "DTMF7", .event = VOICE_EVT_DTMF7 },
{ .name = "DTMF8", .event = VOICE_EVT_DTMF8 },
{ .name = "DTMF9", .event = VOICE_EVT_DTMF9 },
{ .name = "DTMFS", .event = VOICE_EVT_DTMFS },
{ .name = "DTMFH", .event = VOICE_EVT_DTMFH },
{ .name = "DTMFA", .event = VOICE_EVT_DTMFA },
{ .name = "DTMFB", .event = VOICE_EVT_DTMFB },
{ .name = "DTMFC", .event = VOICE_EVT_DTMFC },
{ .name = "DTMFD", .event = VOICE_EVT_DTMFD },
{ .name = "OFFHOOK", .event = VOICE_EVT_OFFHOOK },
{ .name = "ONHOOK", .event = VOICE_EVT_ONHOOK },
{ .name = "FLASH", .event = VOICE_EVT_FLASH },
{ .name = "", .event = VOICE_EVT_END }
};

Yalu Zhang
committed
const struct dect_event_t dect_event_map[] = { // List of events from the dectmngr
{ .name = "SWITCH", .event = DECT_EVT_SWITCH },
{ .name = "JOIN", .event = DECT_EVT_JOIN },
{ .name = "RELEASE", .event = DECT_EVT_RELEASE },
{ .name = "", .event = DECT_EVT_END }
};

Yalu Zhang
committed
const struct voice_signal_t signal_map[] = { // List of signals requested by Asterisk
{ .name = "dial", .signal = VOICE_SIG_DIAL },
{ .name = "ringback", .signal = VOICE_SIG_RINGBACK },
{ .name = "stutter", .signal = VOICE_SIG_STUTTER },
{ .name = "unobtainable", .signal = VOICE_SIG_UNOBTAINABLE },
{ .name = "callwt", .signal = VOICE_SIG_CALL_WAITING },
{ .name = "busy", .signal = VOICE_SIG_BUSY },
{ .name = "ringing", .signal = VOICE_SIG_RINGING },
{ .name = "callid_ringing", .signal = VOICE_SIG_CALLID_RINGING },
{ .name = "callid", .signal = VOICE_SIG_CALLID },
{ .name = "congestion", .signal = VOICE_SIG_NETBUSY },
{ .name = "dtmf0", .signal = VOICE_SIG_DTMF0 },
{ .name = "dtmf1", .signal = VOICE_SIG_DTMF1 },
{ .name = "dtmf2", .signal = VOICE_SIG_DTMF2 },
{ .name = "dtmf3", .signal = VOICE_SIG_DTMF3 },
{ .name = "dtmf4", .signal = VOICE_SIG_DTMF4 },
{ .name = "dtmf5", .signal = VOICE_SIG_DTMF5 },
{ .name = "dtmf6", .signal = VOICE_SIG_DTMF6 },
{ .name = "dtmf7", .signal = VOICE_SIG_DTMF7 },
{ .name = "dtmf8", .signal = VOICE_SIG_DTMF8 },
{ .name = "dtmf9", .signal = VOICE_SIG_DTMF9 },
{ .name = "dtmf#", .signal = VOICE_SIG_DTMFH },
{ .name = "dtmf*", .signal = VOICE_SIG_DTMFS },
{ .name = "dtmfA", .signal = VOICE_SIG_DTMFA },
{ .name = "dtmfB", .signal = VOICE_SIG_DTMFB },
{ .name = "dtmfC", .signal = VOICE_SIG_DTMFC },
{ .name = "dtmfD", .signal = VOICE_SIG_DTMFD },
{ .name = "keypad", .signal = VOICE_SIG_INGRESS_DTMF },
{ .name = "answer", .signal = VOICE_SIG_ANSWER },
{ .name = "k-break", .signal = VOICE_SIG_K_BREAK },

Yalu Zhang
committed
{ .name = "", .signal = VOICE_SIG_LAST },
};
// Callback function which is invoked when an event is detected from the voice engine
void (*voice_cb_event_report)(int line, const char *event, int data) = NULL;
// Callback function which is invoked when an encoded media packet is generated by the voice engine
void (*voice_cb_egress_media)(const struct media_packet_t *packet, int size) = NULL;
void voice_syslog(int level, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsyslog(level, fmt, ap);

Yalu Zhang
committed
int voice_connection_find(int line, int connection)
{
int conIdx;
for(conIdx = 0; conIdx < max_num_connections; conIdx++) {

Yalu Zhang
committed
// If connection is -1, it means any connection on the line
if(connections[conIdx].line == line && (connections[conIdx].connection_id == connection || connection == -1)) {
return conIdx;
}
}
return -1;
}
// Pre-initialization of data structures
int voice_line_preinit(void) {
int i;
if(terminal_info.num_voice_ports <= 0) {
ENDPT_DBG("terminal_info.num_voice_ports = %d\n", terminal_info.num_voice_ports);
// Initialize all contents as 0 by calloc
lines = calloc(terminal_info.num_voice_ports, sizeof(struct line_t));
ENDPT_ERR("%s: out out memory\n", __func__);
for(i = 0; i < terminal_info.num_voice_ports; i++) {
lines[i].type = terminal_info.voice_ports[i];
ENDPT_DBG("lines[%d].type=%d\n", i, lines[i].type);
lines[i].pcm_callid[PCM_0] = CALLID_INVALID;
lines[i].pcm_callid[PCM_1] = CALLID_INVALID;
// Shut down and free resources
int voice_line_deinit(void) {
char *digits;
// Free all line resources we have allocated
for(i = 0; i < terminal_info.num_voice_ports; i++) {
if(lines[i].pending_digits) {
digits = pe_list_get(lines[i].pending_digits);
free(digits);
} while(digits);
free(lines[i].pending_digits);
lines[i].pending_digits = NULL;
voice_line_close(i);
if(lines[i].line_conf.name) {
free(lines[i].line_conf.name);
lines[i].line_conf.name = NULL;
}
if(lines[i].priv) {
free(lines[i].priv);
lines[i].priv = NULL;
}
}
free(lines);
lines = NULL;
return 0;
}
// Register the callback function for event report
int voice_register_cb_event_report(void (*cb_event_report)(int line, const char *event, int data)) {
voice_cb_event_report = cb_event_report;
return 0;
}
// Register the callback function for handling an encoded media packet from the voice engine
int voice_register_cb_egress_media(void (*cb_egress_media)(const struct media_packet_t *packet, int size)) {
voice_cb_egress_media = cb_egress_media;
return 0;
}
const char *voice_event2name(enum VOICE_EVENT evt)
{
const struct voice_event_t *item;
for (item = event_map; item->event != evt && item->event != VOICE_EVT_END; item++)
continue;
return item->name;
}