Merge branch 'master' into moy.r2glare
This commit is contained in:
commit
3594419622
|
@ -251,7 +251,8 @@ libfreeswitch_la_SOURCES = \
|
|||
libs/miniupnpc/upnperrors.c \
|
||||
libs/libnatpmp/natpmp.c \
|
||||
libs/libnatpmp/getgateway.c\
|
||||
libs/spandsp/src/plc.c
|
||||
libs/spandsp/src/plc.c \
|
||||
libs/spandsp/src/bit_operations.c
|
||||
|
||||
if ENABLE_CPP
|
||||
libfreeswitch_la_SOURCES += src/switch_cpp.cpp
|
||||
|
|
|
@ -35,6 +35,7 @@ applications/mod_valet_parking
|
|||
#applications/mod_snapshot
|
||||
#applications/mod_snipe_hunt
|
||||
#applications/mod_callcenter
|
||||
#applications/mod_fsk
|
||||
codecs/mod_g723_1
|
||||
codecs/mod_amr
|
||||
#codecs/mod_amrwb
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
<load module="mod_fsv"/>
|
||||
<load module="mod_cluechoo"/>
|
||||
<load module="mod_valet_parking"/>
|
||||
<!--<load module="mod_fsk"/>-->
|
||||
<!--<load module="mod_spy"/>-->
|
||||
|
||||
<!-- SNOM Module -->
|
||||
|
|
|
@ -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,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
autoheader
|
||||
libtoolize --force --copy
|
||||
aclocal
|
||||
|
|
|
@ -4196,6 +4196,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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -2317,7 +2326,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;
|
||||
}
|
||||
|
@ -3041,23 +3051,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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -599,7 +605,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "cause:%d\n", ftdmchan->caller_data.hangup_cause);
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "RELEASE COMPLETE did not have a cause code\n");
|
||||
ftdmchan->caller_data.hangup_cause = 0;
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL;
|
||||
}
|
||||
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,6 @@ struct switch_core_session;
|
|||
struct switch_core_runtime;
|
||||
struct switch_core_port_allocator;
|
||||
|
||||
|
||||
/*!
|
||||
\defgroup core1 Core Library
|
||||
\ingroup FREESWITCH
|
||||
|
@ -713,6 +712,7 @@ SWITCH_DECLARE(void) switch_core_session_soft_lock(switch_core_session_t *sessio
|
|||
SWITCH_DECLARE(void) switch_core_session_soft_unlock(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine);
|
||||
SWITCH_DECLARE(switch_ivr_dmachine_t *) switch_core_session_get_dmachine(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_set_codec_slin(switch_core_session_t *session, switch_slin_data_t *data);
|
||||
|
||||
/*!
|
||||
\brief Retrieve the unique identifier from the core
|
||||
|
|
|
@ -711,6 +711,14 @@ struct switch_api_interface {
|
|||
#define PROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_rdlock(_it->parent->rwlock); switch_thread_rwlock_rdlock(_it->rwlock); _it->refs++; _it->parent->refs++; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "+++++++++++LOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs);
|
||||
#define UNPROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_unlock(_it->rwlock); switch_thread_rwlock_unlock(_it->parent->rwlock); _it->refs--; _it->parent->refs--; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "---------UNLOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs);
|
||||
|
||||
#include "switch_frame.h"
|
||||
|
||||
struct switch_slin_data {
|
||||
switch_core_session_t *session;
|
||||
switch_frame_t write_frame;
|
||||
switch_codec_t codec;
|
||||
char frame_data[SWITCH_RECOMMENDED_BUFFER_SIZE];
|
||||
};
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
|
||||
#include <switch.h>
|
||||
|
||||
#define DEFAULT_ODBC_RETRIES 120
|
||||
|
||||
SWITCH_BEGIN_EXTERN_C struct switch_odbc_handle;
|
||||
typedef void *switch_odbc_statement_handle_t;
|
||||
|
||||
|
@ -50,6 +52,7 @@ typedef enum {
|
|||
} switch_odbc_status_t;
|
||||
|
||||
SWITCH_DECLARE(switch_odbc_handle_t *) switch_odbc_handle_new(const char *dsn, const char *username, const char *password);
|
||||
SWITCH_DECLARE(void) switch_odbc_set_num_retries(switch_odbc_handle_t *handle, int num_retries);
|
||||
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_handle_t *handle);
|
||||
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_handle_t *handle);
|
||||
SWITCH_DECLARE(void) switch_odbc_handle_destroy(switch_odbc_handle_t **handlep);
|
||||
|
|
|
@ -632,9 +632,13 @@ typedef enum {
|
|||
This flag will never send any. Sheesh....
|
||||
*/
|
||||
|
||||
RTP_BUG_IGNORE_DTMF_DURATION = (1 << 6)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Guess Who? ... Yep, Sonus (and who know's who else) likes to interweave DTMF with the audio stream making it take
|
||||
2X as long as it should and sending an incorrect duration making the DTMF very delayed.
|
||||
This flag will treat every dtmf as if it were 50ms and queue it on recipt of the leading packet rather than at the end.
|
||||
*/
|
||||
|
||||
} switch_rtp_bug_flag_t;
|
||||
|
||||
|
@ -1817,6 +1821,8 @@ typedef struct switch_loadable_module_function_table {
|
|||
|
||||
typedef int (*switch_modulename_callback_func_t) (void *user_data, const char *module_name);
|
||||
|
||||
typedef struct switch_slin_data switch_slin_data_t;
|
||||
|
||||
#define SWITCH_MODULE_DEFINITION_EX(name, load, shutdown, runtime, flags) \
|
||||
static const char modname[] = #name ; \
|
||||
SWITCH_MOD_DECLARE_DATA switch_loadable_module_function_table_t name##_module_interface = { \
|
||||
|
|
|
@ -1485,6 +1485,8 @@ SWITCH_STANDARD_APP(ivr_application_function)
|
|||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to find menu\n");
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No menus configured\n");
|
||||
}
|
||||
switch_xml_free(cxml);
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
BASE=../../../..
|
||||
|
||||
LOCAL_SOURCES=fsk.c uart.c fsk_callerid.c
|
||||
LOCAL_OBJS=fsk.o uart.o fsk_callerid.o
|
||||
include $(BASE)/build/modmake.rules
|
||||
|
|
@ -0,0 +1,351 @@
|
|||
|
||||
/*
|
||||
* bell202.c
|
||||
*
|
||||
* Copyright (c) 2005 Robert Krten. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This module contains a Bell-202 1200-baud FSK decoder, suitable for
|
||||
* use in a library. The general style of the library calls is modeled
|
||||
* after the POSIX pthread_*() functions.
|
||||
*
|
||||
* 2005 03 20 R. Krten created
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "fsk.h"
|
||||
#include "uart.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
fsk_modem_definition_t fsk_modem_definitions[] =
|
||||
{
|
||||
{ /* FSK_V23_FORWARD_MODE1 */ 1700, 1300, 600 },
|
||||
{ /* FSK_V23_FORWARD_MODE2 */ 2100, 1300, 1200 },
|
||||
{ /* FSK_V23_BACKWARD */ 450, 390, 75 },
|
||||
{ /* FSK_BELL202 */ 2200, 1200, 1200 },
|
||||
};
|
||||
|
||||
/*
|
||||
* dsp_fsk_attr_init
|
||||
*
|
||||
* Initializes the attributes structure; this must be done before the
|
||||
* attributes structure is used.
|
||||
*/
|
||||
|
||||
void dsp_fsk_attr_init (dsp_fsk_attr_t *attr)
|
||||
{
|
||||
memset(attr, 0, sizeof(*attr));
|
||||
}
|
||||
|
||||
/*
|
||||
* dsp_fsk_attr_get_bithandler
|
||||
* dsp_fsk_attr_set_bithandler
|
||||
* dsp_fsk_attr_get_bytehandler
|
||||
* dsp_fsk_attr_set_bytehandler
|
||||
* dsp_fsk_attr_getsamplerate
|
||||
* dsp_fsk_attr_setsamplerate
|
||||
*
|
||||
* These functions get and set their respective elements from the
|
||||
* attributes structure. If an error code is returned, it is just
|
||||
* zero == ok, -1 == fail.
|
||||
*/
|
||||
|
||||
bithandler_func_t dsp_fsk_attr_get_bithandler(dsp_fsk_attr_t *attr, void **bithandler_arg)
|
||||
{
|
||||
*bithandler_arg = attr->bithandler_arg;
|
||||
return attr->bithandler;
|
||||
}
|
||||
|
||||
void dsp_fsk_attr_set_bithandler(dsp_fsk_attr_t *attr, bithandler_func_t bithandler, void *bithandler_arg)
|
||||
{
|
||||
attr->bithandler = bithandler;
|
||||
attr->bithandler_arg = bithandler_arg;
|
||||
}
|
||||
|
||||
bytehandler_func_t dsp_fsk_attr_get_bytehandler(dsp_fsk_attr_t *attr, void **bytehandler_arg)
|
||||
{
|
||||
*bytehandler_arg = attr->bytehandler_arg;
|
||||
return attr->bytehandler;
|
||||
}
|
||||
|
||||
void dsp_fsk_attr_set_bytehandler(dsp_fsk_attr_t *attr, bytehandler_func_t bytehandler, void *bytehandler_arg)
|
||||
{
|
||||
attr->bytehandler = bytehandler;
|
||||
attr->bytehandler_arg = bytehandler_arg;
|
||||
}
|
||||
|
||||
int dsp_fsk_attr_get_samplerate (dsp_fsk_attr_t *attr)
|
||||
{
|
||||
return attr->sample_rate;
|
||||
}
|
||||
|
||||
int dsp_fsk_attr_set_samplerate (dsp_fsk_attr_t *attr, int samplerate)
|
||||
{
|
||||
if (samplerate <= 0) {
|
||||
return -1;
|
||||
}
|
||||
attr->sample_rate = samplerate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* dsp_fsk_create
|
||||
*
|
||||
* Creates a handle for subsequent use. The handle is created to contain
|
||||
* a context data structure for use by the sample handler function. The
|
||||
* function expects an initialized attributes structure, and returns the
|
||||
* handle or a NULL if there were errors.
|
||||
*
|
||||
* Once created, the handle can be used until it is destroyed.
|
||||
*/
|
||||
|
||||
dsp_fsk_handle_t *dsp_fsk_create(dsp_fsk_attr_t *attr)
|
||||
{
|
||||
int i;
|
||||
double phi_mark, phi_space;
|
||||
dsp_fsk_handle_t *handle;
|
||||
|
||||
handle = malloc(sizeof(*handle));
|
||||
if (!handle) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(handle, 0, sizeof(*handle));
|
||||
|
||||
/* fill the attributes member */
|
||||
memcpy(&handle->attr, attr, sizeof(*attr));
|
||||
|
||||
/* see if we can do downsampling. We only really need 6 samples to "match" */
|
||||
if (attr->sample_rate / fsk_modem_definitions[FSK_BELL202].freq_mark > 6) {
|
||||
handle->downsampling_count = attr->sample_rate / fsk_modem_definitions[FSK_BELL202].freq_mark / 6;
|
||||
} else {
|
||||
handle->downsampling_count = 1;
|
||||
}
|
||||
handle->current_downsample = 1;
|
||||
|
||||
/* calculate the correlate size (number of samples required for slowest wave) */
|
||||
handle->corrsize = attr->sample_rate / handle->downsampling_count / fsk_modem_definitions[FSK_BELL202].freq_mark;
|
||||
|
||||
/* allocate the correlation sin/cos arrays and initialize */
|
||||
for (i = 0; i < 4; i++) {
|
||||
handle->correlates[i] = malloc(sizeof(double) * handle->corrsize);
|
||||
if (handle->correlates[i] == NULL) {
|
||||
/* some failed, back out memory allocations */
|
||||
dsp_fsk_destroy(&handle);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* now initialize them */
|
||||
phi_mark = 2. * M_PI / ((double) attr->sample_rate / (double) handle->downsampling_count / (double) fsk_modem_definitions[FSK_BELL202].freq_mark);
|
||||
phi_space = 2. * M_PI / ((double) attr->sample_rate / (double) handle->downsampling_count / (double) fsk_modem_definitions[FSK_BELL202].freq_space);
|
||||
|
||||
for (i = 0; i < handle->corrsize; i++) {
|
||||
handle->correlates[0][i] = sin(phi_mark * (double) i);
|
||||
handle->correlates[1][i] = cos(phi_mark * (double) i);
|
||||
handle->correlates[2][i] = sin(phi_space * (double) i);
|
||||
handle->correlates[3][i] = cos(phi_space * (double) i);
|
||||
}
|
||||
|
||||
/* initialize the ring buffer */
|
||||
handle->buffer = malloc(sizeof(double) * handle->corrsize);
|
||||
if (!handle->buffer) { /* failed; back out memory allocations */
|
||||
dsp_fsk_destroy(&handle);
|
||||
return NULL;
|
||||
}
|
||||
memset(handle->buffer, 0, sizeof(double) * handle->corrsize);
|
||||
handle->ringstart = 0;
|
||||
|
||||
/* initalize intra-cell position */
|
||||
handle->cellpos = 0;
|
||||
handle->celladj = fsk_modem_definitions[FSK_BELL202].baud_rate / (double) attr->sample_rate * (double) handle->downsampling_count;
|
||||
|
||||
/* if they have provided a byte handler, add a UART to the processing chain */
|
||||
if (handle->attr.bytehandler) {
|
||||
dsp_uart_attr_t uart_attr;
|
||||
dsp_uart_handle_t *uart_handle;
|
||||
|
||||
dsp_uart_attr_init(&uart_attr);
|
||||
dsp_uart_attr_set_bytehandler(&uart_attr, handle->attr.bytehandler, handle->attr.bytehandler_arg);
|
||||
uart_handle = dsp_uart_create(&uart_attr);
|
||||
if (uart_handle == NULL) {
|
||||
dsp_fsk_destroy(&handle);
|
||||
return NULL;
|
||||
}
|
||||
handle->attr.bithandler = dsp_uart_bit_handler;
|
||||
handle->attr.bithandler_arg = uart_handle;
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
/*
|
||||
* dsp_fsk_destroy
|
||||
*
|
||||
* Destroys a handle, releasing any associated memory. Sets handle pointer to NULL
|
||||
* so A destroyed handle can not be used for anything after the destroy.
|
||||
*/
|
||||
|
||||
void dsp_fsk_destroy(dsp_fsk_handle_t **handle)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* if empty handle, just return */
|
||||
if (*handle == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((*handle)->correlates[i] != NULL) {
|
||||
free((*handle)->correlates[i]);
|
||||
(*handle)->correlates[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((*handle)->buffer != NULL) {
|
||||
free((*handle)->buffer);
|
||||
(*handle)->buffer = NULL;
|
||||
}
|
||||
|
||||
if ((*handle)->attr.bytehandler) {
|
||||
dsp_uart_handle_t** dhandle = (void *)(&(*handle)->attr.bithandler_arg);
|
||||
dsp_uart_destroy(dhandle);
|
||||
}
|
||||
|
||||
free(*handle);
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* dsp_fsk_sample
|
||||
*
|
||||
* This is the main processing entry point. The function accepts a normalized
|
||||
* sample (i.e., one whose range is between -1 and +1). The function performs
|
||||
* the Bell-202 FSK modem decode processing, and, if it detects a valid bit,
|
||||
* will call the bithandler associated with the attributes structure.
|
||||
*
|
||||
* For the Bell-202 standard, a logical zero (space) is 2200 Hz, and a logical
|
||||
* one (mark) is 1200 Hz.
|
||||
*/
|
||||
|
||||
void
|
||||
dsp_fsk_sample (dsp_fsk_handle_t *handle, double normalized_sample)
|
||||
{
|
||||
double val;
|
||||
double factors[4];
|
||||
int i, j;
|
||||
|
||||
/* if we can avoid processing samples, do so */
|
||||
if (handle->downsampling_count != 1) {
|
||||
if (handle->current_downsample < handle->downsampling_count) {
|
||||
handle->current_downsample++;
|
||||
return; /* throw this sample out */
|
||||
}
|
||||
handle->current_downsample = 1;
|
||||
}
|
||||
|
||||
/* store sample in buffer */
|
||||
handle->buffer[handle->ringstart++] = normalized_sample;
|
||||
if (handle->ringstart >= handle->corrsize) {
|
||||
handle->ringstart = 0;
|
||||
}
|
||||
|
||||
/* do the correlation calculation */
|
||||
factors[0] = factors[1] = factors[2] = factors[3] = 0; /* clear out intermediate sums */
|
||||
j = handle->ringstart;
|
||||
for (i = 0; i < handle->corrsize; i++) {
|
||||
if (j >= handle->corrsize) {
|
||||
j = 0;
|
||||
}
|
||||
val = handle->buffer[j];
|
||||
factors[0] += handle->correlates[0][i] * val;
|
||||
factors[1] += handle->correlates[1][i] * val;
|
||||
factors[2] += handle->correlates[2][i] * val;
|
||||
factors[3] += handle->correlates[3][i] * val;
|
||||
j++;
|
||||
}
|
||||
|
||||
/* store the bit (bit value is comparison of the two sets of correlate factors) */
|
||||
handle->previous_bit = handle->current_bit;
|
||||
handle->current_bit = (factors[0] * factors[0] + factors[1] * factors[1] > factors[2] * factors[2] + factors[3] * factors[3]);
|
||||
|
||||
/* if there's a transition, we can synchronize the cell position */
|
||||
if (handle->previous_bit != handle->current_bit) {
|
||||
handle->cellpos = 0.5; /* adjust cell position to be in the middle of the cell */
|
||||
}
|
||||
handle->cellpos += handle->celladj; /* walk the cell along */
|
||||
|
||||
if (handle->cellpos > 1.0) {
|
||||
handle->cellpos -= 1.0;
|
||||
|
||||
switch (handle->state) {
|
||||
case FSK_STATE_DATA:
|
||||
{
|
||||
|
||||
(*handle->attr.bithandler) (handle->attr.bithandler_arg, handle->current_bit);
|
||||
}
|
||||
break;
|
||||
case FSK_STATE_CHANSEIZE:
|
||||
{
|
||||
|
||||
if (handle->last_bit != handle->current_bit) {
|
||||
handle->conscutive_state_bits++;
|
||||
} else {
|
||||
handle->conscutive_state_bits = 0;
|
||||
}
|
||||
|
||||
if (handle->conscutive_state_bits > 15) {
|
||||
handle->state = FSK_STATE_CARRIERSIG;
|
||||
handle->conscutive_state_bits = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FSK_STATE_CARRIERSIG:
|
||||
{
|
||||
if (handle->current_bit) {
|
||||
handle->conscutive_state_bits++;
|
||||
} else {
|
||||
handle->conscutive_state_bits = 0;
|
||||
}
|
||||
|
||||
if (handle->conscutive_state_bits > 15) {
|
||||
handle->state = FSK_STATE_DATA;
|
||||
handle->conscutive_state_bits = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
handle->last_bit = handle->current_bit;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* bell202.h
|
||||
*
|
||||
* Copyright (c) 2005 Robert Krten. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This module contains the manifest constants and declarations for
|
||||
* the Bell-202 1200 baud FSK modem.
|
||||
*
|
||||
* 2005 03 20 R. Krten created
|
||||
*/
|
||||
|
||||
#ifndef __FSK_H__
|
||||
#define __FSK_H__
|
||||
#include "uart.h"
|
||||
|
||||
typedef struct {
|
||||
int freq_space; /* Frequency of the 0 bit */
|
||||
int freq_mark; /* Frequency of the 1 bit */
|
||||
int baud_rate; /* baud rate for the modem */
|
||||
} fsk_modem_definition_t;
|
||||
|
||||
/* Must be kept in sync with fsk_modem_definitions array in fsk.c */
|
||||
/* V.23 definitions: http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-V.23 */
|
||||
typedef enum {
|
||||
FSK_V23_FORWARD_MODE1 = 0, /* Maximum 600 bps for long haul */
|
||||
FSK_V23_FORWARD_MODE2, /* Standard 1200 bps V.23 */
|
||||
FSK_V23_BACKWARD, /* 75 bps return path for V.23 */
|
||||
FSK_BELL202 /* Bell 202 half-duplex 1200 bps */
|
||||
} fsk_modem_types_t;
|
||||
|
||||
typedef enum {
|
||||
FSK_STATE_CHANSEIZE = 0,
|
||||
FSK_STATE_CARRIERSIG,
|
||||
FSK_STATE_DATA
|
||||
} fsk_state_t;
|
||||
|
||||
typedef struct dsp_fsk_attr_s
|
||||
{
|
||||
int sample_rate; /* sample rate in HZ */
|
||||
bithandler_func_t bithandler; /* bit handler */
|
||||
void *bithandler_arg; /* arbitrary ID passed to bithandler as first argument */
|
||||
bytehandler_func_t bytehandler; /* byte handler */
|
||||
void *bytehandler_arg; /* arbitrary ID passed to bytehandler as first argument */
|
||||
} dsp_fsk_attr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fsk_state_t state;
|
||||
dsp_fsk_attr_t attr; /* attributes structure */
|
||||
double *correlates[4]; /* one for each of sin/cos for mark/space */
|
||||
int corrsize; /* correlate size (also number of samples in ring buffer) */
|
||||
double *buffer; /* sample ring buffer */
|
||||
int ringstart; /* ring buffer start offset */
|
||||
double cellpos; /* bit cell position */
|
||||
double celladj; /* bit cell adjustment for each sample */
|
||||
int previous_bit; /* previous bit (for detecting a transition to sync-up cell position) */
|
||||
int current_bit; /* current bit */
|
||||
int last_bit;
|
||||
int downsampling_count; /* number of samples to skip */
|
||||
int current_downsample; /* current skip count */
|
||||
int conscutive_state_bits; /* number of bits in a row that matches the pattern for the current state */
|
||||
} dsp_fsk_handle_t;
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*
|
||||
* General calling order is:
|
||||
* a) create the attributes structure (dsp_fsk_attr_init)
|
||||
* b) initialize fields in the attributes structure (dsp_fsk_attr_set_*)
|
||||
* c) create a Bell-202 handle (dsp_fsk_create)
|
||||
* d) feed samples through the handler (dsp_fsk_sample)
|
||||
*/
|
||||
|
||||
void dsp_fsk_attr_init(dsp_fsk_attr_t *attributes);
|
||||
|
||||
bithandler_func_t dsp_fsk_attr_get_bithandler(dsp_fsk_attr_t *attributes, void **bithandler_arg);
|
||||
void dsp_fsk_attr_set_bithandler(dsp_fsk_attr_t *attributes, bithandler_func_t bithandler, void *bithandler_arg);
|
||||
bytehandler_func_t dsp_fsk_attr_get_bytehandler(dsp_fsk_attr_t *attributes, void **bytehandler_arg);
|
||||
void dsp_fsk_attr_set_bytehandler(dsp_fsk_attr_t *attributes, bytehandler_func_t bytehandler, void *bytehandler_arg);
|
||||
int dsp_fsk_attr_get_samplerate(dsp_fsk_attr_t *attributes);
|
||||
int dsp_fsk_attr_set_samplerate(dsp_fsk_attr_t *attributes, int samplerate);
|
||||
|
||||
dsp_fsk_handle_t * dsp_fsk_create(dsp_fsk_attr_t *attributes);
|
||||
void dsp_fsk_destroy(dsp_fsk_handle_t **handle);
|
||||
|
||||
void dsp_fsk_sample(dsp_fsk_handle_t *handle, double normalized_sample);
|
||||
|
||||
extern fsk_modem_definition_t fsk_modem_definitions[];
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,398 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* mod_fsk -- FSK data transfer
|
||||
*
|
||||
*/
|
||||
|
||||
#include "switch.h"
|
||||
#include "fsk_callerid.h"
|
||||
|
||||
void bitstream_init(bitstream_t *bsp, uint8_t *data, uint32_t datalen, endian_t endian, uint8_t ss)
|
||||
{
|
||||
memset(bsp, 0, sizeof(*bsp));
|
||||
bsp->data = data;
|
||||
bsp->datalen = datalen;
|
||||
bsp->endian = endian;
|
||||
bsp->ss = ss;
|
||||
|
||||
if (endian < 0) {
|
||||
bsp->top = bsp->bit_index = 7;
|
||||
bsp->bot = 0;
|
||||
} else {
|
||||
bsp->top = bsp->bit_index = 0;
|
||||
bsp->bot = 7;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int8_t bitstream_get_bit(bitstream_t *bsp)
|
||||
{
|
||||
int8_t bit = -1;
|
||||
|
||||
|
||||
if (bsp->byte_index >= bsp->datalen) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (bsp->ss) {
|
||||
if (!bsp->ssv) {
|
||||
bsp->ssv = 1;
|
||||
return 0;
|
||||
} else if (bsp->ssv == 2) {
|
||||
bsp->byte_index++;
|
||||
bsp->ssv = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
bit = (bsp->data[bsp->byte_index] >> (bsp->bit_index)) & 1;
|
||||
|
||||
if (bsp->bit_index == bsp->bot) {
|
||||
bsp->bit_index = bsp->top;
|
||||
if (bsp->ss) {
|
||||
bsp->ssv = 2;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (++bsp->byte_index > bsp->datalen) {
|
||||
bit = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
} else {
|
||||
bsp->bit_index = bsp->bit_index + bsp->endian;
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
return bit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void fsk_byte_handler (void *x, int data)
|
||||
{
|
||||
fsk_data_state_t *state = (fsk_data_state_t *) x;
|
||||
uint8_t byte = (uint8_t)data;
|
||||
|
||||
top:
|
||||
|
||||
if (state->init == 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->dlen) {
|
||||
goto add_byte;
|
||||
}
|
||||
|
||||
if (state->bpos == 1) {
|
||||
state->blen = byte;
|
||||
|
||||
if ((uint32_t)(state->dlen = state->bpos + byte + 2) > state->bufsize) {
|
||||
state->dlen = state->bufsize;
|
||||
}
|
||||
goto top;
|
||||
}
|
||||
|
||||
add_byte:
|
||||
|
||||
if (state->bpos <= state->dlen) {
|
||||
state->buf[state->bpos++] = byte;
|
||||
} else {
|
||||
state->init = 3;
|
||||
}
|
||||
}
|
||||
|
||||
switch_status_t fsk_data_init(fsk_data_state_t *state, uint8_t *data, uint32_t datalen)
|
||||
{
|
||||
memset(state, 0, sizeof(*state));
|
||||
state->buf = data;
|
||||
state->bufsize = datalen;
|
||||
state->bpos = 2;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t fsk_data_add_sdmf(fsk_data_state_t *state, const char *date, char *number)
|
||||
{
|
||||
size_t dlen = strlen(date);
|
||||
size_t nlen = strlen(number);
|
||||
|
||||
state->buf[0] = CID_TYPE_SDMF;
|
||||
memcpy(&state->buf[state->bpos], date, dlen);
|
||||
state->bpos += dlen;
|
||||
memcpy(&state->buf[state->bpos], number, nlen);
|
||||
state->bpos += nlen;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t fsk_data_add_mdmf(fsk_data_state_t *state, mdmf_type_t type, const uint8_t *data, uint32_t datalen)
|
||||
{
|
||||
state->buf[0] = CID_TYPE_MDMF;
|
||||
state->buf[state->bpos++] = type;
|
||||
state->buf[state->bpos++] = (uint8_t)datalen;
|
||||
memcpy(&state->buf[state->bpos], data, datalen);
|
||||
state->bpos += datalen;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
switch_status_t fsk_data_add_checksum(fsk_data_state_t *state)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t check = 0;
|
||||
|
||||
state->buf[1] = (uint8_t)(state->bpos - 2);
|
||||
|
||||
for (i = 0; i < state->bpos; i++) {
|
||||
check = check + state->buf[i];
|
||||
}
|
||||
|
||||
state->checksum = state->buf[state->bpos] = (uint8_t)(256 - check);
|
||||
state->bpos++;
|
||||
|
||||
state->dlen = state->bpos;
|
||||
state->blen = state->buf[1];
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
switch_status_t fsk_data_parse(fsk_data_state_t *state, size_t *type, char **data, size_t *len)
|
||||
{
|
||||
|
||||
size_t i;
|
||||
int sum = 0;
|
||||
|
||||
top:
|
||||
|
||||
if (state->checksum != 0 || state->ppos >= state->dlen - 1) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (!state->ppos) {
|
||||
for(i = 0; i < state->bpos; i++) {
|
||||
sum += state->buf[i];
|
||||
}
|
||||
state->checksum = sum % 256;
|
||||
state->ppos = 2;
|
||||
|
||||
if (state->buf[0] != CID_TYPE_MDMF && state->buf[0] != CID_TYPE_SDMF) {
|
||||
state->checksum = -1;
|
||||
}
|
||||
goto top;
|
||||
}
|
||||
|
||||
if (state->buf[0] == CID_TYPE_SDMF) {
|
||||
/* convert sdmf to mdmf so we don't need 2 parsers */
|
||||
if (state->ppos == 2) {
|
||||
*type = MDMF_DATETIME;
|
||||
*len = 8;
|
||||
} else {
|
||||
if (state->buf[state->ppos] == 'P' || state->buf[state->ppos] == 'O') {
|
||||
*type = MDMF_NO_NUM;
|
||||
*len = 1;
|
||||
} else {
|
||||
*type = MDMF_PHONE_NUM;
|
||||
*len = state->blen - 8;
|
||||
}
|
||||
}
|
||||
*data = (char *)&state->buf[state->ppos];
|
||||
state->ppos += *len;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
} else if (state->buf[0] == CID_TYPE_MDMF) {
|
||||
*type = state->buf[state->ppos++];
|
||||
*len = state->buf[state->ppos++];
|
||||
*data = (char *)&state->buf[state->ppos];
|
||||
state->ppos += *len;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
switch_status_t fsk_demod_feed(fsk_data_state_t *state, int16_t *data, size_t samples)
|
||||
{
|
||||
uint32_t x;
|
||||
int16_t *sp = data;
|
||||
|
||||
if (state->init == 3) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
for (x = 0; x < samples; x++) {
|
||||
dsp_fsk_sample (state->fsk1200_handle, (double) *sp++ / 32767.0);
|
||||
if (state->dlen && state->bpos >= state->dlen) {
|
||||
state->init = 3;
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t fsk_demod_destroy(fsk_data_state_t *state)
|
||||
{
|
||||
dsp_fsk_destroy(&state->fsk1200_handle);
|
||||
memset(state, 0, sizeof(*state));
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int fsk_demod_init(fsk_data_state_t *state, int rate, uint8_t *buf, size_t bufsize)
|
||||
{
|
||||
|
||||
dsp_fsk_attr_t fsk1200_attr;
|
||||
|
||||
if (state->fsk1200_handle) {
|
||||
dsp_fsk_destroy(&state->fsk1200_handle);
|
||||
}
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
memset(buf, 0, bufsize);
|
||||
state->buf = buf;
|
||||
state->bufsize = bufsize;
|
||||
|
||||
dsp_fsk_attr_init (&fsk1200_attr);
|
||||
dsp_fsk_attr_set_samplerate (&fsk1200_attr, rate);
|
||||
dsp_fsk_attr_set_bytehandler (&fsk1200_attr, fsk_byte_handler, state);
|
||||
state->fsk1200_handle = dsp_fsk_create (&fsk1200_attr);
|
||||
|
||||
if (state->fsk1200_handle == NULL) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
size_t fsk_modulator_generate_bit(fsk_modulator_t *fsk_trans, int8_t bit, int16_t *buf, size_t buflen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for(i = 0 ; i < buflen; i++) {
|
||||
fsk_trans->bit_accum += fsk_trans->bit_factor;
|
||||
if (fsk_trans->bit_accum >= FSK_MOD_FACTOR) {
|
||||
fsk_trans->bit_accum -= (FSK_MOD_FACTOR + fsk_trans->bit_factor);
|
||||
break;
|
||||
}
|
||||
|
||||
buf[i] = teletone_dds_state_modulate_sample(&fsk_trans->dds, bit);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
int32_t fsk_modulator_generate_carrier_bits(fsk_modulator_t *fsk_trans, uint32_t bits)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
size_t r = 0;
|
||||
int8_t bit = 1;
|
||||
|
||||
for (i = 0; i < bits; i++) {
|
||||
if ((r = fsk_modulator_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) {
|
||||
if (fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
void fsk_modulator_generate_chan_sieze(fsk_modulator_t *fsk_trans)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
size_t r = 0;
|
||||
int8_t bit = 0;
|
||||
|
||||
for (i = 0; i < fsk_trans->chan_sieze_bits; i++) {
|
||||
if ((r = fsk_modulator_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) {
|
||||
if (fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
bit = !bit;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void fsk_modulator_send_data(fsk_modulator_t *fsk_trans)
|
||||
{
|
||||
size_t r = 0;
|
||||
int8_t bit = 0;
|
||||
|
||||
while((bit = bitstream_get_bit(&fsk_trans->bs)) > -1) {
|
||||
if ((r = fsk_modulator_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) {
|
||||
if (fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch_status_t fsk_modulator_init(fsk_modulator_t *fsk_trans,
|
||||
fsk_modem_types_t modem_type,
|
||||
uint32_t sample_rate,
|
||||
fsk_data_state_t *fsk_data,
|
||||
float db_level,
|
||||
uint32_t carrier_bits_start,
|
||||
uint32_t carrier_bits_stop,
|
||||
uint32_t chan_sieze_bits,
|
||||
fsk_write_sample_t write_sample_callback,
|
||||
void *user_data)
|
||||
{
|
||||
memset(fsk_trans, 0, sizeof(*fsk_trans));
|
||||
fsk_trans->modem_type = modem_type;
|
||||
teletone_dds_state_set_tone(&fsk_trans->dds, fsk_modem_definitions[fsk_trans->modem_type].freq_space, sample_rate, 0);
|
||||
teletone_dds_state_set_tone(&fsk_trans->dds, fsk_modem_definitions[fsk_trans->modem_type].freq_mark, sample_rate, 1);
|
||||
fsk_trans->bit_factor = (uint32_t)((fsk_modem_definitions[fsk_trans->modem_type].baud_rate * FSK_MOD_FACTOR) / (float)sample_rate);
|
||||
fsk_trans->samples_per_bit = (uint32_t) (sample_rate / fsk_modem_definitions[fsk_trans->modem_type].baud_rate);
|
||||
fsk_trans->est_bytes = (int32_t)(((fsk_data->dlen * 10) + carrier_bits_start + carrier_bits_stop + chan_sieze_bits) * ((fsk_trans->samples_per_bit + 1) * 2));
|
||||
fsk_trans->bit_accum = 0;
|
||||
fsk_trans->fsk_data = fsk_data;
|
||||
teletone_dds_state_set_tx_level(&fsk_trans->dds, db_level);
|
||||
bitstream_init(&fsk_trans->bs, fsk_trans->fsk_data->buf, (uint32_t)fsk_trans->fsk_data->dlen, ENDIAN_BIG, 1);
|
||||
fsk_trans->carrier_bits_start = carrier_bits_start;
|
||||
fsk_trans->carrier_bits_stop = carrier_bits_stop;
|
||||
fsk_trans->chan_sieze_bits = chan_sieze_bits;
|
||||
fsk_trans->write_sample_callback = write_sample_callback;
|
||||
fsk_trans->user_data = user_data;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* mod_fsk -- FSK data transfer
|
||||
*
|
||||
*/
|
||||
#ifndef __FSK_CALLER_ID_H
|
||||
#define __FSK_CALLER_ID_H
|
||||
SWITCH_BEGIN_EXTERN_C
|
||||
#include "fsk.h"
|
||||
#include "uart.h"
|
||||
|
||||
#define FSK_MOD_FACTOR 0x10000
|
||||
|
||||
typedef enum {
|
||||
ENDIAN_BIG = 1,
|
||||
ENDIAN_LITTLE = -1
|
||||
} endian_t;
|
||||
|
||||
typedef enum {
|
||||
CID_TYPE_SDMF = 0x04,
|
||||
CID_TYPE_MDMF = 0x80
|
||||
} cid_type_t;
|
||||
|
||||
typedef enum {
|
||||
MDMF_DATETIME = 1,
|
||||
MDMF_PHONE_NUM = 2,
|
||||
MDMF_DDN = 3,
|
||||
MDMF_NO_NUM = 4,
|
||||
MDMF_PHONE_NAME = 7,
|
||||
MDMF_NO_NAME = 8,
|
||||
MDMF_ALT_ROUTE = 9,
|
||||
MDMF_NAME_VALUE = 10,
|
||||
MDMF_INVALID = 11
|
||||
} mdmf_type_t;
|
||||
|
||||
struct bitstream {
|
||||
uint8_t *data;
|
||||
uint32_t datalen;
|
||||
uint32_t byte_index;
|
||||
uint8_t bit_index;
|
||||
int8_t endian;
|
||||
uint8_t top;
|
||||
uint8_t bot;
|
||||
uint8_t ss;
|
||||
uint8_t ssv;
|
||||
};
|
||||
|
||||
struct fsk_data_state {
|
||||
dsp_fsk_handle_t *fsk1200_handle;
|
||||
uint8_t init;
|
||||
uint8_t *buf;
|
||||
size_t bufsize;
|
||||
size_t blen;
|
||||
size_t bpos;
|
||||
size_t dlen;
|
||||
size_t ppos;
|
||||
int checksum;
|
||||
};
|
||||
|
||||
typedef struct bitstream bitstream_t;
|
||||
typedef struct fsk_data_state fsk_data_state_t;
|
||||
typedef switch_status_t (*fsk_write_sample_t)(int16_t *buf, size_t buflen, void *user_data);
|
||||
|
||||
struct fsk_modulator {
|
||||
teletone_dds_state_t dds;
|
||||
bitstream_t bs;
|
||||
uint32_t carrier_bits_start;
|
||||
uint32_t carrier_bits_stop;
|
||||
uint32_t chan_sieze_bits;
|
||||
uint32_t bit_factor;
|
||||
uint32_t bit_accum;
|
||||
uint32_t sample_counter;
|
||||
int32_t samples_per_bit;
|
||||
int32_t est_bytes;
|
||||
fsk_modem_types_t modem_type;
|
||||
fsk_data_state_t *fsk_data;
|
||||
fsk_write_sample_t write_sample_callback;
|
||||
void *user_data;
|
||||
int16_t sample_buffer[64];
|
||||
};
|
||||
|
||||
|
||||
typedef int (*fsk_data_decoder_t)(fsk_data_state_t *state);
|
||||
|
||||
typedef void (*logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...);
|
||||
typedef struct fsk_modulator fsk_modulator_t;
|
||||
|
||||
switch_status_t fsk_data_init(fsk_data_state_t *state, uint8_t *data, uint32_t datalen);
|
||||
void bitstream_init(bitstream_t *bsp, uint8_t *data, uint32_t datalen, endian_t endian, uint8_t ss);
|
||||
int8_t bitstream_get_bit(bitstream_t *bsp);
|
||||
switch_status_t fsk_data_add_mdmf(fsk_data_state_t *state, mdmf_type_t type, const uint8_t *data, uint32_t datalen);
|
||||
switch_status_t fsk_data_add_checksum(fsk_data_state_t *state);
|
||||
switch_status_t fsk_data_parse(fsk_data_state_t *state, size_t *type, char **data, size_t *len);
|
||||
switch_status_t fsk_demod_feed(fsk_data_state_t *state, int16_t *data, size_t samples);
|
||||
switch_status_t fsk_demod_destroy(fsk_data_state_t *state);
|
||||
int fsk_demod_init(fsk_data_state_t *state, int rate, uint8_t *buf, size_t bufsize);
|
||||
size_t fsk_modulator_generate_bit(fsk_modulator_t *fsk_trans, int8_t bit, int16_t *buf, size_t buflen);
|
||||
int32_t fsk_modulator_generate_carrier_bits(fsk_modulator_t *fsk_trans, uint32_t bits);
|
||||
void fsk_modulator_generate_chan_sieze(fsk_modulator_t *fsk_trans);
|
||||
void fsk_modulator_send_data(fsk_modulator_t *fsk_trans);
|
||||
switch_status_t fsk_modulator_init(fsk_modulator_t *fsk_trans,
|
||||
fsk_modem_types_t modem_type,
|
||||
uint32_t sample_rate,
|
||||
fsk_data_state_t *fsk_data,
|
||||
float db_level,
|
||||
uint32_t carrier_bits_start,
|
||||
uint32_t carrier_bits_stop,
|
||||
uint32_t chan_sieze_bits,
|
||||
fsk_write_sample_t write_sample_callback,
|
||||
void *user_data);
|
||||
|
||||
|
||||
#define fsk_modulator_send_all(_it) fsk_modulator_generate_chan_sieze(_it); \
|
||||
fsk_modulator_generate_carrier_bits(_it, _it->carrier_bits_start); \
|
||||
fsk_modulator_send_data(_it); \
|
||||
fsk_modulator_generate_carrier_bits(_it, _it->carrier_bits_stop)
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
#endif
|
|
@ -0,0 +1,486 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* mod_fsk.c -- FSK data transfer
|
||||
*
|
||||
*/
|
||||
#include <switch.h>
|
||||
#include "fsk_callerid.h"
|
||||
|
||||
/* Prototypes */
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fsk_shutdown);
|
||||
SWITCH_MODULE_RUNTIME_FUNCTION(mod_fsk_runtime);
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_fsk_load);
|
||||
|
||||
/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime)
|
||||
* Defines a switch_loadable_module_function_table_t and a static const char[] modname
|
||||
*/
|
||||
SWITCH_MODULE_DEFINITION(mod_fsk, mod_fsk_load, mod_fsk_shutdown, NULL);
|
||||
|
||||
switch_status_t my_write_sample(int16_t *buf, size_t buflen, void *user_data)
|
||||
{
|
||||
switch_buffer_t *buffer = (switch_buffer_t *) user_data;
|
||||
|
||||
switch_buffer_write(buffer, buf, buflen * 2);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t write_fsk_data(uint32_t rate, int32_t db, switch_buffer_t *buffer, switch_event_t *event, const char *prefix)
|
||||
{
|
||||
fsk_modulator_t fsk_trans;
|
||||
fsk_data_state_t fsk_data = {0};
|
||||
uint8_t databuf[1024] = "";
|
||||
char time_str[9];
|
||||
struct tm tm;
|
||||
time_t now;
|
||||
switch_event_header_t *hp;
|
||||
switch_size_t plen = 0;
|
||||
|
||||
memset(&fsk_trans, 0, sizeof(fsk_trans));
|
||||
|
||||
time(&now);
|
||||
localtime_r(&now, &tm);
|
||||
strftime(time_str, sizeof(time_str), "%m%d%H%M", &tm);
|
||||
|
||||
fsk_data_init(&fsk_data, databuf, sizeof(databuf));
|
||||
fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, (uint8_t *)time_str, strlen(time_str));
|
||||
|
||||
if (prefix) {
|
||||
plen = strlen(prefix);
|
||||
}
|
||||
|
||||
|
||||
if (event) {
|
||||
for (hp = event->headers; hp; hp = hp->next) {
|
||||
char *packed;
|
||||
char *name = hp->name;
|
||||
|
||||
if (plen && strncasecmp(name, prefix, plen)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
name += plen;
|
||||
|
||||
if (zstr(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoding [%s][%s]\n", hp->name, hp->value);
|
||||
|
||||
if (!strcasecmp(name, "phone_num")) {
|
||||
fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NUM, (uint8_t *)hp->value, strlen(hp->value));
|
||||
} else if (!strcasecmp(name, "phone_name")) {
|
||||
fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NAME, (uint8_t *)hp->value, strlen(hp->value));
|
||||
} else {
|
||||
packed = switch_mprintf("%q:%q", name, hp->value);
|
||||
fsk_data_add_mdmf(&fsk_data, MDMF_NAME_VALUE, (uint8_t *)packed, strlen(packed));
|
||||
free(packed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fsk_data_add_checksum(&fsk_data);
|
||||
|
||||
fsk_modulator_init(&fsk_trans, FSK_BELL202, rate, &fsk_data, db, 180, 5, 300, my_write_sample, buffer);
|
||||
fsk_modulator_send_all((&fsk_trans));
|
||||
|
||||
fsk_demod_destroy(&fsk_data);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SWITCH_STANDARD_APP(fsk_send_function) {
|
||||
switch_event_t *event = NULL;
|
||||
switch_buffer_t *buffer;
|
||||
switch_slin_data_t sdata = { 0 };
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_frame_t *read_frame;
|
||||
switch_status_t status;
|
||||
|
||||
|
||||
if (data) {
|
||||
switch_ivr_sleep(session, 1000, SWITCH_TRUE, NULL);
|
||||
switch_core_session_send_dtmf_string(session, (const char *) data);
|
||||
switch_ivr_sleep(session, 1500, SWITCH_TRUE, NULL);
|
||||
}
|
||||
|
||||
if (switch_core_session_set_codec_slin(session, &sdata) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
|
||||
SWITCH_LOG_ERROR, "FAILURE\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch_buffer_create_dynamic(&buffer, 1024, 2048, 0);
|
||||
|
||||
switch_channel_get_variables(channel, &event);
|
||||
|
||||
write_fsk_data(sdata.codec.implementation->actual_samples_per_second, -14, buffer, event, "fsk_");
|
||||
|
||||
while(switch_channel_ready(channel)) {
|
||||
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
|
||||
if (!SWITCH_READ_ACCEPTABLE(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((sdata.write_frame.datalen = switch_buffer_read(buffer, sdata.write_frame.data,
|
||||
sdata.codec.implementation->decoded_bytes_per_packet)) <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (sdata.write_frame.datalen < sdata.codec.implementation->decoded_bytes_per_packet) {
|
||||
memset((char *)sdata.write_frame.data + sdata.write_frame.datalen, 255,
|
||||
sdata.codec.implementation->decoded_bytes_per_packet - sdata.write_frame.datalen);
|
||||
sdata.write_frame.datalen = sdata.codec.implementation->decoded_bytes_per_packet;
|
||||
}
|
||||
sdata.write_frame.samples = sdata.write_frame.datalen / 2;
|
||||
switch_core_session_write_frame(sdata.session, &sdata.write_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
}
|
||||
|
||||
switch_buffer_destroy(&buffer);
|
||||
switch_core_codec_destroy(&sdata.codec);
|
||||
switch_core_session_set_read_codec(session, NULL);
|
||||
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
switch_core_session_t *session;
|
||||
fsk_data_state_t fsk_data;
|
||||
uint8_t fbuf[512];
|
||||
int skip;
|
||||
} switch_fsk_detect_t;
|
||||
|
||||
|
||||
|
||||
|
||||
static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
|
||||
{
|
||||
switch_fsk_detect_t *pvt = (switch_fsk_detect_t *) user_data;
|
||||
//switch_frame_t *frame = NULL;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(pvt->session);
|
||||
|
||||
switch (type) {
|
||||
case SWITCH_ABC_TYPE_INIT: {
|
||||
switch_codec_implementation_t read_impl = { 0 };
|
||||
switch_core_session_get_read_impl(pvt->session, &read_impl);
|
||||
|
||||
if (fsk_demod_init(&pvt->fsk_data, read_impl.actual_samples_per_second, pvt->fbuf, sizeof(pvt->fbuf))) {
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SWITCH_ABC_TYPE_CLOSE:
|
||||
{
|
||||
fsk_demod_destroy(&pvt->fsk_data);
|
||||
}
|
||||
break;
|
||||
|
||||
case SWITCH_ABC_TYPE_WRITE_REPLACE:
|
||||
case SWITCH_ABC_TYPE_READ_REPLACE:
|
||||
{
|
||||
switch_frame_t *rframe;
|
||||
|
||||
if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
|
||||
rframe = switch_core_media_bug_get_read_replace_frame(bug);
|
||||
} else {
|
||||
rframe = switch_core_media_bug_get_write_replace_frame(bug);
|
||||
}
|
||||
|
||||
if (!pvt->skip && fsk_demod_feed(&pvt->fsk_data, rframe->data, rframe->datalen / 2) != SWITCH_STATUS_SUCCESS) {
|
||||
char str[1024] = "";
|
||||
size_t type, mlen;
|
||||
char *sp;
|
||||
switch_event_t *event;
|
||||
const char *app_var;
|
||||
|
||||
switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA);
|
||||
|
||||
while(fsk_data_parse(&pvt->fsk_data, &type, &sp, &mlen) == SWITCH_STATUS_SUCCESS) {
|
||||
char *varname = NULL, *val, *p;
|
||||
|
||||
switch_copy_string(str, sp, mlen+1);
|
||||
*(str+mlen) = '\0';
|
||||
switch_clean_string(str);
|
||||
//printf("TYPE %u LEN %u VAL [%s]\n", (unsigned)type, (unsigned)mlen, str);
|
||||
|
||||
val = str;
|
||||
|
||||
switch(type) {
|
||||
case MDMF_DATETIME:
|
||||
varname = "fsk_datetime";
|
||||
break;
|
||||
case MDMF_PHONE_NAME:
|
||||
varname = "fsk_phone_name";
|
||||
break;
|
||||
case MDMF_PHONE_NUM:
|
||||
varname = "fsk_phone_num";
|
||||
break;
|
||||
case MDMF_NAME_VALUE:
|
||||
varname = switch_core_session_sprintf(pvt->session, "fsk_%s", val);
|
||||
if ((p = strchr(varname, ':'))) {
|
||||
*p++ = '\0';
|
||||
val = p;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (varname && val) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s setting FSK var [%s][%s]\n",
|
||||
switch_channel_get_name(channel), varname, val);
|
||||
switch_channel_set_variable(channel, varname, val);
|
||||
if (event) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, varname, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event) {
|
||||
if (switch_core_session_queue_event(pvt->session, &event) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_destroy(&event);
|
||||
}
|
||||
}
|
||||
|
||||
if ((app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) {
|
||||
char *app_arg;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s processing execute_on_fsk [%s]\n",
|
||||
switch_channel_get_name(channel), app_var);
|
||||
if ((app_arg = strchr(app_var, ' '))) {
|
||||
*app_arg++ = '\0';
|
||||
}
|
||||
switch_core_session_execute_application(pvt->session, app_var, app_arg);
|
||||
}
|
||||
|
||||
pvt->skip = 10;
|
||||
}
|
||||
|
||||
memset(rframe->data, 255, rframe->datalen);
|
||||
|
||||
if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
|
||||
switch_core_media_bug_set_read_replace_frame(bug, rframe);
|
||||
} else {
|
||||
switch_core_media_bug_set_write_replace_frame(bug, rframe);
|
||||
}
|
||||
|
||||
if (pvt->skip && !--pvt->skip) {
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case SWITCH_ABC_TYPE_WRITE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
switch_status_t stop_fsk_detect_session(switch_core_session_t *session)
|
||||
{
|
||||
switch_media_bug_t *bug;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
if ((bug = switch_channel_get_private(channel, "fsk"))) {
|
||||
switch_channel_set_private(channel, "fsk", NULL);
|
||||
switch_core_media_bug_remove(session, &bug);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
switch_status_t fsk_detect_session(switch_core_session_t *session, const char *flags)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_media_bug_t *bug;
|
||||
switch_status_t status;
|
||||
switch_fsk_detect_t *pvt = { 0 };
|
||||
switch_codec_implementation_t read_impl = { 0 };
|
||||
int bflags = SMBF_READ_REPLACE;
|
||||
|
||||
if (strchr(flags, 'w')) {
|
||||
bflags = SMBF_WRITE_REPLACE;
|
||||
}
|
||||
|
||||
switch_core_session_get_read_impl(session, &read_impl);
|
||||
|
||||
if (!(pvt = switch_core_session_alloc(session, sizeof(*pvt)))) {
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
}
|
||||
|
||||
pvt->session = session;
|
||||
|
||||
|
||||
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if ((status = switch_core_media_bug_add(session, "fsk_detect", NULL,
|
||||
fsk_detect_callback, pvt, 0, bflags | SMBF_NO_PAUSE, &bug)) != SWITCH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
switch_channel_set_private(channel, "fsk", bug);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SWITCH_STANDARD_APP(fsk_recv_function)
|
||||
{
|
||||
fsk_detect_session(session, data);
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(fsk_display_function)
|
||||
{
|
||||
/* expected to be called via 'execute_on_fsk' -- passes display update over FSK */
|
||||
|
||||
const char *cid_name, *cid_num;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_core_session_message_t *msg;
|
||||
switch_core_session_t *psession, *usession = NULL;
|
||||
char *flags = (char *) data;
|
||||
|
||||
cid_name = switch_channel_get_variable(channel, "fsk_phone_name");
|
||||
cid_num = switch_channel_get_variable(channel, "fsk_phone_num");
|
||||
|
||||
if (zstr(cid_name)) {
|
||||
cid_name = cid_num;
|
||||
}
|
||||
|
||||
if (zstr(cid_num)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strchr(flags, 'b')) {
|
||||
if (switch_core_session_get_partner(session, &psession) == SWITCH_STATUS_SUCCESS) {
|
||||
usession = psession;
|
||||
}
|
||||
}
|
||||
|
||||
if (!usession) {
|
||||
usession = session;
|
||||
}
|
||||
|
||||
msg = switch_core_session_alloc(usession, sizeof(*msg));
|
||||
MESSAGE_STAMP_FFL(msg);
|
||||
msg->message_id = SWITCH_MESSAGE_INDICATE_DISPLAY;
|
||||
msg->string_array_arg[0] = switch_core_session_strdup(usession, cid_name);
|
||||
msg->string_array_arg[1] = switch_core_session_strdup(usession, cid_num);
|
||||
msg->from = __FILE__;
|
||||
switch_core_session_queue_message(usession, msg);
|
||||
|
||||
if (psession) {
|
||||
switch_core_session_rwunlock(psession);
|
||||
psession = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(fsk_simplify_function)
|
||||
{
|
||||
/* expected to be called via 'execute_on_fsk' -- redirects call to point-to-point and eliminates legs in the middle */
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
const char *sip_uri, *fsk_simplify_profile, *fsk_simplify_context;
|
||||
char *bridgeto;
|
||||
|
||||
if (!(sip_uri = switch_channel_get_variable(channel, "fsk_uri"))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s Missing URI field!\n", switch_channel_get_name(channel));
|
||||
}
|
||||
|
||||
if (!(fsk_simplify_profile = switch_channel_get_variable(channel, "fsk_simplify_profile"))) {
|
||||
fsk_simplify_profile = "internal";
|
||||
}
|
||||
|
||||
fsk_simplify_context = switch_channel_get_variable(channel, "fsk_simplify_context");
|
||||
|
||||
if (!zstr(sip_uri)) {
|
||||
switch_core_session_t *psession;
|
||||
switch_channel_t *pchannel;
|
||||
|
||||
bridgeto = switch_core_session_sprintf(session, "bridge:sofia/%s/sip:%s", fsk_simplify_profile, sip_uri);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s transfering to [%s]\n",
|
||||
switch_channel_get_name(channel), bridgeto);
|
||||
|
||||
|
||||
if (switch_core_session_get_partner(session, &psession) == SWITCH_STATUS_SUCCESS) {
|
||||
pchannel = switch_core_session_get_channel(psession);
|
||||
switch_channel_set_flag(pchannel, CF_REDIRECT);
|
||||
switch_channel_set_flag(pchannel, CF_TRANSFER);
|
||||
}
|
||||
|
||||
switch_ivr_session_transfer(session, bridgeto, "inline", fsk_simplify_context);
|
||||
|
||||
if (psession) {
|
||||
switch_ivr_session_transfer(psession, "sleep:5000", "inline", NULL);
|
||||
switch_core_session_rwunlock(psession);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Macro expands to: switch_status_t mod_fsk_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_fsk_load)
|
||||
{
|
||||
switch_application_interface_t *app_interface;
|
||||
|
||||
/* connect my internal structure to the blank pointer passed to me */
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "fsk_send", "fsk_send", NULL, fsk_send_function, NULL, SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "fsk_recv", "fsk_recv", NULL, fsk_recv_function, NULL, SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "fsk_simplify", "fsk_simplify", NULL, fsk_simplify_function, NULL, SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "fsk_display", "fsk_display", NULL, fsk_display_function, NULL, SAF_NONE);
|
||||
|
||||
/* indicate that the module should continue to be loaded */
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
Called when the system shuts down
|
||||
Macro expands to: switch_status_t mod_fsk_shutdown() */
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fsk_shutdown)
|
||||
{
|
||||
/* Cleanup dynamically allocated config settings */
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4
|
||||
*/
|
|
@ -0,0 +1,124 @@
|
|||
|
||||
/*
|
||||
* uart.c
|
||||
*
|
||||
* Copyright (c) 2005 Robert Krten. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This module contains a simple 8-bit UART, which performs a callback
|
||||
* with the decoded byte value.
|
||||
*
|
||||
* 2005 06 11 R. Krten created
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "uart.h"
|
||||
|
||||
/*
|
||||
* dsp_uart_attr_init
|
||||
*
|
||||
* Initializes the attributes structure; this must be done before the
|
||||
* attributes structure is used.
|
||||
*/
|
||||
|
||||
void dsp_uart_attr_init (dsp_uart_attr_t *attr)
|
||||
{
|
||||
memset (attr, 0, sizeof (*attr));
|
||||
}
|
||||
|
||||
/*
|
||||
* dsp_uart_attr_get_bytehandler
|
||||
* dsp_uart_attr_set_bytehandler
|
||||
*
|
||||
* These functions get and set their respective elements from the
|
||||
* attributes structure. If an error code is returned, it is just
|
||||
* zero == ok, -1 == fail.
|
||||
*/
|
||||
|
||||
bytehandler_func_t dsp_uart_attr_get_bytehandler(dsp_uart_attr_t *attr, void **bytehandler_arg)
|
||||
{
|
||||
*bytehandler_arg = attr->bytehandler_arg;
|
||||
return attr->bytehandler;
|
||||
}
|
||||
|
||||
void dsp_uart_attr_set_bytehandler(dsp_uart_attr_t *attr, bytehandler_func_t bytehandler, void *bytehandler_arg)
|
||||
{
|
||||
attr->bytehandler = bytehandler;
|
||||
attr->bytehandler_arg = bytehandler_arg;
|
||||
}
|
||||
|
||||
dsp_uart_handle_t *dsp_uart_create(dsp_uart_attr_t *attr)
|
||||
{
|
||||
dsp_uart_handle_t *handle;
|
||||
|
||||
handle = malloc(sizeof (*handle));
|
||||
if (handle) {
|
||||
memset(handle, 0, sizeof (*handle));
|
||||
|
||||
/* fill the attributes member */
|
||||
memcpy(&handle->attr, attr, sizeof (*attr));
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
void dsp_uart_destroy(dsp_uart_handle_t **handle)
|
||||
{
|
||||
if (*handle) {
|
||||
free(*handle);
|
||||
*handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dsp_uart_bit_handler(void *x, int bit)
|
||||
{
|
||||
dsp_uart_handle_t *handle = (dsp_uart_handle_t *) x;
|
||||
|
||||
if (!handle->have_start) {
|
||||
if (bit) {
|
||||
return; /* waiting for start bit (0) */
|
||||
}
|
||||
handle->have_start = 1;
|
||||
handle->data = 0;
|
||||
handle->nbits = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
handle->data >>= 1;
|
||||
handle->data |= 0x80 * !!bit;
|
||||
handle->nbits++;
|
||||
|
||||
if (handle->nbits == 8) {
|
||||
handle->attr.bytehandler(handle->attr.bytehandler_arg, handle->data);
|
||||
handle->nbits = 0;
|
||||
handle->data = 0;
|
||||
handle->have_start = 0;
|
||||
}
|
||||
/* might consider handling errors in the future... */
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* uart.h
|
||||
*
|
||||
* Copyright (c) 2005 Robert Krten. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This module contains the manifest constants and declarations for
|
||||
* the UART module.
|
||||
*
|
||||
* 2005 06 19 R. Krten created
|
||||
*/
|
||||
|
||||
#ifndef __UART_H__
|
||||
#define __UART_H__
|
||||
|
||||
typedef void (*bytehandler_func_t) (void *, int);
|
||||
typedef void (*bithandler_func_t) (void *, int);
|
||||
|
||||
|
||||
typedef struct dsp_uart_attr_s
|
||||
{
|
||||
bytehandler_func_t bytehandler; /* byte handler */
|
||||
void *bytehandler_arg; /* arbitrary ID passed to bytehandler as first argument */
|
||||
} dsp_uart_attr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
dsp_uart_attr_t attr;
|
||||
int have_start; /* wait for start bit to show up */
|
||||
int data; /* data buffer */
|
||||
int nbits; /* number of bits accumulated so far */
|
||||
} dsp_uart_handle_t;
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*
|
||||
* General calling order is:
|
||||
* a) create the attributes structure (dsp_uart_attr_init)
|
||||
* b) initialize fields in the attributes structure (dsp_uart_attr_set_*)
|
||||
* c) create a Bell-202 handle (dsp_uart_create)
|
||||
* d) feed bits through dsp_uart_bit_handler
|
||||
*/
|
||||
|
||||
void dsp_uart_attr_init(dsp_uart_attr_t *attributes);
|
||||
|
||||
bytehandler_func_t dsp_uart_attr_get_bytehandler(dsp_uart_attr_t *attributes, void **bytehandler_arg);
|
||||
void dsp_uart_attr_set_bytehandler(dsp_uart_attr_t *attributes, bytehandler_func_t bytehandler, void *bytehandler_arg);
|
||||
|
||||
dsp_uart_handle_t * dsp_uart_create(dsp_uart_attr_t *attributes);
|
||||
void dsp_uart_destroy(dsp_uart_handle_t **handle);
|
||||
|
||||
void dsp_uart_bit_handler(void *handle, int bit);
|
||||
|
||||
#endif
|
||||
|
|
@ -1973,12 +1973,22 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p
|
|||
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
|
||||
TRY_CODE(switch_ivr_phrase_macro(session, VM_CHOOSE_GREETING_FAIL_MACRO, NULL, NULL, NULL));
|
||||
} else {
|
||||
switch_event_t *params;
|
||||
|
||||
TRY_CODE(switch_ivr_phrase_macro(session, VM_CHOOSE_GREETING_SELECTED_MACRO, input, NULL, NULL));
|
||||
sql =
|
||||
switch_mprintf("update voicemail_prefs set greeting_path='%s' where username='%s' and domain='%s'", file_path, myid,
|
||||
domain_name);
|
||||
vm_execute_sql(profile, sql, profile->mutex);
|
||||
switch_safe_free(sql);
|
||||
|
||||
switch_event_create_subclass(¶ms, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT);
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Action", "change-greeting");
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Greeting-Path", file_path);
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-User", myid);
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Domain", domain_name);
|
||||
switch_channel_event_set_data(channel, params);
|
||||
switch_event_fire(¶ms);
|
||||
}
|
||||
switch_safe_free(file_path);
|
||||
} else if (!strcmp(input, profile->record_greeting_key)) {
|
||||
|
@ -1989,6 +1999,7 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p
|
|||
if (num < 1 || num > VM_MAX_GREETINGS) {
|
||||
TRY_CODE(switch_ivr_phrase_macro(session, VM_CHOOSE_GREETING_FAIL_MACRO, NULL, NULL, NULL));
|
||||
} else {
|
||||
switch_event_t *params;
|
||||
file_path = switch_mprintf("%s%sgreeting_%d.%s", dir_path, SWITCH_PATH_SEPARATOR, num, profile->file_ext);
|
||||
TRY_CODE(create_file(session, profile, VM_RECORD_GREETING_MACRO, file_path, &message_len, SWITCH_TRUE, NULL, NULL));
|
||||
sql =
|
||||
|
@ -1997,6 +2008,14 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p
|
|||
vm_execute_sql(profile, sql, profile->mutex);
|
||||
switch_safe_free(sql);
|
||||
switch_safe_free(file_path);
|
||||
|
||||
switch_event_create_subclass(¶ms, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT);
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Action", "record-greeting");
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Greeting-Path", file_path);
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-User", myid);
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Domain", domain_name);
|
||||
switch_channel_event_set_data(channel, params);
|
||||
switch_event_fire(¶ms);
|
||||
}
|
||||
|
||||
} else if (!strcmp(input, profile->change_pass_key)) {
|
||||
|
@ -2027,12 +2046,21 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p
|
|||
switch_event_fire(¶ms);
|
||||
|
||||
} else if (!strcmp(input, profile->record_name_key)) {
|
||||
switch_event_t *params;
|
||||
file_path = switch_mprintf("%s%srecorded_name.%s", dir_path, SWITCH_PATH_SEPARATOR, profile->file_ext);
|
||||
TRY_CODE(create_file(session, profile, VM_RECORD_NAME_MACRO, file_path, &message_len, SWITCH_FALSE, NULL, NULL));
|
||||
sql = switch_mprintf("update voicemail_prefs set name_path='%s' where username='%s' and domain='%s'", file_path, myid, domain_name);
|
||||
vm_execute_sql(profile, sql, profile->mutex);
|
||||
switch_safe_free(file_path);
|
||||
switch_safe_free(sql);
|
||||
|
||||
switch_event_create_subclass(¶ms, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT);
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Action", "record-name");
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Name-Path", file_path);
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-User", myid);
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Domain", domain_name);
|
||||
switch_channel_event_set_data(channel, params);
|
||||
switch_event_fire(¶ms);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -2337,6 +2365,7 @@ static switch_status_t deliver_vm(vm_profile_t *profile,
|
|||
const char *filename;
|
||||
switch_xml_t x_param, x_params;
|
||||
char *vm_email = NULL;
|
||||
char *vm_email_from = NULL;
|
||||
char *vm_notify_email = NULL;
|
||||
char *email_addr = NULL;
|
||||
char *vm_timezone = NULL;
|
||||
|
@ -2401,6 +2430,8 @@ static switch_status_t deliver_vm(vm_profile_t *profile,
|
|||
vm_email = switch_core_strdup(pool, val);
|
||||
} else if (!strcasecmp(var, "vm-notify-mailto")) {
|
||||
vm_notify_email = switch_core_strdup(pool, val);
|
||||
} else if (!strcasecmp(var, "vm-mailfrom")) {
|
||||
vm_email_from = switch_core_strdup(pool, val);
|
||||
} else if (!strcasecmp(var, "email-addr")) {
|
||||
email_addr = switch_core_strdup(pool, val);
|
||||
} else if (!strcasecmp(var, "vm-email-all-messages") && (send_main = switch_true(val))) {
|
||||
|
@ -2544,7 +2575,9 @@ static switch_status_t deliver_vm(vm_profile_t *profile,
|
|||
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "voicemail_message_len", duration_str);
|
||||
|
||||
if (zstr(profile->email_from)) {
|
||||
if (!zstr(vm_email_from)) {
|
||||
from = switch_core_strdup(pool, vm_email_from);
|
||||
} else if (zstr(profile->email_from)) {
|
||||
from = switch_core_sprintf(pool, "%s@%s", myid, domain_name);
|
||||
} else {
|
||||
from = switch_event_expand_headers(params, profile->email_from);
|
||||
|
|
|
@ -163,7 +163,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_ilbc_load)
|
|||
"mode=30", /* default fmtp to send (can be overridden by the init function) */
|
||||
8000, /* samples transferred per second */
|
||||
8000, /* actual samples transferred per second */
|
||||
13300, /* bits transferred per second */
|
||||
13330, /* bits transferred per second */
|
||||
30000, /* number of microseconds per frame */
|
||||
ILBC_BLOCK_LEN_30MS, /* number of samples per frame */
|
||||
ILBC_BLOCK_LEN_30MS * 2, /* number of bytes per frame decompressed */
|
||||
|
|
|
@ -403,6 +403,7 @@ struct sofia_gateway {
|
|||
char *register_from;
|
||||
char *register_contact;
|
||||
char *extension;
|
||||
char *real_extension;
|
||||
char *register_to;
|
||||
char *register_proxy;
|
||||
char *register_sticky_proxy;
|
||||
|
|
|
@ -161,6 +161,15 @@ static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip, swit
|
|||
char *full;
|
||||
|
||||
if (sip) {
|
||||
if (sip->sip_route) {
|
||||
if ((full = sip_header_as_string(profile->home, (void *) sip->sip_route))) {
|
||||
const char *v = switch_channel_get_variable(channel, "sip_full_route");
|
||||
if (!v) {
|
||||
switch_channel_set_variable(channel, "sip_full_route", full);
|
||||
}
|
||||
su_free(profile->home, full);
|
||||
}
|
||||
}
|
||||
if (sip->sip_via) {
|
||||
if ((full = sip_header_as_string(profile->home, (void *) sip->sip_via))) {
|
||||
const char *v = switch_channel_get_variable(channel, "sip_full_via");
|
||||
|
@ -2056,10 +2065,6 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
|
|||
from_user = username;
|
||||
}
|
||||
|
||||
if (zstr(extension)) {
|
||||
extension = username;
|
||||
}
|
||||
|
||||
if (zstr(proxy)) {
|
||||
proxy = realm;
|
||||
}
|
||||
|
@ -2151,8 +2156,13 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
|
|||
sipip = profile->sipip;
|
||||
}
|
||||
|
||||
gateway->extension = switch_core_strdup(gateway->pool, extension);
|
||||
if (zstr(extension)) {
|
||||
extension = username;
|
||||
} else {
|
||||
gateway->real_extension = switch_core_strdup(gateway->pool, extension);
|
||||
}
|
||||
|
||||
gateway->extension = switch_core_strdup(gateway->pool, extension);
|
||||
|
||||
if (!strncasecmp(proxy, "sip:", 4)) {
|
||||
gateway->register_proxy = switch_core_strdup(gateway->pool, proxy);
|
||||
|
@ -6222,6 +6232,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
|
|||
char acl_token[512] = "";
|
||||
sofia_transport_t transport;
|
||||
const char *gw_name = NULL;
|
||||
const char *gw_param_name = NULL;
|
||||
char *call_info_str = NULL;
|
||||
nua_handle_t *bnh = NULL;
|
||||
char sip_acl_authed_by[512] = "";
|
||||
|
@ -6854,7 +6865,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
|
|||
|
||||
|
||||
if (sip->sip_request->rq_url->url_params) {
|
||||
gw_name = sofia_glue_find_parameter_value(session, sip->sip_request->rq_url->url_params, "gw=");
|
||||
gw_param_name = sofia_glue_find_parameter_value(session, sip->sip_request->rq_url->url_params, "gw=");
|
||||
}
|
||||
|
||||
if (strstr(destination_number, "gw+")) {
|
||||
|
@ -6869,19 +6880,35 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
|
|||
}
|
||||
}
|
||||
|
||||
if (gw_name) {
|
||||
sofia_gateway_t *gateway;
|
||||
if (gw_name && (gateway = sofia_reg_find_gateway(gw_name))) {
|
||||
if (gw_name || gw_param_name) {
|
||||
sofia_gateway_t *gateway = NULL;
|
||||
char *extension = NULL;
|
||||
|
||||
if (gw_name && ((gateway = sofia_reg_find_gateway(gw_name)))) {
|
||||
gw_param_name = NULL;
|
||||
extension = gateway->extension;
|
||||
}
|
||||
|
||||
if (!gateway && gw_param_name) {
|
||||
gateway = sofia_reg_find_gateway(gw_param_name);
|
||||
extension = gateway->real_extension;
|
||||
}
|
||||
|
||||
if (gateway) {
|
||||
context = switch_core_session_strdup(session, gateway->register_context);
|
||||
switch_channel_set_variable(channel, "sip_gateway", gateway->name);
|
||||
|
||||
if (gateway->extension) {
|
||||
if (!strcasecmp(gateway->extension, "auto_to_user")) {
|
||||
if (!zstr(extension)) {
|
||||
if (!strcasecmp(extension, "auto_to_user")) {
|
||||
destination_number = sip->sip_to->a_url->url_user;
|
||||
} else if (!strcasecmp(extension, "auto")) {
|
||||
if (gw_name) {
|
||||
destination_number = sip->sip_to->a_url->url_user;
|
||||
}
|
||||
} else {
|
||||
destination_number = switch_core_session_strdup(session, gateway->extension);
|
||||
destination_number = switch_core_session_strdup(session, extension);
|
||||
}
|
||||
} else {
|
||||
} else if (!gw_param_name) {
|
||||
destination_number = sip->sip_to->a_url->url_user;
|
||||
}
|
||||
|
||||
|
|
|
@ -3550,13 +3550,53 @@ void sofia_glue_set_r_sdp_codec_string(switch_core_session_t *session, const cha
|
|||
}
|
||||
|
||||
if (match) {
|
||||
if (ptime > 0) {
|
||||
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s@%uh@%di", imp->iananame, (unsigned int) map->rm_rate,
|
||||
ptime);
|
||||
} else {
|
||||
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s@%uh", imp->iananame, (unsigned int) map->rm_rate);
|
||||
int codec_ms = ptime;
|
||||
uint32_t map_bit_rate = 0;
|
||||
char ptstr[20] = "";
|
||||
char ratestr[20] = "";
|
||||
char bitstr[20] = "";
|
||||
switch_codec_fmtp_t codec_fmtp = { 0 };
|
||||
|
||||
if (!codec_ms) {
|
||||
codec_ms = switch_default_ptime(map->rm_encoding, map->rm_pt);
|
||||
}
|
||||
already_did[imp->ianacode] = 1;
|
||||
|
||||
map_bit_rate = switch_known_bitrate(map->rm_pt);
|
||||
|
||||
if (!ptime && !strcasecmp(map->rm_encoding, "g723")) {
|
||||
ptime = codec_ms = 30;
|
||||
}
|
||||
|
||||
if (zstr(map->rm_fmtp)) {
|
||||
if (!strcasecmp(map->rm_encoding, "ilbc")) {
|
||||
ptime = codec_ms = 30;
|
||||
map_bit_rate = 13330;
|
||||
}
|
||||
} else {
|
||||
if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) {
|
||||
if (codec_fmtp.bits_per_second) {
|
||||
map_bit_rate = codec_fmtp.bits_per_second;
|
||||
}
|
||||
if (codec_fmtp.microseconds_per_packet) {
|
||||
codec_ms = (codec_fmtp.microseconds_per_packet / 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (map->rm_rate) {
|
||||
switch_snprintf(ratestr, sizeof(ratestr), "@%uh", (unsigned int) map->rm_rate);
|
||||
}
|
||||
|
||||
if (codec_ms) {
|
||||
switch_snprintf(ptstr, sizeof(ptstr), "@%di", codec_ms);
|
||||
}
|
||||
|
||||
if (map_bit_rate) {
|
||||
switch_snprintf(bitstr, sizeof(bitstr), "@%db", map_bit_rate);
|
||||
}
|
||||
|
||||
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s%s%s%s", map->rm_encoding, ratestr, ptstr, bitstr);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4378,6 +4418,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
|
|||
if (zstr(map->rm_fmtp)) {
|
||||
if (!strcasecmp(map->rm_encoding, "ilbc")) {
|
||||
ptime = codec_ms = 30;
|
||||
map_bit_rate = 13330;
|
||||
}
|
||||
} else {
|
||||
if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) {
|
||||
|
@ -4389,8 +4430,6 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (i = first; i < last && i < tech_pvt->num_codecs; i++) {
|
||||
const switch_codec_implementation_t *imp = tech_pvt->codecs[i];
|
||||
|
@ -4401,7 +4440,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
|
|||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Compare [%s:%d:%u:%d:%u]/[%s:%d:%u:%d:%u]\n",
|
||||
rm_encoding, map->rm_pt, (int) map->rm_rate, ptime, map_bit_rate,
|
||||
rm_encoding, map->rm_pt, (int) map->rm_rate, codec_ms, map_bit_rate,
|
||||
imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate);
|
||||
if ((zstr(map->rm_encoding) || (tech_pvt->profile->ndlb & PFLAG_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
|
||||
match = (map->rm_pt == imp->ianacode) ? 1 : 0;
|
||||
|
@ -6149,6 +6188,14 @@ void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str)
|
|||
if (switch_stristr("~NEVER_SEND_MARKER", str)) {
|
||||
*flag_pole &= ~RTP_BUG_NEVER_SEND_MARKER;
|
||||
}
|
||||
|
||||
if (switch_stristr("IGNORE_DTMF_DURATION", str)) {
|
||||
*flag_pole |= RTP_BUG_IGNORE_DTMF_DURATION;
|
||||
}
|
||||
|
||||
if (switch_stristr("~IGNORE_DTMF_DURATION", str)) {
|
||||
*flag_pole &= ~RTP_BUG_IGNORE_DTMF_DURATION;
|
||||
}
|
||||
}
|
||||
|
||||
char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np)
|
||||
|
|
|
@ -1078,7 +1078,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
|||
if (exptime && v_event && *v_event) {
|
||||
char *exp_var;
|
||||
char *allow_multireg = NULL;
|
||||
int force_connectile = 0;
|
||||
int auto_connectile = 0;
|
||||
|
||||
allow_multireg = switch_event_get_header(*v_event, "sip-allow-multiple-registrations");
|
||||
if (allow_multireg && switch_false(allow_multireg)) {
|
||||
|
@ -1097,11 +1097,26 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
|
|||
|
||||
if (profile->rport_level == 3 && sip->sip_user_agent &&
|
||||
sip->sip_user_agent->g_string && !strncasecmp(sip->sip_user_agent->g_string, "Polycom", 7)) {
|
||||
force_connectile = 1;
|
||||
if (sip && sip->sip_via) {
|
||||
const char *host = sip->sip_via->v_host;
|
||||
const char *c_port = sip->sip_via->v_port;
|
||||
int port = 0;
|
||||
|
||||
if (c_port) port = atoi(c_port);
|
||||
if (!port) port = 5060;
|
||||
|
||||
if (host && strcmp(network_ip, host)) {
|
||||
auto_connectile = 1;
|
||||
} else if (port != network_port) {
|
||||
auto_connectile = 1;
|
||||
}
|
||||
} else {
|
||||
auto_connectile = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((v_contact_str = switch_event_get_header(*v_event, "sip-force-contact")) || force_connectile) {
|
||||
if ((!strcasecmp(v_contact_str, "NDLB-connectile-dysfunction-2.0")) || force_connectile) {
|
||||
if ((v_contact_str = switch_event_get_header(*v_event, "sip-force-contact")) || auto_connectile) {
|
||||
if ((!strcasecmp(v_contact_str, "NDLB-connectile-dysfunction-2.0")) || auto_connectile) {
|
||||
char *path_encoded;
|
||||
size_t path_encoded_len;
|
||||
char my_contact_str[1024];
|
||||
|
|
|
@ -1331,6 +1331,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_HOLD_MUSIC_VARIABLE_get() {
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get() {
|
||||
char * jresult ;
|
||||
char *result = 0 ;
|
||||
|
||||
result = (char *)("temp_hold_music");
|
||||
jresult = SWIG_csharp_string_callback((const char *)result);
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_EXPORT_VARS_VARIABLE_get() {
|
||||
char * jresult ;
|
||||
char *result = 0 ;
|
||||
|
@ -7112,6 +7122,20 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_dmachine(void * jar
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_set_codec_slin(void * jarg1, void * jarg2) {
|
||||
int jresult ;
|
||||
switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
|
||||
switch_slin_data_t *arg2 = (switch_slin_data_t *) 0 ;
|
||||
switch_status_t result;
|
||||
|
||||
arg1 = (switch_core_session_t *)jarg1;
|
||||
arg2 = (switch_slin_data_t *)jarg2;
|
||||
result = (switch_status_t)switch_core_session_set_codec_slin(arg1,arg2);
|
||||
jresult = result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_uuid() {
|
||||
char * jresult ;
|
||||
char *result = 0 ;
|
||||
|
@ -10392,6 +10416,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_execute_sql_callback(void * ja
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_affected_rows(void * jarg1) {
|
||||
int jresult ;
|
||||
switch_cache_db_handle_t *arg1 = (switch_cache_db_handle_t *) 0 ;
|
||||
int result;
|
||||
|
||||
arg1 = (switch_cache_db_handle_t *)jarg1;
|
||||
result = (int)switch_cache_db_affected_rows(arg1);
|
||||
jresult = result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_switch_cache_db_status(void * jarg1) {
|
||||
switch_stream_handle_t *arg1 = (switch_stream_handle_t *) 0 ;
|
||||
|
||||
|
@ -11972,6 +12008,30 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_is_digit_string(char * jarg1) {
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT char SWIGSTDCALL CSharp_switch_itodtmf(char jarg1) {
|
||||
char jresult ;
|
||||
char arg1 ;
|
||||
char result;
|
||||
|
||||
arg1 = (char)jarg1;
|
||||
result = (char)switch_itodtmf(arg1);
|
||||
jresult = result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_switch_dtmftoi(char * jarg1) {
|
||||
int jresult ;
|
||||
char *arg1 = (char *) 0 ;
|
||||
int result;
|
||||
|
||||
arg1 = (char *)jarg1;
|
||||
result = (int)switch_dtmftoi(arg1);
|
||||
jresult = result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_known_bitrate(unsigned char jarg1) {
|
||||
unsigned long jresult ;
|
||||
switch_payload_t arg1 ;
|
||||
|
@ -22102,6 +22162,119 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_api_interface(void * jarg1) {
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_session_set(void * jarg1, void * jarg2) {
|
||||
switch_slin_data *arg1 = (switch_slin_data *) 0 ;
|
||||
switch_core_session_t *arg2 = (switch_core_session_t *) 0 ;
|
||||
|
||||
arg1 = (switch_slin_data *)jarg1;
|
||||
arg2 = (switch_core_session_t *)jarg2;
|
||||
if (arg1) (arg1)->session = arg2;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_session_get(void * jarg1) {
|
||||
void * jresult ;
|
||||
switch_slin_data *arg1 = (switch_slin_data *) 0 ;
|
||||
switch_core_session_t *result = 0 ;
|
||||
|
||||
arg1 = (switch_slin_data *)jarg1;
|
||||
result = (switch_core_session_t *) ((arg1)->session);
|
||||
jresult = (void *)result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_write_frame_set(void * jarg1, void * jarg2) {
|
||||
switch_slin_data *arg1 = (switch_slin_data *) 0 ;
|
||||
switch_frame_t *arg2 = (switch_frame_t *) 0 ;
|
||||
|
||||
arg1 = (switch_slin_data *)jarg1;
|
||||
arg2 = (switch_frame_t *)jarg2;
|
||||
if (arg1) (arg1)->write_frame = *arg2;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_write_frame_get(void * jarg1) {
|
||||
void * jresult ;
|
||||
switch_slin_data *arg1 = (switch_slin_data *) 0 ;
|
||||
switch_frame_t *result = 0 ;
|
||||
|
||||
arg1 = (switch_slin_data *)jarg1;
|
||||
result = (switch_frame_t *)& ((arg1)->write_frame);
|
||||
jresult = (void *)result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_codec_set(void * jarg1, void * jarg2) {
|
||||
switch_slin_data *arg1 = (switch_slin_data *) 0 ;
|
||||
switch_codec_t *arg2 = (switch_codec_t *) 0 ;
|
||||
|
||||
arg1 = (switch_slin_data *)jarg1;
|
||||
arg2 = (switch_codec_t *)jarg2;
|
||||
if (arg1) (arg1)->codec = *arg2;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_codec_get(void * jarg1) {
|
||||
void * jresult ;
|
||||
switch_slin_data *arg1 = (switch_slin_data *) 0 ;
|
||||
switch_codec_t *result = 0 ;
|
||||
|
||||
arg1 = (switch_slin_data *)jarg1;
|
||||
result = (switch_codec_t *)& ((arg1)->codec);
|
||||
jresult = (void *)result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_frame_data_set(void * jarg1, char * jarg2) {
|
||||
switch_slin_data *arg1 = (switch_slin_data *) 0 ;
|
||||
char *arg2 ;
|
||||
|
||||
arg1 = (switch_slin_data *)jarg1;
|
||||
arg2 = (char *)jarg2;
|
||||
{
|
||||
if(arg2) {
|
||||
strncpy((char*)arg1->frame_data, (const char *)arg2, 4096-1);
|
||||
arg1->frame_data[4096-1] = 0;
|
||||
} else {
|
||||
arg1->frame_data[0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT char * SWIGSTDCALL CSharp_switch_slin_data_frame_data_get(void * jarg1) {
|
||||
char * jresult ;
|
||||
switch_slin_data *arg1 = (switch_slin_data *) 0 ;
|
||||
char *result = 0 ;
|
||||
|
||||
arg1 = (switch_slin_data *)jarg1;
|
||||
result = (char *)(char *) ((arg1)->frame_data);
|
||||
jresult = SWIG_csharp_string_callback((const char *)result);
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_slin_data() {
|
||||
void * jresult ;
|
||||
switch_slin_data *result = 0 ;
|
||||
|
||||
result = (switch_slin_data *)new switch_slin_data();
|
||||
jresult = (void *)result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_slin_data(void * jarg1) {
|
||||
switch_slin_data *arg1 = (switch_slin_data *) 0 ;
|
||||
|
||||
arg1 = (switch_slin_data *)jarg1;
|
||||
delete arg1;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_timetable_profile_created_set(void * jarg1, void * jarg2) {
|
||||
switch_channel_timetable *arg1 = (switch_channel_timetable *) 0 ;
|
||||
switch_time_t arg2 ;
|
||||
|
@ -22834,6 +23007,30 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_variable_partner(void *
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_hold_music(void * jarg1) {
|
||||
char * jresult ;
|
||||
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||
char *result = 0 ;
|
||||
|
||||
arg1 = (switch_channel_t *)jarg1;
|
||||
result = (char *)switch_channel_get_hold_music(arg1);
|
||||
jresult = SWIG_csharp_string_callback((const char *)result);
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_hold_music_partner(void * jarg1) {
|
||||
char * jresult ;
|
||||
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||
char *result = 0 ;
|
||||
|
||||
arg1 = (switch_channel_t *)jarg1;
|
||||
result = (char *)switch_channel_get_hold_music_partner(arg1);
|
||||
jresult = SWIG_csharp_string_callback((const char *)result);
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_var_check(void * jarg1, char * jarg2, char * jarg3, char * jarg4, int jarg5) {
|
||||
int jresult ;
|
||||
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||
|
@ -23079,6 +23276,20 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_channel_test_cap(void * jarg1
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_channel_test_cap_partner(void * jarg1, int jarg2) {
|
||||
unsigned long jresult ;
|
||||
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||
switch_channel_cap_t arg2 ;
|
||||
uint32_t result;
|
||||
|
||||
arg1 = (switch_channel_t *)jarg1;
|
||||
arg2 = (switch_channel_cap_t)jarg2;
|
||||
result = (uint32_t)switch_channel_test_cap_partner(arg1,arg2);
|
||||
jresult = (unsigned long)result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_set_flag_partner(void * jarg1, int jarg2) {
|
||||
int jresult ;
|
||||
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||
|
@ -28362,6 +28573,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_deactivate_jitter_buffer(void * jar
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_pause_jitter_buffer(void * jarg1, int jarg2) {
|
||||
int jresult ;
|
||||
switch_rtp_t *arg1 = (switch_rtp_t *) 0 ;
|
||||
switch_bool_t arg2 ;
|
||||
switch_status_t result;
|
||||
|
||||
arg1 = (switch_rtp_t *)jarg1;
|
||||
arg2 = (switch_bool_t)jarg2;
|
||||
result = (switch_status_t)switch_rtp_pause_jitter_buffer(arg1,arg2);
|
||||
jresult = result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_flag(void * jarg1, unsigned long jarg2) {
|
||||
switch_rtp_t *arg1 = (switch_rtp_t *) 0 ;
|
||||
switch_rtp_flag_t arg2 ;
|
||||
|
@ -33252,6 +33477,24 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_voice_name_get(void * jarg1) {
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_insertFile(void * jarg1, char * jarg2, char * jarg3, int jarg4) {
|
||||
int jresult ;
|
||||
CoreSession *arg1 = (CoreSession *) 0 ;
|
||||
char *arg2 = (char *) 0 ;
|
||||
char *arg3 = (char *) 0 ;
|
||||
int arg4 ;
|
||||
int result;
|
||||
|
||||
arg1 = (CoreSession *)jarg1;
|
||||
arg2 = (char *)jarg2;
|
||||
arg3 = (char *)jarg3;
|
||||
arg4 = (int)jarg4;
|
||||
result = (int)(arg1)->insertFile((char const *)arg2,(char const *)arg3,arg4);
|
||||
jresult = result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Answer(void * jarg1) {
|
||||
int jresult ;
|
||||
CoreSession *arg1 = (CoreSession *) 0 ;
|
||||
|
|
|
@ -1422,6 +1422,17 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_HOLD_MUSIC_VARIABLE_get() {
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get() {
|
||||
char * jresult ;
|
||||
char *result = 0 ;
|
||||
|
||||
result = (char *) "temp_hold_music";
|
||||
|
||||
jresult = SWIG_csharp_string_callback((const char *)result);
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_EXPORT_VARS_VARIABLE_get() {
|
||||
char * jresult ;
|
||||
char *result = 0 ;
|
||||
|
@ -12304,6 +12315,30 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_is_digit_string(char * jarg1) {
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT char SWIGSTDCALL CSharp_switch_itodtmf(char jarg1) {
|
||||
char jresult ;
|
||||
char arg1 ;
|
||||
char result;
|
||||
|
||||
arg1 = (char)jarg1;
|
||||
result = (char)switch_itodtmf(arg1);
|
||||
jresult = result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_switch_dtmftoi(char * jarg1) {
|
||||
int jresult ;
|
||||
char *arg1 = (char *) 0 ;
|
||||
int result;
|
||||
|
||||
arg1 = (char *)jarg1;
|
||||
result = (int)switch_dtmftoi(arg1);
|
||||
jresult = result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_known_bitrate(unsigned char jarg1) {
|
||||
unsigned long jresult ;
|
||||
switch_payload_t arg1 ;
|
||||
|
@ -23501,6 +23536,30 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_variable_partner(void *
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_hold_music(void * jarg1) {
|
||||
char * jresult ;
|
||||
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||
char *result = 0 ;
|
||||
|
||||
arg1 = (switch_channel_t *)jarg1;
|
||||
result = (char *)switch_channel_get_hold_music(arg1);
|
||||
jresult = SWIG_csharp_string_callback((const char *)result);
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_hold_music_partner(void * jarg1) {
|
||||
char * jresult ;
|
||||
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||
char *result = 0 ;
|
||||
|
||||
arg1 = (switch_channel_t *)jarg1;
|
||||
result = (char *)switch_channel_get_hold_music_partner(arg1);
|
||||
jresult = SWIG_csharp_string_callback((const char *)result);
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_var_check(void * jarg1, char * jarg2, char * jarg3, char * jarg4, int jarg5) {
|
||||
int jresult ;
|
||||
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||
|
@ -23746,6 +23805,20 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_channel_test_cap(void * jarg1
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_channel_test_cap_partner(void * jarg1, int jarg2) {
|
||||
unsigned long jresult ;
|
||||
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||
switch_channel_cap_t arg2 ;
|
||||
uint32_t result;
|
||||
|
||||
arg1 = (switch_channel_t *)jarg1;
|
||||
arg2 = (switch_channel_cap_t)jarg2;
|
||||
result = (uint32_t)switch_channel_test_cap_partner(arg1,arg2);
|
||||
jresult = (unsigned long)result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_set_flag_partner(void * jarg1, int jarg2) {
|
||||
int jresult ;
|
||||
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||
|
@ -29077,6 +29150,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_deactivate_jitter_buffer(void * jar
|
|||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_pause_jitter_buffer(void * jarg1, int jarg2) {
|
||||
int jresult ;
|
||||
switch_rtp_t *arg1 = (switch_rtp_t *) 0 ;
|
||||
switch_bool_t arg2 ;
|
||||
switch_status_t result;
|
||||
|
||||
arg1 = (switch_rtp_t *)jarg1;
|
||||
arg2 = (switch_bool_t)jarg2;
|
||||
result = (switch_status_t)switch_rtp_pause_jitter_buffer(arg1,arg2);
|
||||
jresult = result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_flag(void * jarg1, unsigned long jarg2) {
|
||||
switch_rtp_t *arg1 = (switch_rtp_t *) 0 ;
|
||||
switch_rtp_flag_t arg2 ;
|
||||
|
|
|
@ -224,6 +224,11 @@ public class CoreSession : IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
public int insertFile(string file, string insert_file, int sample_point) {
|
||||
int ret = freeswitchPINVOKE.CoreSession_insertFile(swigCPtr, file, insert_file, sample_point);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int Answer() {
|
||||
int ret = freeswitchPINVOKE.CoreSession_Answer(swigCPtr);
|
||||
return ret;
|
||||
|
@ -1362,6 +1367,11 @@ public class freeswitch {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static switch_status_t switch_core_session_set_codec_slin(SWIGTYPE_p_switch_core_session session, switch_slin_data data) {
|
||||
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_set_codec_slin(SWIGTYPE_p_switch_core_session.getCPtr(session), switch_slin_data.getCPtr(data));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string switch_core_get_uuid() {
|
||||
string ret = freeswitchPINVOKE.switch_core_get_uuid();
|
||||
return ret;
|
||||
|
@ -2338,6 +2348,11 @@ public class freeswitch {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static int switch_cache_db_affected_rows(switch_cache_db_handle_t dbh) {
|
||||
int ret = freeswitchPINVOKE.switch_cache_db_affected_rows(switch_cache_db_handle_t.getCPtr(dbh));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void switch_cache_db_status(switch_stream_handle stream) {
|
||||
freeswitchPINVOKE.switch_cache_db_status(switch_stream_handle.getCPtr(stream));
|
||||
}
|
||||
|
@ -2732,6 +2747,16 @@ public class freeswitch {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static char switch_itodtmf(char i) {
|
||||
char ret = freeswitchPINVOKE.switch_itodtmf(i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int switch_dtmftoi(string s) {
|
||||
int ret = freeswitchPINVOKE.switch_dtmftoi(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static uint switch_known_bitrate(byte payload) {
|
||||
uint ret = freeswitchPINVOKE.switch_known_bitrate(payload);
|
||||
return ret;
|
||||
|
@ -3281,6 +3306,16 @@ public class freeswitch {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static string switch_channel_get_hold_music(SWIGTYPE_p_switch_channel channel) {
|
||||
string ret = freeswitchPINVOKE.switch_channel_get_hold_music(SWIGTYPE_p_switch_channel.getCPtr(channel));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string switch_channel_get_hold_music_partner(SWIGTYPE_p_switch_channel channel) {
|
||||
string ret = freeswitchPINVOKE.switch_channel_get_hold_music_partner(SWIGTYPE_p_switch_channel.getCPtr(channel));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static switch_status_t switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel channel, string varname, string val, string export_varname, switch_bool_t var_check) {
|
||||
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, val, export_varname, (int)var_check);
|
||||
return ret;
|
||||
|
@ -3369,6 +3404,11 @@ public class freeswitch {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static uint switch_channel_test_cap_partner(SWIGTYPE_p_switch_channel channel, switch_channel_cap_t cap) {
|
||||
uint ret = freeswitchPINVOKE.switch_channel_test_cap_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)cap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static switch_bool_t switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel channel, switch_channel_flag_t flag) {
|
||||
switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)flag);
|
||||
return ret;
|
||||
|
@ -4664,6 +4704,11 @@ public class freeswitch {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static switch_status_t switch_rtp_pause_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, switch_bool_t pause) {
|
||||
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_pause_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), (int)pause);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void switch_rtp_set_flag(SWIGTYPE_p_switch_rtp rtp_session, uint flags) {
|
||||
freeswitchPINVOKE.switch_rtp_set_flag(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), flags);
|
||||
}
|
||||
|
@ -5418,6 +5463,7 @@ public class freeswitch {
|
|||
public static readonly string SWITCH_PROXY_MEDIA_VARIABLE = freeswitchPINVOKE.SWITCH_PROXY_MEDIA_VARIABLE_get();
|
||||
public static readonly string SWITCH_ENDPOINT_DISPOSITION_VARIABLE = freeswitchPINVOKE.SWITCH_ENDPOINT_DISPOSITION_VARIABLE_get();
|
||||
public static readonly string SWITCH_HOLD_MUSIC_VARIABLE = freeswitchPINVOKE.SWITCH_HOLD_MUSIC_VARIABLE_get();
|
||||
public static readonly string SWITCH_TEMP_HOLD_MUSIC_VARIABLE = freeswitchPINVOKE.SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get();
|
||||
public static readonly string SWITCH_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_EXPORT_VARS_VARIABLE_get();
|
||||
public static readonly string SWITCH_BRIDGE_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get();
|
||||
public static readonly string SWITCH_R_SDP_VARIABLE = freeswitchPINVOKE.SWITCH_R_SDP_VARIABLE_get();
|
||||
|
@ -6010,6 +6056,9 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_HOLD_MUSIC_VARIABLE_get")]
|
||||
public static extern string SWITCH_HOLD_MUSIC_VARIABLE_get();
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get")]
|
||||
public static extern string SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get();
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_EXPORT_VARS_VARIABLE_get")]
|
||||
public static extern string SWITCH_EXPORT_VARS_VARIABLE_get();
|
||||
|
||||
|
@ -7474,6 +7523,9 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_dmachine")]
|
||||
public static extern IntPtr switch_core_session_get_dmachine(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_set_codec_slin")]
|
||||
public static extern int switch_core_session_set_codec_slin(HandleRef jarg1, HandleRef jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_uuid")]
|
||||
public static extern string switch_core_get_uuid();
|
||||
|
||||
|
@ -8218,6 +8270,9 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_execute_sql_callback")]
|
||||
public static extern int switch_cache_db_execute_sql_callback(HandleRef jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4, ref string jarg5);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_affected_rows")]
|
||||
public static extern int switch_cache_db_affected_rows(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_status")]
|
||||
public static extern void switch_cache_db_status(HandleRef jarg1);
|
||||
|
||||
|
@ -8590,6 +8645,12 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_switch_is_digit_string")]
|
||||
public static extern int switch_is_digit_string(string jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_itodtmf")]
|
||||
public static extern char switch_itodtmf(char jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_dtmftoi")]
|
||||
public static extern int switch_dtmftoi(string jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_known_bitrate")]
|
||||
public static extern uint switch_known_bitrate(byte jarg1);
|
||||
|
||||
|
@ -11149,6 +11210,36 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_delete_switch_api_interface")]
|
||||
public static extern void delete_switch_api_interface(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_session_set")]
|
||||
public static extern void switch_slin_data_session_set(HandleRef jarg1, HandleRef jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_session_get")]
|
||||
public static extern IntPtr switch_slin_data_session_get(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_write_frame_set")]
|
||||
public static extern void switch_slin_data_write_frame_set(HandleRef jarg1, HandleRef jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_write_frame_get")]
|
||||
public static extern IntPtr switch_slin_data_write_frame_get(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_codec_set")]
|
||||
public static extern void switch_slin_data_codec_set(HandleRef jarg1, HandleRef jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_codec_get")]
|
||||
public static extern IntPtr switch_slin_data_codec_get(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_frame_data_set")]
|
||||
public static extern void switch_slin_data_frame_data_set(HandleRef jarg1, string jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_frame_data_get")]
|
||||
public static extern string switch_slin_data_frame_data_get(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_new_switch_slin_data")]
|
||||
public static extern IntPtr new_switch_slin_data();
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_delete_switch_slin_data")]
|
||||
public static extern void delete_switch_slin_data(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_profile_created_set")]
|
||||
public static extern void switch_channel_timetable_profile_created_set(HandleRef jarg1, HandleRef jarg2);
|
||||
|
||||
|
@ -11311,6 +11402,12 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_variable_partner")]
|
||||
public static extern string switch_channel_get_variable_partner(HandleRef jarg1, string jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_hold_music")]
|
||||
public static extern string switch_channel_get_hold_music(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_hold_music_partner")]
|
||||
public static extern string switch_channel_get_hold_music_partner(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_export_variable_var_check")]
|
||||
public static extern int switch_channel_export_variable_var_check(HandleRef jarg1, string jarg2, string jarg3, string jarg4, int jarg5);
|
||||
|
||||
|
@ -11368,6 +11465,9 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_test_cap")]
|
||||
public static extern uint switch_channel_test_cap(HandleRef jarg1, int jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_test_cap_partner")]
|
||||
public static extern uint switch_channel_test_cap_partner(HandleRef jarg1, int jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_flag_partner")]
|
||||
public static extern int switch_channel_set_flag_partner(HandleRef jarg1, int jarg2);
|
||||
|
||||
|
@ -12481,6 +12581,9 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_deactivate_jitter_buffer")]
|
||||
public static extern int switch_rtp_deactivate_jitter_buffer(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_pause_jitter_buffer")]
|
||||
public static extern int switch_rtp_pause_jitter_buffer(HandleRef jarg1, int jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_flag")]
|
||||
public static extern void switch_rtp_set_flag(HandleRef jarg1, uint jarg2);
|
||||
|
||||
|
@ -13672,6 +13775,9 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_CoreSession_voice_name_get")]
|
||||
public static extern string CoreSession_voice_name_get(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_CoreSession_insertFile")]
|
||||
public static extern int CoreSession_insertFile(HandleRef jarg1, string jarg2, string jarg3, int jarg4);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_CoreSession_Answer")]
|
||||
public static extern int CoreSession_Answer(HandleRef jarg1);
|
||||
|
||||
|
@ -21515,6 +21621,8 @@ public enum switch_channel_cap_t {
|
|||
CC_MEDIA_ACK = 1,
|
||||
CC_BYPASS_MEDIA,
|
||||
CC_PROXY_MEDIA,
|
||||
CC_JITTERBUFFER,
|
||||
CC_FS_RTP,
|
||||
CC_FLAG_MAX
|
||||
}
|
||||
|
||||
|
@ -29531,6 +29639,98 @@ public enum switch_signal_t {
|
|||
|
||||
namespace FreeSWITCH.Native {
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class switch_slin_data : IDisposable {
|
||||
private HandleRef swigCPtr;
|
||||
protected bool swigCMemOwn;
|
||||
|
||||
internal switch_slin_data(IntPtr cPtr, bool cMemoryOwn) {
|
||||
swigCMemOwn = cMemoryOwn;
|
||||
swigCPtr = new HandleRef(this, cPtr);
|
||||
}
|
||||
|
||||
internal static HandleRef getCPtr(switch_slin_data obj) {
|
||||
return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
|
||||
}
|
||||
|
||||
~switch_slin_data() {
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public virtual void Dispose() {
|
||||
lock(this) {
|
||||
if (swigCPtr.Handle != IntPtr.Zero) {
|
||||
if (swigCMemOwn) {
|
||||
swigCMemOwn = false;
|
||||
freeswitchPINVOKE.delete_switch_slin_data(swigCPtr);
|
||||
}
|
||||
swigCPtr = new HandleRef(null, IntPtr.Zero);
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_switch_core_session session {
|
||||
set {
|
||||
freeswitchPINVOKE.switch_slin_data_session_set(swigCPtr, SWIGTYPE_p_switch_core_session.getCPtr(value));
|
||||
}
|
||||
get {
|
||||
IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_session_get(swigCPtr);
|
||||
SWIGTYPE_p_switch_core_session ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_core_session(cPtr, false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public switch_frame write_frame {
|
||||
set {
|
||||
freeswitchPINVOKE.switch_slin_data_write_frame_set(swigCPtr, switch_frame.getCPtr(value));
|
||||
}
|
||||
get {
|
||||
IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_write_frame_get(swigCPtr);
|
||||
switch_frame ret = (cPtr == IntPtr.Zero) ? null : new switch_frame(cPtr, false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public switch_codec codec {
|
||||
set {
|
||||
freeswitchPINVOKE.switch_slin_data_codec_set(swigCPtr, switch_codec.getCPtr(value));
|
||||
}
|
||||
get {
|
||||
IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_codec_get(swigCPtr);
|
||||
switch_codec ret = (cPtr == IntPtr.Zero) ? null : new switch_codec(cPtr, false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public string frame_data {
|
||||
set {
|
||||
freeswitchPINVOKE.switch_slin_data_frame_data_set(swigCPtr, value);
|
||||
}
|
||||
get {
|
||||
string ret = freeswitchPINVOKE.switch_slin_data_frame_data_get(swigCPtr);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public switch_slin_data() : this(freeswitchPINVOKE.new_switch_slin_data(), true) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/* ----------------------------------------------------------------------------
|
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 2.0.1
|
||||
*
|
||||
* Do not make changes to this file unless you know what you are doing--modify
|
||||
* the SWIG interface file instead.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
namespace FreeSWITCH.Native {
|
||||
|
||||
[System.Flags] public enum switch_speech_flag_enum_t {
|
||||
SWITCH_SPEECH_FLAG_NONE = 0,
|
||||
SWITCH_SPEECH_FLAG_HASTEXT = (1 << 0),
|
||||
|
|
|
@ -2732,6 +2732,16 @@ public class freeswitch {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static char switch_itodtmf(char i) {
|
||||
char ret = freeswitchPINVOKE.switch_itodtmf(i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int switch_dtmftoi(string s) {
|
||||
int ret = freeswitchPINVOKE.switch_dtmftoi(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static uint switch_known_bitrate(byte payload) {
|
||||
uint ret = freeswitchPINVOKE.switch_known_bitrate(payload);
|
||||
return ret;
|
||||
|
@ -3281,6 +3291,16 @@ public class freeswitch {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static string switch_channel_get_hold_music(SWIGTYPE_p_switch_channel channel) {
|
||||
string ret = freeswitchPINVOKE.switch_channel_get_hold_music(SWIGTYPE_p_switch_channel.getCPtr(channel));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string switch_channel_get_hold_music_partner(SWIGTYPE_p_switch_channel channel) {
|
||||
string ret = freeswitchPINVOKE.switch_channel_get_hold_music_partner(SWIGTYPE_p_switch_channel.getCPtr(channel));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static switch_status_t switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel channel, string varname, string val, string export_varname, switch_bool_t var_check) {
|
||||
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, val, export_varname, (int)var_check);
|
||||
return ret;
|
||||
|
@ -3369,6 +3389,11 @@ public class freeswitch {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static uint switch_channel_test_cap_partner(SWIGTYPE_p_switch_channel channel, switch_channel_cap_t cap) {
|
||||
uint ret = freeswitchPINVOKE.switch_channel_test_cap_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)cap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static switch_bool_t switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel channel, switch_channel_flag_t flag) {
|
||||
switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)flag);
|
||||
return ret;
|
||||
|
@ -4664,6 +4689,11 @@ public class freeswitch {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static switch_status_t switch_rtp_pause_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, switch_bool_t pause) {
|
||||
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_pause_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), (int)pause);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void switch_rtp_set_flag(SWIGTYPE_p_switch_rtp rtp_session, uint flags) {
|
||||
freeswitchPINVOKE.switch_rtp_set_flag(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), flags);
|
||||
}
|
||||
|
@ -5418,6 +5448,7 @@ public class freeswitch {
|
|||
public static readonly string SWITCH_PROXY_MEDIA_VARIABLE = freeswitchPINVOKE.SWITCH_PROXY_MEDIA_VARIABLE_get();
|
||||
public static readonly string SWITCH_ENDPOINT_DISPOSITION_VARIABLE = freeswitchPINVOKE.SWITCH_ENDPOINT_DISPOSITION_VARIABLE_get();
|
||||
public static readonly string SWITCH_HOLD_MUSIC_VARIABLE = freeswitchPINVOKE.SWITCH_HOLD_MUSIC_VARIABLE_get();
|
||||
public static readonly string SWITCH_TEMP_HOLD_MUSIC_VARIABLE = freeswitchPINVOKE.SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get();
|
||||
public static readonly string SWITCH_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_EXPORT_VARS_VARIABLE_get();
|
||||
public static readonly string SWITCH_BRIDGE_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get();
|
||||
public static readonly string SWITCH_R_SDP_VARIABLE = freeswitchPINVOKE.SWITCH_R_SDP_VARIABLE_get();
|
||||
|
@ -6006,6 +6037,9 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_HOLD_MUSIC_VARIABLE_get")]
|
||||
public static extern string SWITCH_HOLD_MUSIC_VARIABLE_get();
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get")]
|
||||
public static extern string SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get();
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_EXPORT_VARS_VARIABLE_get")]
|
||||
public static extern string SWITCH_EXPORT_VARS_VARIABLE_get();
|
||||
|
||||
|
@ -8589,6 +8623,12 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_switch_is_digit_string")]
|
||||
public static extern int switch_is_digit_string(string jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_itodtmf")]
|
||||
public static extern char switch_itodtmf(char jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_dtmftoi")]
|
||||
public static extern int switch_dtmftoi(string jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_known_bitrate")]
|
||||
public static extern uint switch_known_bitrate(byte jarg1);
|
||||
|
||||
|
@ -11310,6 +11350,12 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_variable_partner")]
|
||||
public static extern string switch_channel_get_variable_partner(HandleRef jarg1, string jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_hold_music")]
|
||||
public static extern string switch_channel_get_hold_music(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_hold_music_partner")]
|
||||
public static extern string switch_channel_get_hold_music_partner(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_export_variable_var_check")]
|
||||
public static extern int switch_channel_export_variable_var_check(HandleRef jarg1, string jarg2, string jarg3, string jarg4, int jarg5);
|
||||
|
||||
|
@ -11367,6 +11413,9 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_test_cap")]
|
||||
public static extern uint switch_channel_test_cap(HandleRef jarg1, int jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_test_cap_partner")]
|
||||
public static extern uint switch_channel_test_cap_partner(HandleRef jarg1, int jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_flag_partner")]
|
||||
public static extern int switch_channel_set_flag_partner(HandleRef jarg1, int jarg2);
|
||||
|
||||
|
@ -12480,6 +12529,9 @@ class freeswitchPINVOKE {
|
|||
[DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_deactivate_jitter_buffer")]
|
||||
public static extern int switch_rtp_deactivate_jitter_buffer(HandleRef jarg1);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_pause_jitter_buffer")]
|
||||
public static extern int switch_rtp_pause_jitter_buffer(HandleRef jarg1, int jarg2);
|
||||
|
||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_flag")]
|
||||
public static extern void switch_rtp_set_flag(HandleRef jarg1, uint jarg2);
|
||||
|
||||
|
@ -21477,6 +21529,8 @@ public enum switch_channel_cap_t {
|
|||
CC_MEDIA_ACK = 1,
|
||||
CC_BYPASS_MEDIA,
|
||||
CC_PROXY_MEDIA,
|
||||
CC_JITTERBUFFER,
|
||||
CC_FS_RTP,
|
||||
CC_FLAG_MAX
|
||||
}
|
||||
|
||||
|
|
|
@ -744,6 +744,7 @@ abyss_bool handler_hook(TSession * r)
|
|||
|
||||
if (dateValue) {
|
||||
ResponseAddField(r, "Date", dateValue);
|
||||
free(dateValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,39 @@ SWITCH_DECLARE(void) switch_core_session_soft_unlock(switch_core_session_t *sess
|
|||
session->soft_lock = 0;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_set_codec_slin(switch_core_session_t *session, switch_slin_data_t *data)
|
||||
|
||||
{
|
||||
switch_codec_implementation_t read_impl = { 0 };
|
||||
int interval;
|
||||
|
||||
switch_core_session_get_read_impl(session, &read_impl);
|
||||
interval = read_impl.microseconds_per_packet / 1000;
|
||||
data->session = session;
|
||||
|
||||
if (switch_core_codec_init(&data->codec,
|
||||
"L16",
|
||||
NULL,
|
||||
read_impl.actual_samples_per_second,
|
||||
interval,
|
||||
1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
|
||||
SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %dms\n", read_impl.actual_samples_per_second, interval);
|
||||
|
||||
memset(&data->write_frame, 0, sizeof(data->write_frame));
|
||||
|
||||
data->write_frame.codec = &data->codec;
|
||||
data->write_frame.data = data->frame_data;
|
||||
data->write_frame.buflen = sizeof(data->frame_data);
|
||||
data->write_frame.datalen = 0;
|
||||
switch_core_session_set_read_codec(session, &data->codec);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SWITCH_DEBUG_RWLOCKS
|
||||
SWITCH_DECLARE(switch_core_session_t *) switch_core_session_perform_locate(const char *uuid_str, const char *file, const char *func, int line)
|
||||
#else
|
||||
|
|
|
@ -57,6 +57,7 @@ struct switch_odbc_handle {
|
|||
char odbc_driver[256];
|
||||
BOOL is_firebird;
|
||||
int affected_rows;
|
||||
int num_retries;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -90,6 +91,7 @@ SWITCH_DECLARE(switch_odbc_handle_t *) switch_odbc_handle_new(const char *dsn, c
|
|||
new_handle->env = SQL_NULL_HANDLE;
|
||||
new_handle->state = SWITCH_ODBC_STATE_INIT;
|
||||
new_handle->affected_rows = 0;
|
||||
new_handle->num_retries = DEFAULT_ODBC_RETRIES;
|
||||
|
||||
return new_handle;
|
||||
|
||||
|
@ -104,6 +106,15 @@ SWITCH_DECLARE(switch_odbc_handle_t *) switch_odbc_handle_new(const char *dsn, c
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_odbc_set_num_retries(switch_odbc_handle_t *handle, int num_retries)
|
||||
{
|
||||
#ifdef SWITCH_HAVE_ODBC
|
||||
if (handle) {
|
||||
handle->num_retries = num_retries;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_handle_t *handle)
|
||||
{
|
||||
#ifdef SWITCH_HAVE_ODBC
|
||||
|
@ -133,6 +144,53 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_h
|
|||
|
||||
|
||||
#ifdef SWITCH_HAVE_ODBC
|
||||
static switch_odbc_status_t init_odbc_handles(switch_odbc_handle_t *handle, switch_bool_t do_reinit)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!handle) {
|
||||
return SWITCH_ODBC_FAIL;
|
||||
}
|
||||
|
||||
/* if handle is already initialized, and we're supposed to reinit - free old handle first */
|
||||
if (do_reinit == SWITCH_TRUE && handle->env != SQL_NULL_HANDLE) {
|
||||
SQLFreeHandle(SQL_HANDLE_DBC, handle->con);
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||
handle->env = SQL_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (handle->env == SQL_NULL_HANDLE) {
|
||||
result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handle->env);
|
||||
|
||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHandle\n");
|
||||
handle->env = SQL_NULL_HANDLE; /* Reset handle value, just in case */
|
||||
return SWITCH_ODBC_FAIL;
|
||||
}
|
||||
|
||||
result = SQLSetEnvAttr(handle->env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
|
||||
|
||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error SetEnv\n");
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||
handle->env = SQL_NULL_HANDLE; /* Reset handle value after it's freed */
|
||||
return SWITCH_ODBC_FAIL;
|
||||
}
|
||||
|
||||
result = SQLAllocHandle(SQL_HANDLE_DBC, handle->env, &handle->con);
|
||||
|
||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHDB %d\n", result);
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||
handle->env = SQL_NULL_HANDLE; /* Reset handle value after it's freed */
|
||||
return SWITCH_ODBC_FAIL;
|
||||
}
|
||||
SQLSetConnectAttr(handle->con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *) 10, 0);
|
||||
}
|
||||
|
||||
return SWITCH_ODBC_SUCCESS;
|
||||
}
|
||||
|
||||
static int db_is_up(switch_odbc_handle_t *handle)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -143,12 +201,18 @@ static int db_is_up(switch_odbc_handle_t *handle)
|
|||
switch_odbc_status_t recon = 0;
|
||||
char *err_str = NULL;
|
||||
SQLCHAR sql[255] = "";
|
||||
int max_tries = 120;
|
||||
int max_tries = DEFAULT_ODBC_RETRIES;
|
||||
int code = 0;
|
||||
SQLRETURN rc;
|
||||
SQLSMALLINT nresultcols;
|
||||
|
||||
|
||||
if (handle) {
|
||||
max_tries = handle->num_retries;
|
||||
if (max_tries < 1)
|
||||
max_tries = DEFAULT_ODBC_RETRIES;
|
||||
}
|
||||
|
||||
top:
|
||||
|
||||
if (!handle) {
|
||||
|
@ -199,6 +263,13 @@ static int db_is_up(switch_odbc_handle_t *handle)
|
|||
|
||||
error:
|
||||
err_str = switch_odbc_handle_get_error(handle, stmt);
|
||||
|
||||
/* Make sure to free the handle before we try to reconnect */
|
||||
if (stmt) {
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||
stmt = NULL;
|
||||
}
|
||||
|
||||
recon = switch_odbc_handle_connect(handle);
|
||||
|
||||
max_tries--;
|
||||
|
@ -228,11 +299,6 @@ static int db_is_up(switch_odbc_handle_t *handle)
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (stmt) {
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||
stmt = NULL;
|
||||
}
|
||||
|
||||
switch_safe_free(err_str);
|
||||
switch_yield(1000000);
|
||||
goto top;
|
||||
|
@ -274,31 +340,8 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_hand
|
|||
SQLSMALLINT valueLength = 0;
|
||||
int i = 0;
|
||||
|
||||
if (handle->env == SQL_NULL_HANDLE) {
|
||||
result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handle->env);
|
||||
init_odbc_handles(handle, SWITCH_FALSE); /* Init ODBC handles, if they are already initialized, don't do it again */
|
||||
|
||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHandle\n");
|
||||
return SWITCH_ODBC_FAIL;
|
||||
}
|
||||
|
||||
result = SQLSetEnvAttr(handle->env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
|
||||
|
||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error SetEnv\n");
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||
return SWITCH_ODBC_FAIL;
|
||||
}
|
||||
|
||||
result = SQLAllocHandle(SQL_HANDLE_DBC, handle->env, &handle->con);
|
||||
|
||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHDB %d\n", result);
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||
return SWITCH_ODBC_FAIL;
|
||||
}
|
||||
SQLSetConnectAttr(handle->con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *) 10, 0);
|
||||
}
|
||||
if (handle->state == SWITCH_ODBC_STATE_CONNECTED) {
|
||||
switch_odbc_handle_disconnect(handle);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Re-connecting %s\n", handle->dsn);
|
||||
|
@ -325,7 +368,9 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_hand
|
|||
SQLGetDiagRec(SQL_HANDLE_DBC, handle->con, 1, stat, &err, msg, 100, &mlen);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error SQLConnect=%d errno=%d %s\n", result, (int) err, msg);
|
||||
}
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||
|
||||
/* Deallocate handles again, more chanses to succeed when reconnecting */
|
||||
init_odbc_handles(handle, SWITCH_TRUE); /* Reinit ODBC handles */
|
||||
return SWITCH_ODBC_FAIL;
|
||||
}
|
||||
|
||||
|
@ -554,6 +599,7 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c
|
|||
}
|
||||
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||
stmt = NULL; /* Make sure we don't try to free this handle again */
|
||||
|
||||
if (!err_cnt) {
|
||||
return SWITCH_ODBC_SUCCESS;
|
||||
|
@ -593,8 +639,10 @@ SWITCH_DECLARE(void) switch_odbc_handle_destroy(switch_odbc_handle_t **handlep)
|
|||
if (handle) {
|
||||
switch_odbc_handle_disconnect(handle);
|
||||
|
||||
SQLFreeHandle(SQL_HANDLE_DBC, handle->con);
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||
if (handle->env != SQL_NULL_HANDLE) {
|
||||
SQLFreeHandle(SQL_HANDLE_DBC, handle->con);
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||
}
|
||||
switch_safe_free(handle->dsn);
|
||||
switch_safe_free(handle->username);
|
||||
switch_safe_free(handle->password);
|
||||
|
|
|
@ -126,6 +126,7 @@ struct switch_rtp_rfc2833_data {
|
|||
uint16_t in_digit_seq;
|
||||
uint32_t in_digit_ts;
|
||||
uint32_t in_digit_sanity;
|
||||
uint32_t in_interleaved;
|
||||
uint32_t timestamp_dtmf;
|
||||
uint16_t last_duration;
|
||||
uint32_t flip;
|
||||
|
@ -133,6 +134,7 @@ struct switch_rtp_rfc2833_data {
|
|||
char last_digit;
|
||||
switch_queue_t *dtmf_inqueue;
|
||||
switch_mutex_t *dtmf_mutex;
|
||||
uint8_t in_digit_queued;
|
||||
};
|
||||
|
||||
struct switch_rtp {
|
||||
|
@ -2479,7 +2481,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
}
|
||||
}
|
||||
|
||||
if ((!(io_flags & SWITCH_IO_FLAG_NOBLOCK)) && (rtp_session->dtmf_data.out_digit_dur == 0 || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO))) {
|
||||
if ((!(io_flags & SWITCH_IO_FLAG_NOBLOCK)) &&
|
||||
(rtp_session->dtmf_data.out_digit_dur == 0 || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO))) {
|
||||
return_cng_frame();
|
||||
}
|
||||
}
|
||||
|
@ -2819,7 +2822,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
}
|
||||
#ifdef DEBUG_2833
|
||||
if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) {
|
||||
printf("sanity %d\n", rtp_session->dtmf_data.in_digit_sanity);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2869,7 +2872,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
}
|
||||
}
|
||||
#ifdef DEBUG_2833
|
||||
printf("packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned)
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned)
|
||||
packet[1], (unsigned) packet[2], (unsigned) packet[3]);
|
||||
#endif
|
||||
|
||||
|
@ -2878,16 +2881,28 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
rtp_session->dtmf_data.in_digit_seq = in_digit_seq;
|
||||
#ifdef DEBUG_2833
|
||||
|
||||
printf("read: %c %u %u %u %u %d %d %s\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n",
|
||||
key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq,
|
||||
ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : "");
|
||||
#endif
|
||||
|
||||
if (!rtp_session->dtmf_data.in_digit_queued && (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) &&
|
||||
rtp_session->dtmf_data.in_digit_ts) {
|
||||
switch_dtmf_t dtmf = { key, switch_core_min_dtmf_duration(0) };
|
||||
#ifdef DEBUG_2833
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Early Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8);
|
||||
#endif
|
||||
switch_rtp_queue_rfc2833_in(rtp_session, &dtmf);
|
||||
rtp_session->dtmf_data.in_digit_queued = 1;
|
||||
}
|
||||
|
||||
/* only set sanity if we do NOT ignore the packet */
|
||||
if (rtp_session->dtmf_data.in_digit_ts) {
|
||||
rtp_session->dtmf_data.in_digit_sanity = 2000;
|
||||
}
|
||||
|
||||
if (rtp_session->dtmf_data.last_duration > duration && rtp_session->dtmf_data.last_duration > 0xFC17 && ts == rtp_session->dtmf_data.in_digit_ts) {
|
||||
if (rtp_session->dtmf_data.last_duration > duration &&
|
||||
rtp_session->dtmf_data.last_duration > 0xFC17 && ts == rtp_session->dtmf_data.in_digit_ts) {
|
||||
rtp_session->dtmf_data.flip++;
|
||||
}
|
||||
|
||||
|
@ -2902,18 +2917,26 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
dtmf.duration += rtp_session->dtmf_data.flip * 0xFFFF;
|
||||
rtp_session->dtmf_data.flip = 0;
|
||||
#ifdef DEBUG_2833
|
||||
printf("you're welcome!\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "you're welcome!\n");
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG_2833
|
||||
printf("done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n",
|
||||
dtmf.digit, ts, rtp_session->dtmf_data.in_digit_ts, duration, dtmf.duration);
|
||||
#endif
|
||||
switch_rtp_queue_rfc2833_in(rtp_session, &dtmf);
|
||||
|
||||
if (!(rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && !rtp_session->dtmf_data.in_digit_queued) {
|
||||
#ifdef DEBUG_2833
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8);
|
||||
#endif
|
||||
switch_rtp_queue_rfc2833_in(rtp_session, &dtmf);
|
||||
}
|
||||
|
||||
rtp_session->dtmf_data.last_digit = rtp_session->dtmf_data.first_digit;
|
||||
|
||||
rtp_session->dtmf_data.in_digit_ts = 0;
|
||||
rtp_session->dtmf_data.in_digit_sanity = 0;
|
||||
rtp_session->dtmf_data.in_digit_queued = 0;
|
||||
do_cng = 1;
|
||||
} else {
|
||||
if (!switch_rtp_ready(rtp_session)) {
|
||||
|
@ -2932,7 +2955,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
rtp_session->dtmf_data.last_duration = duration;
|
||||
} else {
|
||||
#ifdef DEBUG_2833
|
||||
printf("drop: %c %u %u %u %u %d %d\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "drop: %c %u %u %u %u %d %d\n",
|
||||
key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end);
|
||||
#endif
|
||||
switch_cond_next();
|
||||
|
@ -2941,10 +2964,27 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
}
|
||||
|
||||
if (rtp_session->dtmf_data.in_digit_ts) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (bytes && rtp_session->dtmf_data.in_digit_ts) {
|
||||
if (!switch_rtp_ready(rtp_session)) {
|
||||
goto end;
|
||||
}
|
||||
return_cng_frame();
|
||||
|
||||
if (!rtp_session->dtmf_data.in_interleaved && rtp_session->recv_msg.header.pt != rtp_session->recv_te) {
|
||||
/* Drat, they are sending audio still as well as DTMF ok fine..... *sigh* */
|
||||
rtp_session->dtmf_data.in_interleaved = 1;
|
||||
}
|
||||
|
||||
if (rtp_session->dtmf_data.in_interleaved || (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION)) {
|
||||
if (rtp_session->recv_msg.header.pt == rtp_session->recv_te) {
|
||||
goto recvfrom;
|
||||
}
|
||||
} else {
|
||||
return_cng_frame();
|
||||
}
|
||||
}
|
||||
|
||||
timer_check:
|
||||
|
@ -3254,7 +3294,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
|
|||
}
|
||||
|
||||
frame->datalen = bytes;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3540,7 +3579,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
|
|||
#ifdef RTP_DEBUG_WRITE_DELTA
|
||||
{
|
||||
int delta = (int) (now - rtp_session->send_time) / 1000;
|
||||
printf("WRITE %d delta %d\n", (int) bytes, delta);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WRITE %d delta %d\n", (int) bytes, delta);
|
||||
}
|
||||
#endif
|
||||
rtp_session->send_time = now;
|
||||
|
|
Loading…
Reference in New Issue