Skip to content
Snippets Groups Projects
common.c 6.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * This file contains platform independent code only.
     */
    
    #include <syslog.h>
    #include <stdarg.h>
    
    #include <stdlib.h>
    
    #include "libvoice.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         }
    };
    
    
    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          }
    };
    
    
    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 },
    
    Yalu Zhang's avatar
    Yalu Zhang committed
    	{ .name = "answer",         .signal = VOICE_SIG_ANSWER },
    	{ .name = "k-break",        .signal = VOICE_SIG_K_BREAK },
    
    // 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);
    
    int voice_connection_find(int line, int connection)
    
    {
    	int conIdx;
    
    	for(conIdx = 0; conIdx < max_num_connections; conIdx++) {
    
    		// If connection is -1, it means any connection on the line
    		if(connections[conIdx].line == line && (connections[conIdx].connection_id == connection || connection == -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));
    
    	if(!lines) {
    
    		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(lines[i].pending_digits);
    			lines[i].pending_digits = NULL;
    
    		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;
    
    
    // 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;
    }