Merge branch 'master' into moy.r2glare

This commit is contained in:
Moises Silva 2011-01-12 13:37:05 -05:00
commit 3594419622
39 changed files with 2780 additions and 143 deletions

View File

@ -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

View File

@ -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

View File

@ -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 -->

1
libs/.gitignore vendored
View File

@ -1001,6 +1001,7 @@
/unimrcp/build/acmacros/lt~obsolete.m4
/*.tar.gz
/celt-0.7.1/
/celt-0.10.0/
/flite-1.3.99/
/freeradius-client-1.1.6/
/iksemel/test/tst-dom

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
autoheader
libtoolize --force --copy
aclocal

View File

@ -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);

View File

@ -634,6 +634,10 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span)
ftdm_mutex_lock(span->mutex);
/* stop the signaling */
/* This is a forced stopped */
ftdm_clear_flag(span, FTDM_SPAN_NON_STOPPABLE);
ftdm_span_stop(span);
/* destroy the channels */
@ -739,6 +743,11 @@ FT_DECLARE(ftdm_status_t) ftdm_span_stop(ftdm_span_t *span)
ftdm_status_t status = FTDM_SUCCESS;
ftdm_mutex_lock(span->mutex);
if (ftdm_test_flag(span, FTDM_SPAN_NON_STOPPABLE)) {
status = FTDM_NOTIMPL;
goto done;
}
if (!ftdm_test_flag(span, FTDM_SPAN_STARTED)) {
status = FTDM_EINVAL;
@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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");

View File

@ -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 */

View File

@ -9,8 +9,7 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <winsock.h>
#include <errno.h>
#include <winsock2.h>
#include "xmlrpc_config.h"
#include "xmlrpc-c/util_int.h"
@ -249,6 +248,7 @@ struct socketWin {
SOCKET winsock;
bool userSuppliedWinsock;
/* 'socket' was supplied by the user; it belongs to him */
HANDLE interruptEvent;
};
static
@ -322,6 +322,8 @@ channelDestroy(TChannel * const channelP) {
if (!socketWinP->userSuppliedWinsock)
closesocket(socketWinP->winsock);
CloseHandle(socketWinP->interruptEvent);
free(socketWinP);
}
@ -430,9 +432,9 @@ channelWait(TChannel * const channelP,
timedOut = TRUE;
break;
case -1: /* socket error */
if (errno != EINTR)
if (WSAGetLastError() != WSAEINTR)
failed = TRUE;
break;
break;
default:
if (FD_ISSET(socketWinP->winsock, &rfds))
readRdy = TRUE;
@ -460,7 +462,9 @@ channelInterrupt(TChannel * const channelP) {
now or in the future.
Actually, this is just a no-op because we don't yet know how to
accomplish that.
accomplish that. (But we could probably do it the same way
chanSwitchInterrupt() works -- no one has needed it enough yet to do that
work).
-----------------------------------------------------------------------------*/
}
@ -484,7 +488,7 @@ ChannelWinGetPeerName(TChannel * const channelP,
if (rc != 0) {
int const lastError = WSAGetLastError();
xmlrpc_asprintf(errorP, "getpeername() failed. WSAERROR = %d (%s)",
xmlrpc_asprintf(errorP, "getpeername() failed. WSA error = %d (%s)",
lastError, getWSAError(lastError));
} else {
if (addrlen != sizeof(sockAddr))
@ -581,7 +585,8 @@ makeChannelFromWinsock(SOCKET const winsock,
socketWinP->winsock = winsock;
socketWinP->userSuppliedWinsock = TRUE;
socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
ChannelCreate(&channelVtbl, socketWinP, &channelP);
if (channelP == NULL)
@ -591,8 +596,10 @@ makeChannelFromWinsock(SOCKET const winsock,
*channelPP = channelP;
*errorP = NULL;
}
if (*errorP)
if (*errorP) {
CloseHandle(socketWinP->interruptEvent);
free(socketWinP);
}
}
}
@ -632,7 +639,7 @@ ChannelWinCreateWinsock(SOCKET const fd,
socklen_t peerAddrLen;
int rc;
peerAddrLen = sizeof(peerAddrLen);
peerAddrLen = sizeof(peerAddr);
rc = getpeername(fd, &peerAddr, &peerAddrLen);
@ -676,6 +683,8 @@ chanSwitchDestroy(TChanSwitch * const chanSwitchP) {
if (!socketWinP->userSuppliedWinsock)
closesocket(socketWinP->winsock);
CloseHandle(socketWinP->interruptEvent);
free(socketWinP);
}
@ -711,6 +720,49 @@ chanSwitchListen(TChanSwitch * const chanSwitchP,
static void
createChannelForAccept(int const acceptedWinsock,
struct sockaddr const peerAddr,
TChannel ** const channelPP,
void ** const channelInfoPP,
const char ** const errorP) {
struct abyss_win_chaninfo * channelInfoP;
makeChannelInfo(&channelInfoP, peerAddr, sizeof(peerAddr), errorP);
if (!*errorP) {
struct socketWin * acceptedSocketP;
MALLOCVAR(acceptedSocketP);
if (!acceptedSocketP)
xmlrpc_asprintf(errorP, "Unable to allocate memory");
else {
TChannel * channelP;
acceptedSocketP->winsock = acceptedWinsock;
acceptedSocketP->userSuppliedWinsock = FALSE;
acceptedSocketP->interruptEvent =
CreateEvent(NULL, FALSE, FALSE, NULL);
ChannelCreate(&channelVtbl, acceptedSocketP, &channelP);
if (!channelP)
xmlrpc_asprintf(errorP,
"Failed to create TChannel object.");
else {
*errorP = NULL;
*channelPP = channelP;
*channelInfoPP = channelInfoP;
}
if (*errorP) {
CloseHandle(acceptedSocketP->interruptEvent);
free(acceptedSocketP);
}
}
}
}
static SwitchAcceptImpl chanSwitchAccept;
static void
@ -728,7 +780,7 @@ chanSwitchAccept(TChanSwitch * const chanSwitchP,
*channelPP == NULL.
-----------------------------------------------------------------------------*/
struct socketWin * const listenSocketP = chanSwitchP->implP;
HANDLE acceptEvent = WSACreateEvent();
bool interrupted;
TChannel * channelP;
@ -736,46 +788,44 @@ chanSwitchAccept(TChanSwitch * const chanSwitchP,
channelP = NULL; /* No connection yet */
*errorP = NULL; /* No error yet */
WSAEventSelect(listenSocketP->winsock, acceptEvent,
FD_ACCEPT | FD_CLOSE | FD_READ);
while (!channelP && !*errorP && !interrupted) {
HANDLE interrupts[2] = {acceptEvent, listenSocketP->interruptEvent};
int rc;
struct sockaddr peerAddr;
socklen_t size = sizeof(peerAddr);
int rc;
rc = WaitForMultipleObjects(2, interrupts, FALSE, INFINITE);
if (WAIT_OBJECT_0 + 1 == rc) {
interrupted = TRUE;
continue;
};
rc = accept(listenSocketP->winsock, &peerAddr, &size);
if (rc >= 0) {
int const acceptedWinsock = rc;
struct socketWin * acceptedSocketP;
MALLOCVAR(acceptedSocketP);
createChannelForAccept(acceptedWinsock, peerAddr,
&channelP, channelInfoPP, errorP);
if (!acceptedSocketP)
xmlrpc_asprintf(errorP, "Unable to allocate memory");
else {
acceptedSocketP->winsock = acceptedWinsock;
acceptedSocketP->userSuppliedWinsock = FALSE;
*channelInfoPP = NULL;
ChannelCreate(&channelVtbl, acceptedSocketP, &channelP);
if (!channelP)
xmlrpc_asprintf(errorP,
"Failed to create TChannel object.");
else
*errorP = NULL;
if (*errorP)
free(acceptedSocketP);
}
if (*errorP)
closesocket(acceptedWinsock);
} else if (errno == EINTR)
interrupted = TRUE;
else
xmlrpc_asprintf(errorP, "accept() failed, errno = %d (%s)",
errno, strerror(errno));
} else {
int const lastError = WSAGetLastError();
if (lastError == WSAEINTR)
interrupted = TRUE;
else
xmlrpc_asprintf(errorP,
"accept() failed, WSA error = %d (%s)",
lastError, getWSAError(lastError));
}
}
*channelPP = channelP;
CloseHandle(acceptEvent);
}
@ -787,15 +837,10 @@ chanSwitchInterrupt(TChanSwitch * const chanSwitchP) {
/*----------------------------------------------------------------------------
Interrupt any waiting that a thread might be doing in chanSwitchAccept()
now or in the future.
Actually, this is just a no-op because we don't yet know how to
accomplish that.
-----------------------------------------------------------------------------*/
struct socketWin * const socketWinP = chanSwitchP->implP;
if (!socketWinP->userSuppliedWinsock)
closesocket(socketWinP->winsock);
struct socketWin * const listenSocketP = chanSwitchP->implP;
SetEvent(listenSocketP->interruptEvent);
}
@ -889,6 +934,7 @@ ChanSwitchWinCreate(uint16_t const portNumber,
} else {
socketWinP->winsock = winsock;
socketWinP->userSuppliedWinsock = FALSE;
socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
setSocketOptions(socketWinP->winsock, errorP);
if (!*errorP) {
@ -899,8 +945,10 @@ ChanSwitchWinCreate(uint16_t const portNumber,
chanSwitchPP);
}
if (*errorP)
if (*errorP) {
CloseHandle(socketWinP->interruptEvent);
closesocket(winsock);
}
}
if (*errorP)
free(socketWinP);
@ -929,7 +977,8 @@ ChanSwitchWinCreateWinsock(SOCKET const winsock,
socketWinP->winsock = winsock;
socketWinP->userSuppliedWinsock = TRUE;
socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
ChanSwitchCreate(&chanSwitchVtbl, socketWinP, &chanSwitchP);
if (chanSwitchP == NULL)
@ -939,8 +988,10 @@ ChanSwitchWinCreateWinsock(SOCKET const winsock,
*chanSwitchPP = chanSwitchP;
*errorP = NULL;
}
if (*errorP)
if (*errorP) {
CloseHandle(socketWinP->interruptEvent);
free(socketWinP);
}
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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 = { \

View File

@ -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 {

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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
*/

View File

@ -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... */
}

View File

@ -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

View File

@ -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(&params, 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(&params);
}
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(&params, 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(&params);
}
} 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(&params);
} 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(&params, 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(&params);
}
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);

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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)

View File

@ -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];

View File

@ -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 ;

View File

@ -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 ;

View File

@ -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),

View File

@ -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
}

View File

@ -744,6 +744,7 @@ abyss_bool handler_hook(TSession * r)
if (dateValue) {
ResponseAddField(r, "Date", dateValue);
free(dateValue);
}
}

View File

@ -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

View File

@ -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);

View File

@ -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;