Merge branch 'master' of git://git.freeswitch.org/freeswitch

This commit is contained in:
David Yat Sin
2011-01-11 15:42:54 -05:00
39 changed files with 2779 additions and 142 deletions
+1
View File
@@ -1001,6 +1001,7 @@
/unimrcp/build/acmacros/lt~obsolete.m4
/*.tar.gz
/celt-0.7.1/
/celt-0.10.0/
/flite-1.3.99/
/freeradius-client-1.1.6/
/iksemel/test/tst-dom
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
autoheader
libtoolize --force --copy
aclocal
+13
View File
@@ -4177,6 +4177,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load)
freetdm_endpoint_interface->state_handler = &freetdm_state_handlers;
SWITCH_ADD_API(commands_api_interface, "ftdm", "FreeTDM commands", ft_function, FT_SYNTAX);
switch_console_set_complete("add ftdm start");
switch_console_set_complete("add ftdm stop");
switch_console_set_complete("add ftdm retart");
switch_console_set_complete("add ftdm dump");
switch_console_set_complete("add ftdm sigstatus get");
switch_console_set_complete("add ftdm sigstatus set");
switch_console_set_complete("add ftdm trace");
switch_console_set_complete("add ftdm notrace");
switch_console_set_complete("add ftdm q931_pcap");
switch_console_set_complete("add ftdm gains");
switch_console_set_complete("add ftdm dtmf on");
switch_console_set_complete("add ftdm dtmf off");
SWITCH_ADD_APP(app_interface, "disable_ec", "Disable Echo Canceller", "Disable Echo Canceller", disable_ec_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "disable_dtmf", "Disable DTMF Detection", "Disable DTMF Detection", disable_dtmf_function, "", SAF_NONE);
+27 -13
View File
@@ -634,6 +634,10 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span)
ftdm_mutex_lock(span->mutex);
/* stop the signaling */
/* This is a forced stopped */
ftdm_clear_flag(span, FTDM_SPAN_NON_STOPPABLE);
ftdm_span_stop(span);
/* destroy the channels */
@@ -739,6 +743,11 @@ FT_DECLARE(ftdm_status_t) ftdm_span_stop(ftdm_span_t *span)
ftdm_status_t status = FTDM_SUCCESS;
ftdm_mutex_lock(span->mutex);
if (ftdm_test_flag(span, FTDM_SPAN_NON_STOPPABLE)) {
status = FTDM_NOTIMPL;
goto done;
}
if (!ftdm_test_flag(span, FTDM_SPAN_STARTED)) {
status = FTDM_EINVAL;
@@ -2288,7 +2297,8 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_BUSY, 1);
break;
case FTDM_CHANNEL_INDICATE_PROCEED:
if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_PROCEED_STATE)) {
if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_PROCEED_STATE) ||
ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) {
ftdm_ack_indication(ftdmchan, indication, status);
goto done;
}
@@ -2929,23 +2939,27 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
case FTDM_COMMAND_ENABLE_DTMF_DETECT:
{
/* if they don't have thier own, use ours */
if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate);
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled software DTMF detector\n");
GOTO_STATUS(done, FTDM_SUCCESS);
if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate);
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled software DTMF detector\n");
GOTO_STATUS(done, FTDM_SUCCESS);
}
}
}
break;
case FTDM_COMMAND_DISABLE_DTMF_DETECT:
{
if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled software DTMF detector\n");
GOTO_STATUS(done, FTDM_SUCCESS);
if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled software DTMF detector\n");
GOTO_STATUS(done, FTDM_SUCCESS);
}
}
}
break;
@@ -1094,6 +1094,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE);
ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES);
ftdm_set_flag(span, FTDM_SPAN_NON_STOPPABLE);
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
span->trunk_type == FTDM_TRUNK_BRI) {
@@ -133,13 +133,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
get_redir_num(ftdmchan, &conEvnt->redirNmb);
get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad);
get_prog_ind_ie(ftdmchan, &conEvnt->progInd);
get_facility_ie(ftdmchan, &conEvnt->facilityStr);
get_facility_ie(ftdmchan, &conEvnt->facilityStr);
if (get_calling_name_from_display(ftdmchan, &conEvnt->display) != FTDM_SUCCESS) {
get_calling_name_from_usr_usr(ftdmchan, &conEvnt->usrUsr);
}
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Incoming call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
if (conEvnt->bearCap[0].eh.pres) {
@@ -147,10 +146,17 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val);
}
if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) {
if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) {
snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", conEvnt->ni2OctStr.str.val[3]);
uint8_t encoding = (conEvnt->ni2OctStr.str.val[2] >> 5);
if (encoding == 0 || encoding == 1) {
/* BCD even or BCD odd */
uint8_t value = (conEvnt->ni2OctStr.str.val[3] & 0x0F)*10 + ((conEvnt->ni2OctStr.str.val[3] >> 4) & 0x0F);
snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", value);
} else if (encoding == 2) {
/* IA 5 */
snprintf(ftdmchan->caller_data.aniII, 5, "%c", conEvnt->ni2OctStr.str.val[3]);
}
}
}
@@ -39,7 +39,7 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
ConEvnt conEvnt;
sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_ORIG_NISDN};
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID};
ftdm_assert((!sngisdn_info->suInstId && !sngisdn_info->spInstId), "Trying to call out, but call data was not cleared\n");
@@ -186,6 +186,9 @@ typedef enum {
/* If this flag is set, the signalling module supports jumping directly to state up, without
going through PROGRESS/PROGRESS_MEDIA */
FTDM_SPAN_USE_SKIP_STATES = (1 << 12),
/* If this flag is set, then this span cannot be stopped individually, it can only be stopped
on freetdm unload */
FTDM_SPAN_NON_STOPPABLE = (1 << 13),
} ftdm_span_flag_t;
/*! \brief Channel supported features */
+97 -46
View File
@@ -9,8 +9,7 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <winsock.h>
#include <errno.h>
#include <winsock2.h>
#include "xmlrpc_config.h"
#include "xmlrpc-c/util_int.h"
@@ -249,6 +248,7 @@ struct socketWin {
SOCKET winsock;
bool userSuppliedWinsock;
/* 'socket' was supplied by the user; it belongs to him */
HANDLE interruptEvent;
};
static
@@ -322,6 +322,8 @@ channelDestroy(TChannel * const channelP) {
if (!socketWinP->userSuppliedWinsock)
closesocket(socketWinP->winsock);
CloseHandle(socketWinP->interruptEvent);
free(socketWinP);
}
@@ -430,9 +432,9 @@ channelWait(TChannel * const channelP,
timedOut = TRUE;
break;
case -1: /* socket error */
if (errno != EINTR)
if (WSAGetLastError() != WSAEINTR)
failed = TRUE;
break;
break;
default:
if (FD_ISSET(socketWinP->winsock, &rfds))
readRdy = TRUE;
@@ -460,7 +462,9 @@ channelInterrupt(TChannel * const channelP) {
now or in the future.
Actually, this is just a no-op because we don't yet know how to
accomplish that.
accomplish that. (But we could probably do it the same way
chanSwitchInterrupt() works -- no one has needed it enough yet to do that
work).
-----------------------------------------------------------------------------*/
}
@@ -484,7 +488,7 @@ ChannelWinGetPeerName(TChannel * const channelP,
if (rc != 0) {
int const lastError = WSAGetLastError();
xmlrpc_asprintf(errorP, "getpeername() failed. WSAERROR = %d (%s)",
xmlrpc_asprintf(errorP, "getpeername() failed. WSA error = %d (%s)",
lastError, getWSAError(lastError));
} else {
if (addrlen != sizeof(sockAddr))
@@ -581,7 +585,8 @@ makeChannelFromWinsock(SOCKET const winsock,
socketWinP->winsock = winsock;
socketWinP->userSuppliedWinsock = TRUE;
socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
ChannelCreate(&channelVtbl, socketWinP, &channelP);
if (channelP == NULL)
@@ -591,8 +596,10 @@ makeChannelFromWinsock(SOCKET const winsock,
*channelPP = channelP;
*errorP = NULL;
}
if (*errorP)
if (*errorP) {
CloseHandle(socketWinP->interruptEvent);
free(socketWinP);
}
}
}
@@ -632,7 +639,7 @@ ChannelWinCreateWinsock(SOCKET const fd,
socklen_t peerAddrLen;
int rc;
peerAddrLen = sizeof(peerAddrLen);
peerAddrLen = sizeof(peerAddr);
rc = getpeername(fd, &peerAddr, &peerAddrLen);
@@ -676,6 +683,8 @@ chanSwitchDestroy(TChanSwitch * const chanSwitchP) {
if (!socketWinP->userSuppliedWinsock)
closesocket(socketWinP->winsock);
CloseHandle(socketWinP->interruptEvent);
free(socketWinP);
}
@@ -711,6 +720,49 @@ chanSwitchListen(TChanSwitch * const chanSwitchP,
static void
createChannelForAccept(int const acceptedWinsock,
struct sockaddr const peerAddr,
TChannel ** const channelPP,
void ** const channelInfoPP,
const char ** const errorP) {
struct abyss_win_chaninfo * channelInfoP;
makeChannelInfo(&channelInfoP, peerAddr, sizeof(peerAddr), errorP);
if (!*errorP) {
struct socketWin * acceptedSocketP;
MALLOCVAR(acceptedSocketP);
if (!acceptedSocketP)
xmlrpc_asprintf(errorP, "Unable to allocate memory");
else {
TChannel * channelP;
acceptedSocketP->winsock = acceptedWinsock;
acceptedSocketP->userSuppliedWinsock = FALSE;
acceptedSocketP->interruptEvent =
CreateEvent(NULL, FALSE, FALSE, NULL);
ChannelCreate(&channelVtbl, acceptedSocketP, &channelP);
if (!channelP)
xmlrpc_asprintf(errorP,
"Failed to create TChannel object.");
else {
*errorP = NULL;
*channelPP = channelP;
*channelInfoPP = channelInfoP;
}
if (*errorP) {
CloseHandle(acceptedSocketP->interruptEvent);
free(acceptedSocketP);
}
}
}
}
static SwitchAcceptImpl chanSwitchAccept;
static void
@@ -728,7 +780,7 @@ chanSwitchAccept(TChanSwitch * const chanSwitchP,
*channelPP == NULL.
-----------------------------------------------------------------------------*/
struct socketWin * const listenSocketP = chanSwitchP->implP;
HANDLE acceptEvent = WSACreateEvent();
bool interrupted;
TChannel * channelP;
@@ -736,46 +788,44 @@ chanSwitchAccept(TChanSwitch * const chanSwitchP,
channelP = NULL; /* No connection yet */
*errorP = NULL; /* No error yet */
WSAEventSelect(listenSocketP->winsock, acceptEvent,
FD_ACCEPT | FD_CLOSE | FD_READ);
while (!channelP && !*errorP && !interrupted) {
HANDLE interrupts[2] = {acceptEvent, listenSocketP->interruptEvent};
int rc;
struct sockaddr peerAddr;
socklen_t size = sizeof(peerAddr);
int rc;
rc = WaitForMultipleObjects(2, interrupts, FALSE, INFINITE);
if (WAIT_OBJECT_0 + 1 == rc) {
interrupted = TRUE;
continue;
};
rc = accept(listenSocketP->winsock, &peerAddr, &size);
if (rc >= 0) {
int const acceptedWinsock = rc;
struct socketWin * acceptedSocketP;
MALLOCVAR(acceptedSocketP);
createChannelForAccept(acceptedWinsock, peerAddr,
&channelP, channelInfoPP, errorP);
if (!acceptedSocketP)
xmlrpc_asprintf(errorP, "Unable to allocate memory");
else {
acceptedSocketP->winsock = acceptedWinsock;
acceptedSocketP->userSuppliedWinsock = FALSE;
*channelInfoPP = NULL;
ChannelCreate(&channelVtbl, acceptedSocketP, &channelP);
if (!channelP)
xmlrpc_asprintf(errorP,
"Failed to create TChannel object.");
else
*errorP = NULL;
if (*errorP)
free(acceptedSocketP);
}
if (*errorP)
closesocket(acceptedWinsock);
} else if (errno == EINTR)
interrupted = TRUE;
else
xmlrpc_asprintf(errorP, "accept() failed, errno = %d (%s)",
errno, strerror(errno));
} else {
int const lastError = WSAGetLastError();
if (lastError == WSAEINTR)
interrupted = TRUE;
else
xmlrpc_asprintf(errorP,
"accept() failed, WSA error = %d (%s)",
lastError, getWSAError(lastError));
}
}
*channelPP = channelP;
CloseHandle(acceptEvent);
}
@@ -787,15 +837,10 @@ chanSwitchInterrupt(TChanSwitch * const chanSwitchP) {
/*----------------------------------------------------------------------------
Interrupt any waiting that a thread might be doing in chanSwitchAccept()
now or in the future.
Actually, this is just a no-op because we don't yet know how to
accomplish that.
-----------------------------------------------------------------------------*/
struct socketWin * const socketWinP = chanSwitchP->implP;
if (!socketWinP->userSuppliedWinsock)
closesocket(socketWinP->winsock);
struct socketWin * const listenSocketP = chanSwitchP->implP;
SetEvent(listenSocketP->interruptEvent);
}
@@ -889,6 +934,7 @@ ChanSwitchWinCreate(uint16_t const portNumber,
} else {
socketWinP->winsock = winsock;
socketWinP->userSuppliedWinsock = FALSE;
socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
setSocketOptions(socketWinP->winsock, errorP);
if (!*errorP) {
@@ -899,8 +945,10 @@ ChanSwitchWinCreate(uint16_t const portNumber,
chanSwitchPP);
}
if (*errorP)
if (*errorP) {
CloseHandle(socketWinP->interruptEvent);
closesocket(winsock);
}
}
if (*errorP)
free(socketWinP);
@@ -929,7 +977,8 @@ ChanSwitchWinCreateWinsock(SOCKET const winsock,
socketWinP->winsock = winsock;
socketWinP->userSuppliedWinsock = TRUE;
socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
ChanSwitchCreate(&chanSwitchVtbl, socketWinP, &chanSwitchP);
if (chanSwitchP == NULL)
@@ -939,8 +988,10 @@ ChanSwitchWinCreateWinsock(SOCKET const winsock,
*chanSwitchPP = chanSwitchP;
*errorP = NULL;
}
if (*errorP)
if (*errorP) {
CloseHandle(socketWinP->interruptEvent);
free(socketWinP);
}
}
}
}