merge fixes

This commit is contained in:
Ken Rice 2012-11-21 06:33:40 +00:00
commit 71184fc104
76 changed files with 1429 additions and 483 deletions

View File

@ -1,3 +1,3 @@
en-us-callie 1.0.18
en-us-callie 1.0.22
ru-RU-elena 1.0.13

View File

@ -141,6 +141,18 @@
<!-- <action application="export" data="sip_secure_media=true"/> -->
</condition>
<!--
Since we have inbound-late-negotation on by default now the
above behavior isn't the same so you have to do one extra step.
-->
<condition field="${endpoint_disposition}" expression="^(DELAYED NEGOTIATION)"/>
<condition field="${switch_r_sdp}" expression="(AES_CM_128_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_80)" break="never">
<action application="set" data="sip_secure_media=true"/>
<!-- Offer SRTP on outbound legs if we have it on inbound. -->
<!-- <action application="export" data="sip_secure_media=true"/> -->
</condition>
<condition>
<action application="hash" data="insert/${domain_name}-spymap/${caller_id_number}/${uuid}"/>
<action application="hash" data="insert/${domain_name}-last_dial/${caller_id_number}/${destination_number}"/>

View File

@ -577,7 +577,7 @@ AX_HAVE_CPU_SET
AC_CHECK_LIB(rt, clock_gettime, [AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if you have clock_gettime()])])
AC_CHECK_LIB(rt, clock_getres, [AC_DEFINE(HAVE_CLOCK_GETRES, 1, [Define if you have clock_getres()])])
AC_CHECK_LIB(rt, clock_nanosleep, [AC_DEFINE(HAVE_CLOCK_NANOSLEEP, 1, [Define if you have clock_nanosleep()])])
AC_CHECK_LIB(pthread, pthread_setschedprio, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPRIO, 1, [Define if you have pthread_setschedprio()])])
AC_CHECK_LIB(pthread, pthread_setschedparam, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPARAM, 1, [Define if you have pthread_setschedparam()])])
AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket))

1
debian/bootstrap.sh vendored
View File

@ -15,7 +15,6 @@ avoid_mods=(
applications/mod_rad_auth
applications/mod_skel
asr_tts/mod_cepstral
asr_tts/mod_flite
codecs/mod_com_g729
codecs/mod_ilbc
codecs/mod_sangoma_codec

2
debian/rules vendored
View File

@ -6,7 +6,7 @@
FS_CC?=gcc
FS_CXX?=g++
FS_CFLAGS?=-ggdb3 -O2
FS_CFLAGS?=-ggdb3 -O2 -fPIC
FS_CPPFLAGS?=
FS_CXXFLAGS?=$(FS_CFLAGS)
export PATH?=/usr/lib/ccache:/usr/sbin:/usr/bin:/sbin:/bin

View File

@ -1,3 +1,11 @@
freeswitch (1.2.5)
mod_lua: Enable mod_lua to use native pgsql dbh support (r:2cea7f0f)
mod_sofia: Add att_xfer_destination_number variable to indicate the original destination number of the attended transfer leg on REFER for semi-attended transfer scenarios. (r:893cd7be)
sounds: Bump Callie sounds ver to 1.0.22 (r:41e00c78)
freeswitch (1.2.4)
core: Add Postgres core db support (r:0c1180d5)
mod_cdr_mongodb: update MongoDB driver to v0.6 (r:10093b44)
mod_dingaling: do lookup in dingaling when an address is specified as host:foo.bar.com like sofia does (r:fbfe830a)
freeswitch (1.2.3)
core: add hold_events variable with start and stop times for each hold (r:9a193a9c)
core: update json lib in core and ESL and re-apply old patches (r:5a956890)

View File

@ -1 +1 @@
Tue Oct 23 13:13:30 EDT 2012
Wed Nov 7 10:37:54 CST 2012

View File

@ -1620,7 +1620,7 @@ APR_CHECK_DEFINE_FILES(POLLIN, poll.h sys/poll.h)
if test "$threads" = "1"; then
APR_CHECK_DEFINE(PTHREAD_PROCESS_SHARED, pthread.h)
AC_CHECK_FUNCS(pthread_mutexattr_setpshared)
AC_CHECK_LIB(pthread, pthread_setschedprio, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPRIO, 1, [Define if you have pthread_setschedprio()])])
AC_CHECK_LIB(pthread, pthread_setschedparam, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPARAM, 1, [Define if you have pthread_setschedparam()])])
# Some systems have setpshared and define PROCESS_SHARED, but don't
# really support PROCESS_SHARED locks. So, we must validate that we

View File

@ -146,6 +146,7 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new,
{
apr_status_t stat;
pthread_attr_t *temp;
pthread_t tt;
(*new) = (apr_thread_t *)apr_pcalloc(pool, sizeof(apr_thread_t));
@ -173,15 +174,21 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new,
return stat;
}
if ((stat = pthread_create((*new)->td, temp, dummy_worker, (*new))) == 0) {
if ((stat = pthread_create(&tt, temp, dummy_worker, (*new))) == 0) {
#ifdef HAVE_PTHREAD_SETSCHEDPRIO
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
if (attr && attr->priority) {
pthread_t *thread = (*new)->td;
pthread_setschedprio(*thread, attr->priority);
int policy;
struct sched_param param = { 0 };
pthread_getschedparam(tt, &policy, &param);
param.sched_priority = attr->priority;
pthread_setschedparam(tt, policy, &param);
}
#endif
*(*new)->td = tt;
return APR_SUCCESS;
}
else {

View File

@ -918,6 +918,7 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *
struct addrinfo hints = { 0 }, *result;
struct sockaddr_in *sockaddr_in;
struct sockaddr_in6 *sockaddr_in6;
socklen_t socklen;
#ifndef WIN32
int fd_flags = 0;
#else
@ -951,10 +952,12 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *
case AF_INET:
sockaddr_in = (struct sockaddr_in*)&(handle->sockaddr);
sockaddr_in->sin_port = htons(port);
socklen = sizeof(struct sockaddr_in);
break;
case AF_INET6:
sockaddr_in6 = (struct sockaddr_in6*)&(handle->sockaddr);
sockaddr_in6->sin6_port = htons(port);
socklen = sizeof(struct sockaddr_in6);
break;
default:
strncpy(handle->err, "Host resolves to unsupported address family", sizeof(handle->err));
@ -985,7 +988,7 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *
#endif
}
rval = connect(handle->sock, (struct sockaddr*)&handle->sockaddr, sizeof(handle->sockaddr));
rval = connect(handle->sock, (struct sockaddr*)&handle->sockaddr, socklen);
if (timeout) {
int r;

View File

@ -942,7 +942,7 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
ftdm_channel_t *chtmp = chan;
if (call) {
pri_destroycall(isdn_data->spri.pri, call);
/* pri call destroy is done by libpri itself (on release_ack) */
chan_priv->call = NULL;
}
@ -953,6 +953,9 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
lpwrap_stop_timer(&isdn_data->spri, &chan_priv->t316);
chan_priv->t316_timeout_cnt = 0;
/* Unset remote hangup */
chan_priv->peerhangup = 0;
if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n",
ftdm_channel_get_span_id(chan),
@ -1206,12 +1209,21 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
{
if (call) {
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
pri_hangup(isdn_data->spri.pri, call, caller_data->hangup_cause);
// pri_destroycall(isdn_data->spri.pri, call);
// chan_priv->call = NULL;
if (chan_priv->peerhangup) {
/* Call is inbound and hangup has been initiated by peer */
if (!ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
} else if (caller_data->hangup_cause == PRI_CAUSE_NO_USER_RESPONSE) {
/* Can happen when we have a DL link expire or some timer expired */
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
} else if (caller_data->hangup_cause == PRI_CAUSE_DESTINATION_OUT_OF_ORDER) {
/* Can happen when we have a DL link expire or some timer expired */
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
}
}
}
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
}
break;
@ -1368,6 +1380,7 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
{
ftdm_span_t *span = spri->span;
ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->hangup.channel);
ftdm_libpri_b_chan_t *chan_priv = chan->call_data;
if (!chan) {
ftdm_log(FTDM_LOG_CRIT, "-- Hangup on channel %d:%d but it's not in use?\n", ftdm_span_get_id(spri->span), pevent->hangup.channel);
@ -1386,8 +1399,6 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup REQ on channel %d:%d\n",
ftdm_span_get_id(spri->span), pevent->hangup.channel);
pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause);
chan->caller_data.hangup_cause = pevent->hangup.cause;
switch (ftdm_channel_get_state(chan)) {
@ -1400,19 +1411,27 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
}
break;
case LPWRAP_PRI_EVENT_HANGUP_ACK: /* */
case LPWRAP_PRI_EVENT_HANGUP_ACK: /* RELEASE_COMPLETE */
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup ACK on channel %d:%d\n",
ftdm_span_get_id(spri->span), pevent->hangup.channel);
pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause);
ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
switch (ftdm_channel_get_state(chan)) {
case FTDM_CHANNEL_STATE_RESTART:
/* ACK caused by DL FAILURE in DISC REQ */
ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN);
break;
default:
ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
break;
}
break;
case LPWRAP_PRI_EVENT_HANGUP: /* "RELEASE/RELEASE_COMPLETE/other" */
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n",
ftdm_span_get_id(spri->span), pevent->hangup.channel);
chan_priv->peerhangup = 1;
switch (ftdm_channel_get_state(chan)) {
case FTDM_CHANNEL_STATE_DIALING:
case FTDM_CHANNEL_STATE_RINGING:
@ -1424,9 +1443,19 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING);
break;
case FTDM_CHANNEL_STATE_HANGUP:
/* this will send "RELEASE_COMPLETE", eventually */
pri_hangup(spri->pri, pevent->hangup.call, chan->caller_data.hangup_cause);
chan->caller_data.hangup_cause = pevent->hangup.cause;
ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
break;
case FTDM_CHANNEL_STATE_RESTART:
/*
* We got an hungup doing a restart, normally beacause link has been lost during
* a call and the T309 timer has expired. So destroy it :) (DL_RELEASE_IND)
*/
pri_destroycall(spri->pri, pevent->hangup.call);
ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN);
break;
// case FTDM_CHANNEL_STATE_TERMINATING:
// ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP);
// break;

View File

@ -131,6 +131,7 @@ struct ftdm_libpri_b_chan {
q931_call *call; /*!< libpri opaque call handle */
uint32_t flags; /*!< channel flags */
uint32_t t316_timeout_cnt; /*!< T316 timeout counter */
int peerhangup; /*!< hangup requested from libpri (RELEASE/RELEASE_ACK/DL_RELEASE/TIMERS EXPIRY) */
};
typedef struct ftdm_libpri_b_chan ftdm_libpri_b_chan_t;

View File

@ -169,6 +169,10 @@ int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *
if (spri->pri) {
pri_set_debug(spri->pri, debug);
#ifdef HAVE_LIBPRI_BRI
/* "follow Q.931 Section 5.3.2 call hangup better" */
pri_hangup_fix_enable(spri->pri, 1);
#endif
#ifdef HAVE_LIBPRI_AOC
pri_aoc_events_enable(spri->pri, 1);
#endif

View File

@ -102,6 +102,7 @@ struct ioctl_codes {
ioctlcmd SETTXBITS;
ioctlcmd GETRXBITS;
ioctlcmd SETPOLARITY;
ioctlcmd TONEDETECT;
};
/**
@ -139,7 +140,8 @@ static struct ioctl_codes zt_ioctl_codes = {
.GETCONFMUTE = ZT_GETCONFMUTE,
.ECHOTRAIN = ZT_ECHOTRAIN,
.SETTXBITS = ZT_SETTXBITS,
.GETRXBITS = ZT_GETRXBITS
.GETRXBITS = ZT_GETRXBITS,
.TONEDETECT = ZT_TONEDETECT,
};
/**
@ -178,7 +180,8 @@ static struct ioctl_codes dahdi_ioctl_codes = {
.ECHOTRAIN = DAHDI_ECHOTRAIN,
.SETTXBITS = DAHDI_SETTXBITS,
.GETRXBITS = DAHDI_GETRXBITS,
.SETPOLARITY = DAHDI_SETPOLARITY
.SETPOLARITY = DAHDI_SETPOLARITY,
.TONEDETECT = DAHDI_TONEDETECT,
};
#define ZT_INVALID_SOCKET -1
@ -271,6 +274,7 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f
{
unsigned configured = 0, x;
zt_params_t ztp;
zt_tone_mode_t mode = 0;
memset(&ztp, 0, sizeof(ztp));
@ -361,7 +365,7 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f
cc.sigtype = ZT_SIG_CAS;
cc.idlebits = cas_bits;
if (ioctl(CONTROL_FD, codes.CHANCONFIG, &cc)) {
ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d err:%s", chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd, strerror(errno));
ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d err:%s\n", chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd, strerror(errno));
close(sockfd);
continue;
}
@ -436,12 +440,23 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f
continue;
}
mode = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
if (ioctl(sockfd, codes.TONEDETECT, &mode)) {
ftdm_log(FTDM_LOG_DEBUG, "HW DTMF not available on FreeTDM device %d:%d fd:%d\n", ftdmchan->span_id, ftdmchan->chan_id, sockfd);
} else {
ftdm_log(FTDM_LOG_DEBUG, "HW DTMF available on FreeTDM device %d:%d fd:%d\n", ftdmchan->span_id, ftdmchan->chan_id, sockfd);
ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT);
mode = 0;
ioctl(sockfd, codes.TONEDETECT, &mode);
}
if (!ftdm_strlen_zero(name)) {
ftdm_copy_string(ftdmchan->chan_name, name, sizeof(ftdmchan->chan_name));
}
if (!ftdm_strlen_zero(number)) {
ftdm_copy_string(ftdmchan->chan_number, number, sizeof(ftdmchan->chan_number));
}
configured++;
} else {
ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s\n", chanpath);
@ -666,7 +681,6 @@ static FIO_OPEN_FUNCTION(zt_open)
}
}
}
}
return FTDM_SUCCESS;
}
@ -858,6 +872,24 @@ static FIO_COMMAND_FUNCTION(zt_command)
err = ioctl(ftdmchan->sockfd, codes.FLUSH, &flushmode);
}
break;
case FTDM_COMMAND_SET_RX_QUEUE_SIZE:
case FTDM_COMMAND_SET_TX_QUEUE_SIZE:
/* little white lie ... eventually we can implement this, in the meantime, not worth the effort
and this is only used by some sig modules such as ftmod_r2 to behave bettter under load */
err = 0;
break;
case FTDM_COMMAND_ENABLE_DTMF_DETECT:
{
zt_tone_mode_t mode = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
err = ioctl(ftdmchan->sockfd, codes.TONEDETECT, &mode);
}
break;
case FTDM_COMMAND_DISABLE_DTMF_DETECT:
{
zt_tone_mode_t mode = 0;
err = ioctl(ftdmchan->sockfd, codes.TONEDETECT, &mode);
}
break;
default:
err = FTDM_NOTIMPL;
break;
@ -949,7 +981,7 @@ pollagain:
pfds[0].fd = ftdmchan->sockfd;
pfds[0].events = inflags;
result = poll(pfds, 1, to);
*flags = 0;
*flags = FTDM_NO_FLAGS;
if (result < 0 && errno == EINTR) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "DAHDI wait got interrupted, trying again\n");
@ -965,8 +997,6 @@ pollagain:
inflags = pfds[0].revents;
}
*flags = FTDM_NO_FLAGS;
if (result < 0){
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Poll failed");
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to poll DAHDI device: %s\n", strerror(errno));
@ -1042,6 +1072,23 @@ FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event)
return k ? FTDM_SUCCESS : FTDM_FAIL;
}
static __inline__ int handle_dtmf_event(ftdm_channel_t *fchan, zt_event_t zt_event_id)
{
if ((zt_event_id & ZT_EVENT_DTMFUP)) {
int digit = (zt_event_id & (~ZT_EVENT_DTMFUP));
char tmp_dtmf[2] = { digit, 0 };
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "DTMF UP [%d]\n", digit);
ftdm_channel_queue_dtmf(fchan, tmp_dtmf);
return 0;
} else if ((zt_event_id & ZT_EVENT_DTMFDOWN)) {
int digit = (zt_event_id & (~ZT_EVENT_DTMFDOWN));
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "DTMF DOWN [%d]\n", digit);
return 0;
} else {
return -1;
}
}
/**
* \brief Process an event from a ftdmchan and set the proper OOB event_id. The channel must be locked.
* \param fchan Channel to retrieve event from
@ -1151,8 +1198,12 @@ static __inline__ ftdm_status_t zt_channel_process_event(ftdm_channel_t *fchan,
break;
default:
{
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Unhandled event %d\n", zt_event_id);
*event_id = FTDM_OOB_INVALID;
if (handle_dtmf_event(fchan, zt_event_id)) {
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Unhandled event %d\n", zt_event_id);
*event_id = FTDM_OOB_INVALID;
} else {
*event_id = FTDM_OOB_NOOP;
}
}
break;
}
@ -1308,8 +1359,12 @@ tryagain:
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed retrieving event after ELAST on write: %s\n", strerror(errno));
return FTDM_FAIL;
}
/* we should enqueue this event somewhere so it can be retrieved by the user, for now, dropping it to see what it is! */
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dropping event %d to be able to write data\n", zt_event_id);
if (handle_dtmf_event(ftdmchan, zt_event_id)) {
/* we should enqueue this event somewhere so it can be retrieved by the user, for now, dropping it to see what it is! */
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dropping event %d to be able to write data\n", zt_event_id);
}
goto tryagain;
}
@ -1325,7 +1380,6 @@ static FIO_CHANNEL_DESTROY_FUNCTION(zt_channel_destroy)
{
close(ftdmchan->sockfd);
ftdmchan->sockfd = ZT_INVALID_SOCKET;
return FTDM_SUCCESS;
}

View File

@ -195,7 +195,9 @@ typedef enum {
ZT_EVENT_TIMER_EXPIRED = 15,
ZT_EVENT_TIMER_PING = 16,
ZT_EVENT_POLARITY = 17,
ZT_EVENT_RINGBEGIN = 18
ZT_EVENT_RINGBEGIN = 18,
ZT_EVENT_DTMFDOWN = (1 << 17),
ZT_EVENT_DTMFUP = (1 << 18),
} zt_event_t;
typedef enum {
@ -258,6 +260,12 @@ ZT_BBIT = 4,
ZT_ABIT = 8
} zt_cas_bit_t;
typedef enum {
/* Tone Detection */
ZT_TONEDETECT_ON = (1 << 0), /* Detect tones */
ZT_TONEDETECT_MUTE = (1 << 1) /* Mute audio in received channel */
} zt_tone_mode_t;
/* Defines */
#define ZT_MAX_BLOCKSIZE 8192
@ -312,6 +320,11 @@ ZT_ABIT = 8
#define ZT_SETTXBITS _IOW (ZT_CODE, 43, int)
#define ZT_GETRXBITS _IOR (ZT_CODE, 45, int)
/*
* Enable tone detection -- implemented by low level driver
*/
#define ZT_TONEDETECT _IOW(ZT_CODE, 91, int)
#define DAHDI_GET_BLOCKSIZE _IOR (DAHDI_CODE, 1, int) /* Get Transfer Block Size. */
#define DAHDI_SET_BLOCKSIZE _IOW (DAHDI_CODE, 1, int) /* Set Transfer Block Size. */
#define DAHDI_FLUSH _IOW (DAHDI_CODE, 3, int) /* Flush Buffer(s) and stop I/O */
@ -361,6 +374,11 @@ ZT_ABIT = 8
#define DAHDI_SETPOLARITY _IOW (DAHDI_CODE, 92, int) /* Polarity setting for FXO lines */
/*
* Enable tone detection -- implemented by low level driver
*/
#define DAHDI_TONEDETECT _IOW(DAHDI_CODE, 91, int)
#endif
/* For Emacs:

View File

@ -45,7 +45,7 @@ __RCSID("$NetBSD: unvis.c,v 1.28 2005/09/13 01:44:09 christos Exp $");
#include <stdio.h>
#include <vis.h>
#if defined(__weak_reference) && !defined(__FreeBSD__)
#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__)
__weak_alias(strunvis,_strunvis)
#endif

View File

@ -915,14 +915,14 @@ vi_comment_out(EditLine *el, int c)
* NB: posix implies that we should enter insert mode, however
* this is against historical precedent...
*/
#if defined(__weak_reference) && !defined(__FreeBSD__)
#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__)
extern char *get_alias_text(const char *) __weak_reference(get_alias_text);
#endif
protected el_action_t
/*ARGSUSED*/
vi_alias(EditLine *el, int c)
{
#if defined(__weak_reference) && !defined(__FreeBSD__)
#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__)
char alias_name[3];
char *alias_text;

View File

@ -88,7 +88,7 @@ __RCSID("$NetBSD: vis.c,v 1.35 2006/08/28 20:42:12 christos Exp $");
#include <vis.h>
#include <stdlib.h>
#if defined(__weak_reference) && !defined(__FreeBSD__)
#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__)
__weak_alias(strsvis,_strsvis)
__weak_alias(strsvisx,_strsvisx)
__weak_alias(strvis,_strvis)

View File

@ -1 +1 @@
Fri Nov 2 13:36:06 CDT 2012
Tue Nov 13 15:22:19 CST 2012

View File

@ -254,7 +254,7 @@ if test x"$have_check" = "xyes"; then
fi
AC_CHECK_HEADERS([fnmatch.h])
AC_CHECK_LIB(pthread, pthread_setschedprio, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPRIO, 1, [Define if you have pthread_setschedprio()])])
AC_CHECK_LIB(pthread, pthread_setschedparam, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPARAM, 1, [Define if you have pthread_setschedparam()])])
dnl dl is currently used only in testing

View File

@ -9211,7 +9211,7 @@ int outgoing_recv(nta_outgoing_t *_orq,
if (orq->orq_destroyed && 200 <= status && status < 300) {
if (orq->orq_uas && su_strcasecmp(sip->sip_to->a_tag, orq->orq_tag) != 0) {
/* Orphan 200 Ok to INVITE. ACK and BYE it */
SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE\n" VA_NONE));
SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE %p\n", (void *)orq));
return nta_msg_ackbye(sa, msg);
}
return -1; /* Proxy statelessly (RFC3261 section 16.11) */

View File

@ -1245,6 +1245,7 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
int status = 200;
char const *phrase = "OK", *reason = NULL;
char const *invite_branch;
char const *pl_s = NULL;
assert(cr->cr_orq);
assert(cr->cr_method == sip_method_invite);
@ -1256,6 +1257,11 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
goto error;
}
tl_gets(tags,
SIPTAG_PAYLOAD_STR_REF(pl_s),
TAG_END());
assert(ds->ds_leg);
msg = nta_outgoing_getrequest(cr->cr_orq);
@ -1305,7 +1311,7 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
while (sip->sip_supported)
sip_header_remove(msg, sip, (sip_header_t*)sip->sip_supported);
if (ss == NULL || ss->ss_state > nua_callstate_ready)
if (ss == NULL || ss->ss_state > nua_callstate_ready || pl_s)
;
else if (cr->cr_offer_recv && !cr->cr_answer_sent) {
if (nh->nh_soa == NULL) {

View File

@ -510,13 +510,20 @@ issize_t su_vsend(su_socket_t s,
su_sockaddr_t const *su, socklen_t sulen)
{
struct msghdr hdr[1] = {{0}};
int rv;
hdr->msg_name = (void *)su;
hdr->msg_namelen = sulen;
hdr->msg_iov = (struct iovec *)iov;
hdr->msg_iovlen = iovlen;
return sendmsg(s, hdr, flags);
do {
if ((rv = sendmsg(s, hdr, flags)) == -1) {
if (errno == EAGAIN) usleep(1000);
}
} while (rv == -1 && (errno == EAGAIN || errno == EINTR));
return rv;
}
issize_t su_vrecv(su_socket_t s, su_iovec_t iov[], isize_t iovlen, int flags,
@ -531,7 +538,9 @@ issize_t su_vrecv(su_socket_t s, su_iovec_t iov[], isize_t iovlen, int flags,
hdr->msg_iov = (struct iovec *)iov;
hdr->msg_iovlen = iovlen;
retval = recvmsg(s, hdr, flags);
do {
retval = recvmsg(s, hdr, flags);
} while (retval == -1 && errno == EINTR);
if (su && sulen)
*sulen = hdr->msg_namelen;

View File

@ -268,9 +268,13 @@ int su_pthreaded_port_start(su_port_create_f *create,
pthread_mutex_lock(arg.mutex);
if (pthread_create(&tid, &attr, su_pthread_port_clone_main, &arg) == 0) {
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
int policy;
struct sched_param param;
#ifdef HAVE_PTHREAD_SETSCHEDPRIO
pthread_setschedprio(tid, 99);
pthread_getschedparam(tid, &policy, &param);
param.sched_priority = 99;
pthread_setschedparam(tid, policy, &param);
#endif
pthread_cond_wait(arg.cv, arg.mutex);

View File

@ -212,6 +212,9 @@ struct t30_state_s
/*! \brief TRUE once the far end FAX entity has been detected. */
int far_end_detected;
/*! \brief TRUE once the end of procedure condition has been detected. */
int end_of_procedure_detected;
/*! \brief TRUE if a local T.30 interrupt is pending. */
int local_interrupt_pending;

View File

@ -88,6 +88,16 @@ typedef int (*span_tx_handler_t)(void *s, int16_t amp[], int max_len);
#define FP_Q_2_14(x) ((int16_t) (16384.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_1_15(x) ((int16_t) (32768.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_9_7_32(x) ((int32_t) (128.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_8_8_32(x) ((int32_t) (256.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_7_9_32(x) ((int32_t) (512.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_6_10_32(x) ((int32_t) (1024.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_5_11_32(x) ((int32_t) (2048.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_4_12_32(x) ((int32_t) (4096.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_3_13_32(x) ((int32_t) (8192.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_2_14_32(x) ((int32_t) (16384.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_1_15_32(x) ((int32_t) (32768.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_9_23(x) ((int32_t) (65536.0*128.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_8_24(x) ((int32_t) (65536.0*256.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_7_25(x) ((int32_t) (65536.0*512.0*x + ((x >= 0.0) ? 0.5 : -0.5)))

View File

@ -132,19 +132,19 @@ enum
static const char *phase_names[] =
{
"T30_PHASE_IDLE",
"T30_PHASE_A_CED",
"T30_PHASE_A_CNG",
"T30_PHASE_B_RX",
"T30_PHASE_B_TX",
"T30_PHASE_C_NON_ECM_RX",
"T30_PHASE_C_NON_ECM_TX",
"T30_PHASE_C_ECM_RX",
"T30_PHASE_C_ECM_TX",
"T30_PHASE_D_RX",
"T30_PHASE_D_TX",
"T30_PHASE_E",
"T30_PHASE_CALL_FINISHED"
"IDLE",
"A_CED",
"A_CNG",
"B_RX",
"B_TX",
"C_NON_ECM_RX",
"C_NON_ECM_TX",
"C_ECM_RX",
"C_ECM_TX",
"D_RX",
"D_TX",
"E",
"CALL_FINISHED"
};
/* These state names are modelled after places in the T.30 flow charts. */
@ -184,6 +184,43 @@ enum
T30_STATE_CALL_FINISHED
};
static const char *state_names[] =
{
"NONE",
"ANSWERING",
"B",
"C",
"D",
"D_TCF",
"D_POST_TCF",
"F_TCF",
"F_CFR",
"F_FTT",
"F_DOC_NON_ECM",
"F_POST_DOC_NON_ECM",
"F_DOC_ECM",
"F_POST_DOC_ECM",
"F_POST_RCP_MCF",
"F_POST_RCP_PPR",
"F_POST_RCP_RNR",
"R",
"T",
"I",
"II",
"II_Q",
"III_Q_MCF",
"III_Q_RTP",
"III_Q_RTN",
"IV",
"IV_PPS_NULL",
"IV_PPS_Q",
"IV_PPS_RNR",
"IV_CTC",
"IV_EOR",
"IV_EOR_RNR",
"CALL_FINISHED"
};
enum
{
T30_MIN_SCAN_20MS = 0,
@ -1309,7 +1346,7 @@ static int build_dcs(t30_state_t *s)
int i;
int bad;
int row_squashing_ratio;
/* Make a DCS frame based on local issues and the latest received DIS/DTC frame. Negotiate
the result based on what both parties can do. */
s->dcs_frame[0] = ADDRESS_FIELD;
@ -2017,7 +2054,7 @@ static int start_receiving_document(t30_state_t *s)
static void unexpected_non_final_frame(t30_state_t *s, const uint8_t *msg, int len)
{
span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %d\n", t30_frametype(msg[2]), s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %s\n", t30_frametype(msg[2]), state_names[s->state]);
if (s->current_status == T30_ERR_OK)
t30_set_status(s, T30_ERR_UNEXPECTED);
}
@ -2025,7 +2062,7 @@ static void unexpected_non_final_frame(t30_state_t *s, const uint8_t *msg, int l
static void unexpected_final_frame(t30_state_t *s, const uint8_t *msg, int len)
{
span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %d\n", t30_frametype(msg[2]), s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %s\n", t30_frametype(msg[2]), state_names[s->state]);
if (s->current_status == T30_ERR_OK)
t30_set_status(s, T30_ERR_UNEXPECTED);
send_dcn(s);
@ -2473,17 +2510,15 @@ static int send_response_to_pps(t30_state_t *s)
{
set_state(s, T30_STATE_F_POST_RCP_MCF);
send_simple_frame(s, T30_MCF);
return TRUE;
}
else
{
/* We need to send the PPR frame we have created, to try to fill in the missing/bad data. */
set_state(s, T30_STATE_F_POST_RCP_PPR);
s->ecm_frame_map[0] = ADDRESS_FIELD;
s->ecm_frame_map[1] = CONTROL_FIELD_FINAL_FRAME;
s->ecm_frame_map[2] = (uint8_t) (T30_PPR | s->dis_received);
send_frame(s, s->ecm_frame_map, 3 + 32);
}
return 0;
/* We need to send the PPR frame we have created, to try to fill in the missing/bad data. */
set_state(s, T30_STATE_F_POST_RCP_PPR);
s->ecm_frame_map[0] = ADDRESS_FIELD;
s->ecm_frame_map[1] = CONTROL_FIELD_FINAL_FRAME;
s->ecm_frame_map[2] = (uint8_t) (T30_PPR | s->dis_received);
send_frame(s, s->ecm_frame_map, 3 + 32);
return FALSE;
}
/*- End of function --------------------------------------------------------*/
@ -2685,7 +2720,17 @@ static int process_rx_pps(t30_state_t *s, const uint8_t *msg, int len)
}
else
{
send_response_to_pps(s);
if (send_response_to_pps(s))
{
switch (s->last_pps_fcf2)
{
case T30_PRI_EOP:
case T30_EOP:
span_log(&s->logging, SPAN_LOG_FLOW, "End of procedure detected\n");
s->end_of_procedure_detected = TRUE;
break;
}
}
}
break;
default:
@ -3364,6 +3409,8 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
}
/* Fall through */
case T30_EOP:
span_log(&s->logging, SPAN_LOG_FLOW, "End of procedure detected\n");
s->end_of_procedure_detected = TRUE;
s->next_rx_step = fcf;
queue_phase(s, T30_PHASE_D_TX);
switch (copy_quality(s))
@ -3397,7 +3444,6 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
send_simple_frame(s, T30_RTN);
break;
}
break;
case T30_DCN:
t30_set_status(s, T30_ERR_RX_DCNFAX);
@ -3565,7 +3611,17 @@ static void process_state_f_post_rcp_rnr(t30_state_t *s, const uint8_t *msg, int
else
{
/* Now we send the deferred response */
send_response_to_pps(s);
if (send_response_to_pps(s))
{
switch (s->last_pps_fcf2)
{
case T30_PRI_EOP:
case T30_EOP:
span_log(&s->logging, SPAN_LOG_FLOW, "End of procedure detected\n");
s->end_of_procedure_detected = TRUE;
break;
}
}
}
break;
case T30_CRP:
@ -4656,7 +4712,7 @@ static void process_rx_control_msg(t30_state_t *s, const uint8_t *msg, int len)
/* The following handles context sensitive message types, which should
occur at the end of message sequences. They should, therefore have
the final frame flag set. */
span_log(&s->logging, SPAN_LOG_FLOW, "Rx final frame in state %d\n", s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "Rx final frame in state %s\n", state_names[s->state]);
switch (s->state)
{
@ -4891,7 +4947,7 @@ static void set_state(t30_state_t *s, int state)
{
if (s->state != state)
{
span_log(&s->logging, SPAN_LOG_FLOW, "Changing from state %d to %d\n", s->state, state);
span_log(&s->logging, SPAN_LOG_FLOW, "Changing from state %s to %s\n", state_names[s->state], state_names[state]);
s->state = state;
}
s->step = 0;
@ -4982,9 +5038,9 @@ static void repeat_last_command(t30_state_t *s)
default:
span_log(&s->logging,
SPAN_LOG_FLOW,
"Repeat command called with nothing to repeat - phase %s, state %d\n",
"Repeat command called with nothing to repeat - phase %s, state %s\n",
phase_names[s->phase],
s->state);
state_names[s->state]);
break;
}
}
@ -5098,7 +5154,7 @@ static void timer_t2_t4_stop(t30_state_t *s)
static void timer_t0_expired(t30_state_t *s)
{
span_log(&s->logging, SPAN_LOG_FLOW, "T0 expired in state %d\n", s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "T0 expired in state %s\n", state_names[s->state]);
t30_set_status(s, T30_ERR_T0_EXPIRED);
/* Just end the call */
disconnect(s);
@ -5107,7 +5163,7 @@ static void timer_t0_expired(t30_state_t *s)
static void timer_t1_expired(t30_state_t *s)
{
span_log(&s->logging, SPAN_LOG_FLOW, "T1 expired in state %d\n", s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "T1 expired in state %s\n", state_names[s->state]);
/* The initial connection establishment has timeout out. In other words, we
have been unable to communicate successfully with a remote machine.
It is time to abandon the call. */
@ -5132,7 +5188,7 @@ static void timer_t1_expired(t30_state_t *s)
static void timer_t2_expired(t30_state_t *s)
{
if (s->timer_t2_t4_is != TIMER_IS_T2B)
span_log(&s->logging, SPAN_LOG_FLOW, "T2 expired in phase %s, state %d\n", phase_names[s->phase], s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "T2 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
switch (s->state)
{
case T30_STATE_III_Q_MCF:
@ -5202,7 +5258,7 @@ static void timer_t2_expired(t30_state_t *s)
static void timer_t1a_expired(t30_state_t *s)
{
span_log(&s->logging, SPAN_LOG_FLOW, "T1A expired in phase %s, state %d. An HDLC frame lasted too long.\n", phase_names[s->phase], s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "T1A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]);
t30_set_status(s, T30_ERR_HDLC_CARRIER);
disconnect(s);
}
@ -5210,7 +5266,7 @@ static void timer_t1a_expired(t30_state_t *s)
static void timer_t2a_expired(t30_state_t *s)
{
span_log(&s->logging, SPAN_LOG_FLOW, "T2A expired in phase %s, state %d. An HDLC frame lasted too long.\n", phase_names[s->phase], s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "T2A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]);
t30_set_status(s, T30_ERR_HDLC_CARRIER);
disconnect(s);
}
@ -5218,14 +5274,14 @@ static void timer_t2a_expired(t30_state_t *s)
static void timer_t2b_expired(t30_state_t *s)
{
span_log(&s->logging, SPAN_LOG_FLOW, "T2B expired in phase %s, state %d. The line is now quiet.\n", phase_names[s->phase], s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "T2B expired in phase %s, state %s. The line is now quiet.\n", phase_names[s->phase], state_names[s->state]);
timer_t2_expired(s);
}
/*- End of function --------------------------------------------------------*/
static void timer_t3_expired(t30_state_t *s)
{
span_log(&s->logging, SPAN_LOG_FLOW, "T3 expired in phase %s, state %d\n", phase_names[s->phase], s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "T3 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
t30_set_status(s, T30_ERR_T3_EXPIRED);
disconnect(s);
}
@ -5235,7 +5291,7 @@ static void timer_t4_expired(t30_state_t *s)
{
/* There was no response (or only a corrupt response) to a command,
within the T4 timeout period. */
span_log(&s->logging, SPAN_LOG_FLOW, "T4 expired in phase %s, state %d\n", phase_names[s->phase], s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "T4 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
/* Of course, things might just be a little late, especially if there are T.38
links in the path. There is no point in simply timing out, and resending,
if we are currently receiving something from the far end - its a half-duplex
@ -5249,7 +5305,7 @@ static void timer_t4_expired(t30_state_t *s)
static void timer_t4a_expired(t30_state_t *s)
{
span_log(&s->logging, SPAN_LOG_FLOW, "T4A expired in phase %s, state %d. An HDLC frame lasted too long.\n", phase_names[s->phase], s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "T4A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]);
t30_set_status(s, T30_ERR_HDLC_CARRIER);
disconnect(s);
}
@ -5257,7 +5313,7 @@ static void timer_t4a_expired(t30_state_t *s)
static void timer_t4b_expired(t30_state_t *s)
{
span_log(&s->logging, SPAN_LOG_FLOW, "T4B expired in phase %s, state %d. The line is now quiet.\n", phase_names[s->phase], s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "T4B expired in phase %s, state %s. The line is now quiet.\n", phase_names[s->phase], state_names[s->state]);
timer_t4_expired(s);
}
/*- End of function --------------------------------------------------------*/
@ -5265,7 +5321,7 @@ static void timer_t4b_expired(t30_state_t *s)
static void timer_t5_expired(t30_state_t *s)
{
/* Give up waiting for the receiver to become ready in error correction mode */
span_log(&s->logging, SPAN_LOG_FLOW, "T5 expired in phase %s, state %d\n", phase_names[s->phase], s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "T5 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
t30_set_status(s, T30_ERR_TX_T5EXP);
}
/*- End of function --------------------------------------------------------*/
@ -5351,7 +5407,7 @@ static void t30_non_ecm_rx_status(void *user_data, int status)
int was_trained;
s = (t30_state_t *) user_data;
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM signal status is %s (%d) in state %d\n", signal_status_to_str(status), status, s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM signal status is %s (%d) in state %s\n", signal_status_to_str(status), status, state_names[s->state]);
switch (status)
{
case SIG_STATUS_TRAINING_IN_PROGRESS:
@ -5555,7 +5611,7 @@ SPAN_DECLARE_NONSTD(int) t30_non_ecm_get_bit(void *user_data)
bit = 0;
break;
default:
span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get_bit in bad state %d\n", s->state);
span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get_bit in bad state %s\n", state_names[s->state]);
bit = SIG_STATUS_END_OF_DATA;
break;
}
@ -5590,7 +5646,7 @@ SPAN_DECLARE(int) t30_non_ecm_get(void *user_data, uint8_t buf[], int max_len)
len = 0;
break;
default:
span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get in bad state %d\n", s->state);
span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get in bad state %s\n", state_names[s->state]);
len = -1;
break;
}
@ -5604,7 +5660,7 @@ static void t30_hdlc_rx_status(void *user_data, int status)
int was_trained;
s = (t30_state_t *) user_data;
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC signal status is %s (%d) in state %d\n", signal_status_to_str(status), status, s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC signal status is %s (%d) in state %s\n", signal_status_to_str(status), status, state_names[s->state]);
switch (status)
{
case SIG_STATUS_TRAINING_IN_PROGRESS:
@ -5798,7 +5854,7 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status)
switch (status)
{
case T30_FRONT_END_SEND_STEP_COMPLETE:
span_log(&s->logging, SPAN_LOG_FLOW, "Send complete in phase %s, state %d\n", phase_names[s->phase], s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "Send complete in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
/* We have finished sending our messages, so move on to the next operation. */
switch (s->state)
{
@ -6025,12 +6081,12 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status)
disconnect from the far end overlaps something. */
break;
default:
span_log(&s->logging, SPAN_LOG_FLOW, "Bad state for send complete in t30_front_end_status - %d\n", s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "Bad state for send complete in t30_front_end_status - %s\n", state_names[s->state]);
break;
}
break;
case T30_FRONT_END_RECEIVE_COMPLETE:
span_log(&s->logging, SPAN_LOG_FLOW, "Receive complete in phase %s, state %d\n", phase_names[s->phase], s->state);
span_log(&s->logging, SPAN_LOG_FLOW, "Receive complete in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
/* Usually receive complete is notified by a carrier down signal. However,
in cases like a T.38 packet stream dying in the middle of reception
there needs to be a means to stop things. */
@ -6175,8 +6231,12 @@ SPAN_DECLARE(void) t30_terminate(t30_state_t *s)
hussle things along. */
break;
default:
/* The call terminated prematurely. */
t30_set_status(s, T30_ERR_CALLDROPPED);
/* If we have seen a genuine EOP or PRI_EOP, that's good enough. */
if (!s->end_of_procedure_detected)
{
/* The call terminated prematurely. */
t30_set_status(s, T30_ERR_CALLDROPPED);
}
break;
}
if (s->phase_e_handler)
@ -6268,6 +6328,7 @@ SPAN_DECLARE(int) t30_restart(t30_state_t *s)
s->rtp_events = 0;
s->local_interrupt_pending = FALSE;
s->far_end_detected = FALSE;
s->end_of_procedure_detected = FALSE;
s->timer_t0_t1 = ms_to_samples(DEFAULT_TIMER_T0);
if (s->calling_party)
{

View File

@ -661,7 +661,7 @@ static int make_header(t4_tx_state_t *s)
if ((s->header_text = malloc(132 + 1)) == NULL)
return -1;
}
/* This is very English oriented, but then most FAX machines are. Some
/* This is very English oriented, but then most FAX machines are, too. Some
measure of i18n in the time and date, and even the header_info string, is
entirely possible, although the font area would need some serious work to
properly deal with East Asian script. There is no spec for what the header
@ -733,26 +733,21 @@ static int header_row_read_handler(void *user_data, uint8_t buf[], size_t len)
return len;
}
}
switch (s->tiff.image_type)
row = s->header_row/repeats;
pos = 0;
for (t = s->header_text; *t && pos <= len - 2; t++)
{
case T4_IMAGE_TYPE_BILEVEL:
row = s->header_row/repeats;
pos = 0;
for (t = s->header_text; *t && pos <= len - 2; t++)
{
pattern = header_font[(uint8_t) *t][row];
buf[pos++] = (uint8_t) (pattern >> 8);
buf[pos++] = (uint8_t) (pattern & 0xFF);
}
while (pos < len)
buf[pos++] = 0;
s->header_row++;
if (s->header_row >= 16*repeats)
{
/* End of header. Change to normal image row data. */
set_row_read_handler(s, s->row_handler, s->row_handler_user_data);
}
break;
pattern = header_font[(uint8_t) *t][row];
buf[pos++] = (uint8_t) (pattern >> 8);
buf[pos++] = (uint8_t) (pattern & 0xFF);
}
while (pos < len)
buf[pos++] = 0;
s->header_row++;
if (s->header_row >= 16*repeats)
{
/* End of header. Change to normal image row data. */
set_row_read_handler(s, s->row_handler, s->row_handler_user_data);
}
return len;
}
@ -1113,7 +1108,7 @@ SPAN_DECLARE(int) t4_tx_start_page(t4_tx_state_t *s)
break;
}
/* If there is a page header, create that first */
if (s->header_info && s->header_info[0] && make_header(s) == 0)
if (s->tiff.image_type == T4_IMAGE_TYPE_BILEVEL && s->header_info && s->header_info[0] && make_header(s) == 0)
{
s->header_row = 0;
set_row_read_handler(s, header_row_read_handler, (void *) s);

View File

@ -106,6 +106,7 @@ int image_width = 1728;
int octets_per_ecm_frame = 256;
int error_correcting_mode = FALSE;
int current_fallback = 0;
int end_of_page_detected = FALSE;
static void decode_20digit_msg(const uint8_t *pkt, int len)
{
@ -232,8 +233,6 @@ static int check_rx_dcs(const uint8_t *msg, int len)
if ((current_fallback = find_fallback_entry(dcs_frame[4] & (DISBIT6 | DISBIT5 | DISBIT4 | DISBIT3))) < 0)
printf("Remote asked for a modem standard we do not support\n");
error_correcting_mode = ((dcs_frame[6] & DISBIT3) != 0);
//v17_rx_restart(&v17, fallback_sequence[fallback_entry].bit_rate, FALSE);
return 0;
}
/*- End of function --------------------------------------------------------*/
@ -298,6 +297,7 @@ static void t4_begin(void)
t4_rx_start_page(&t4_rx_state);
t4_up = TRUE;
end_of_page_detected = FALSE;
for (i = 0; i < 256; i++)
ecm_len[i] = -1;
@ -381,7 +381,9 @@ static void v17_put_bit(void *user_data, int bit)
if (t4_rx_put_bit(&t4_rx_state, bit))
{
t4_end();
fprintf(stderr, "End of page detected\n");
if (!end_of_page_detected)
fprintf(stderr, "End of page detected\n");
end_of_page_detected = TRUE;
}
}
//printf("V.17 Rx bit %d - %d\n", rx_bits++, bit);
@ -417,7 +419,9 @@ static void v29_put_bit(void *user_data, int bit)
if (t4_rx_put_bit(&t4_rx_state, bit))
{
t4_end();
fprintf(stderr, "End of page detected\n");
if (!end_of_page_detected)
fprintf(stderr, "End of page detected\n");
end_of_page_detected = TRUE;
}
}
//printf("V.29 Rx bit %d - %d\n", rx_bits++, bit);
@ -453,7 +457,9 @@ static void v27ter_put_bit(void *user_data, int bit)
if (t4_rx_put_bit(&t4_rx_state, bit))
{
t4_end();
fprintf(stderr, "End of page detected\n");
if (!end_of_page_detected)
fprintf(stderr, "End of page detected\n");
end_of_page_detected = TRUE;
}
}
//printf("V.27ter Rx bit %d - %d\n", rx_bits++, bit);

View File

@ -216,7 +216,7 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len)
#endif
}
s->in_ptr = 0;
#if defined(HAVE_FFTW3_H)
#if defined(HAVE_FFTW3_H)
fftw_execute(s->p);
#else
fftw_one(s->p, s->in, s->out);
@ -227,7 +227,7 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len)
for (i = 0; i < 512; i++)
{
s->spec_re_plot[2*i] = i*4000.0/512.0;
#if defined(HAVE_FFTW3_H)
#if defined(HAVE_FFTW3_H)
s->spec_re_plot[2*i + 1] = 10.0*log10((s->out[i][0]*s->out[i][0] + s->out[i][1]*s->out[i][1])/(256.0*32768*256.0*32768) + 1.0e-10) + 3.14;
#else
s->spec_re_plot[2*i + 1] = 10.0*log10((s->out[i].re*s->out[i].re + s->out[i].im*s->out[i].im)/(256.0*32768*256.0*32768) + 1.0e-10) + 3.14;
@ -395,7 +395,7 @@ int start_line_model_monitor(int len)
s->w->end();
s->w->show();
#if defined(HAVE_FFTW3_H)
#if defined(HAVE_FFTW3_H)
s->p = fftw_plan_dft_1d(1024, s->in, s->out, FFTW_BACKWARD, FFTW_ESTIMATE);
for (i = 0; i < 1024; i++)
{

View File

@ -31,11 +31,16 @@
#include <string.h>
#include <unistd.h>
#if HAVE_APPLE_OPENGL_FRAMEWORK
#if HAVE_OPENGL_GL_H
# include <OpenGL/gl.h>
#endif
#if HAVE_GLUT_GLUT_H
# include <GLUT/glut.h>
#else
#endif
#if HAVE_GL_GL_H
# include <GL/gl.h>
#endif
#if HAVE_GL_GLUT_H
# include <GL/glut.h>
#endif

View File

@ -103,14 +103,16 @@ set_fs_ver () {
-e "s|\(AC_SUBST(SWITCH_VERSION_MINOR, \[\).*\(\])\)|\1$minor\2|" \
-e "s|\(AC_SUBST(SWITCH_VERSION_MICRO, \[\).*\(\])\)|\1$micro\2|" \
-e "s|\(AC_INIT(\[freeswitch\], \[\).*\(\], BUG-REPORT-ADDRESS)\)|\1$ver\2|" \
-i configure.in
configure.in > configure.in.$$
mv configure.in.$$ configure.in
if [ -n "$rev" ]; then
[ -n "$hrev" ] || hrev="$rev"
sed -e "s|\(AC_SUBST(SWITCH_VERSION_REVISION, \[\).*\(\])\)|\1$rev\2|" \
-e "s|\(AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, \[\).*\(\])\)|\1$hrev\2|" \
-e "s|#\(AC_SUBST(SWITCH_VERSION_REVISION\)|\1|" \
-e "s|#\(AC_SUBST(SWITCH_VERSION_REVISION_HUMAN\)|\1|" \
-i configure.in
configure.in > configure.in.$$
mv configure.in.$$ configure.in
fi
}

View File

@ -285,6 +285,7 @@ struct switch_session_manager {
int ready;
int running;
int busy;
int popping;
};
extern struct switch_session_manager session_manager;

View File

@ -643,6 +643,8 @@ SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_queued_extension(
SWITCH_DECLARE(void) switch_channel_transfer_to_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension);
SWITCH_DECLARE(const char *) switch_channel_get_partner_uuid(switch_channel_t *channel);
SWITCH_DECLARE(switch_hold_record_t *) switch_channel_get_hold_record(switch_channel_t *channel);
SWITCH_DECLARE(void) switch_channel_state_thread_lock(switch_channel_t *channel);
SWITCH_DECLARE(void) switch_channel_state_thread_unlock(switch_channel_t *channel);
SWITCH_END_EXTERN_C
#endif

View File

@ -722,6 +722,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_pool_launch(switch_co
/*!
\brief Signal a session's state machine thread that a state change has occured
*/
SWITCH_DECLARE(switch_mutex_t *) switch_core_session_get_mutex(switch_core_session_t *session);
SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(_In_ switch_core_session_t *session);
SWITCH_DECLARE(void) switch_core_session_signal_state_change(_In_ switch_core_session_t *session);

View File

@ -106,11 +106,20 @@ SWITCH_DECLARE(void) switch_pgsql_free_result(switch_pgsql_result_t **result);
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const char* file, const char *func, int line, switch_pgsql_handle_t *handle);
#define switch_pgsql_finish_results(handle) switch_pgsql_finish_results_real(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, handle)
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql_handle_t *handle, const char *sql, char **err);
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base_detailed(const char *file, const char *func, int line,
switch_pgsql_handle_t *handle, const char *sql, char **err);
#define switch_pgsql_handle_exec_base(handle, sql, err) switch_pgsql_handle_exec_base_detailed(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, handle, sql, err)
SWITCH_DECLARE(switch_pgsql_state_t) switch_pgsql_handle_get_state(switch_pgsql_handle_t *handle);
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec(switch_pgsql_handle_t *handle, const char *sql, char **err);
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err);
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_detailed(const char *file, const char *func, int line,
switch_pgsql_handle_t *handle, const char *sql, char **err);
#define switch_pgsql_handle_exec(handle, sql, err) switch_pgsql_handle_exec_detailed(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, handle, sql, err)
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string_detailed(const char *file, const char *func, int line,
switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err);
#define switch_pgsql_handle_exec_string(handle, sql, resbuf, len, err) switch_pgsql_handle_exec_string_detailed(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, handle, sql, resbuf, len, err)
SWITCH_DECLARE(switch_bool_t) switch_pgsql_available(void);
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLSetAutoCommitAttr(switch_pgsql_handle_t *handle, switch_bool_t on);
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLEndTran(switch_pgsql_handle_t *handle, switch_bool_t commit);
@ -147,6 +156,8 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_callback_exec_detailed
SWITCH_DECLARE(char *) switch_pgsql_handle_get_error(switch_pgsql_handle_t *handle);
SWITCH_DECLARE(int) switch_pgsql_handle_affected_rows(switch_pgsql_handle_t *handle);
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_flush(switch_pgsql_handle_t *handle);
SWITCH_END_EXTERN_C
#endif

View File

@ -1255,6 +1255,7 @@ typedef enum {
CF_NO_CDR,
CF_EARLY_OK,
CF_MEDIA_TRANS,
CF_HOLD_ON_BRIDGE,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
/* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
CF_FLAG_MAX

View File

@ -1389,9 +1389,6 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_time_t t_agent_answered = 0;
switch_time_t t_member_called = atoi(h->member_joined_epoch);
switch_event_t *event = NULL;
char agent_uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
switch_uuid_str(agent_uuid_str, sizeof(agent_uuid_str));
switch_mutex_lock(globals.mutex);
globals.threads++;
@ -1421,7 +1418,6 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-Type", h->agent_type);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-UUID", agent_uuid_str);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name);
@ -1451,7 +1447,6 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "loopback_bowout", "false");
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "loopback_bowout_on_execute", "false");
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "ignore_early_media", "true");
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "origination_uuid", "%s", agent_uuid_str);
switch_channel_process_export(member_channel, NULL, ovars, "cc_export_vars");

View File

@ -695,6 +695,8 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
}
if (cid && channel) {
switch_event_t *event;
switch_channel_set_variable(channel, "original_caller_id_name", switch_core_strdup(pool, profile->caller_id_name));
if (!zstr(cid->src)) {
switch_channel_set_variable(channel, "cidlookup_source", cid->src);
@ -703,6 +705,19 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
switch_channel_set_variable(channel, "cidlookup_area", cid->area);
}
profile->caller_id_name = switch_core_strdup(profile->pool, cid->name);;
if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE) == SWITCH_STATUS_SUCCESS) {
const char *uuid = switch_channel_get_partner_uuid(channel);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Direction", "RECV");
if (uuid) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridged-To", uuid);
}
switch_channel_event_set_data(channel, event);
switch_event_fire(&event);
}
}

View File

@ -2037,7 +2037,9 @@ SWITCH_STANDARD_API(status_function)
duration.sec, duration.sec == 1 ? "" : "s", duration.ms , duration.ms == 1 ? "" : "s", duration.mms,
duration.mms == 1 ? "" : "s", nl);
stream->write_function(stream, "FreeSWITCH is %s%s", switch_core_ready() ? "ready" : "not ready", nl);
stream->write_function(stream, "FreeSWITCH (Version %s) is %s%s", SWITCH_VERSION_FULL_HUMAN,
switch_core_ready() ? "ready" : "not ready", nl);
stream->write_function(stream, "%" SWITCH_SIZE_T_FMT " session(s) since startup%s", switch_core_session_id() - 1, nl);
switch_core_session_ctl(SCSC_LAST_SPS, &last_sps);
switch_core_session_ctl(SCSC_SPS, &sps);

View File

@ -271,7 +271,7 @@ SWITCH_LIMIT_STATUS(limit_status_db)
/* INIT / Config */
static switch_xml_config_string_options_t limit_config_dsn = { NULL, 0, "^pgsql;|[^:]+:[^:]+:.+" };
static switch_xml_config_string_options_t limit_config_dsn = { NULL, 0, "^pgsql|^odbc|^sqlite|[^:]+:[^:]+:.+" };
static switch_xml_config_item_t config_settings[] = {
SWITCH_CONFIG_ITEM("odbc-dsn", SWITCH_CONFIG_STRING, 0, &globals.odbc_dsn, NULL, &limit_config_dsn,

View File

@ -3584,6 +3584,7 @@ static switch_call_cause_t pickup_outgoing_channel(switch_core_session_t *sessio
pickup = outbound_profile->destination_number;
flags |= SOF_NO_LIMITS;
if (!(nsession = switch_core_session_request(pickup_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n");
@ -3921,7 +3922,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
if ((x_params = switch_xml_child(x_user, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *pvar = switch_xml_attr(x_param, "name");
const char *pvar = switch_xml_attr_soft(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (!strcasecmp(pvar, "dial-string")) {
@ -4813,10 +4814,6 @@ static switch_bool_t do_mutex(switch_core_session_t *session, const char *key, s
struct read_frame_data rf = { 0 };
long to_val = 0;
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
return SWITCH_FALSE;
}
switch_mutex_lock(globals.mutex_mutex);
used = switch_channel_test_app_flag_key(key, channel, MUTEX_FLAG_WAIT) || switch_channel_test_app_flag_key(key, channel, MUTEX_FLAG_SET);
@ -4876,19 +4873,12 @@ static switch_bool_t do_mutex(switch_core_session_t *session, const char *key, s
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s mutex %s is busy, waiting...\n", switch_channel_get_name(channel), key);
if (!(feedback = switch_channel_get_variable(channel, "mutex_feedback"))) {
if ((var = switch_channel_get_variable(channel, "ringback"))) {
feedback = switch_core_session_sprintf(session, "tone_stream://%s;loops=-1", var);
} else {
feedback = switch_channel_get_hold_music(channel);
if ((feedback = switch_channel_get_variable(channel, "mutex_feedback"))) {
if (!strcasecmp(feedback, "silence")) {
feedback = "silence_stream://-1";
}
}
if (zstr(feedback) || !strcasecmp(feedback, "silence")) {
feedback = "silence_stream://-1";
}
if ((rf.exten = switch_channel_get_variable(channel, "mutex_orbit_exten"))) {
to_val = 60;
}
@ -4916,7 +4906,16 @@ static switch_bool_t do_mutex(switch_core_session_t *session, const char *key, s
args.user_data = &rf;
while(switch_channel_ready(channel) && switch_channel_test_app_flag_key(key, channel, MUTEX_FLAG_WAIT)) {
switch_status_t st = switch_ivr_play_file(session, NULL, feedback, &args);
switch_status_t st;
if (feedback) {
switch_channel_pre_answer(channel);
st = switch_ivr_play_file(session, NULL, feedback, &args);
} else {
if ((st = switch_ivr_sleep(session, 20, SWITCH_FALSE, NULL)) == SWITCH_STATUS_SUCCESS) {
st = read_frame_callback(session, NULL, &rf);
}
}
if (st != SWITCH_STATUS_SUCCESS) {
break;
@ -5518,7 +5517,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "flush_dtmf", "flush any queued dtmf", "flush any queued dtmf", flush_dtmf_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "hold", "Send a hold message", "Send a hold message", hold_function, HOLD_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "unhold", "Send a un-hold message", "Send a un-hold message", unhold_function, UNHOLD_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "mutex", "block on a call flow only allowing one at a time", "", mutex_function, MUTEX_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "mutex", "block on a call flow only allowing one at a time", "", mutex_function, MUTEX_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "page", "", "", page_function, PAGE_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "transfer", "Transfer a channel", TRANSFER_LONG_DESC, transfer_function, "<exten> [<dialplan> <context>]",
SAF_SUPPORT_NOMEDIA);

View File

@ -1318,7 +1318,7 @@ static switch_call_cause_t lcr_outgoing_channel(switch_core_session_t *session,
switch_event_t *event = NULL;
const char *intrastate = NULL;
const char *intralata = NULL;
switch_core_session_t *mysession = NULL;
switch_core_session_t *mysession = NULL, *locked_session = NULL;
switch_channel_t *channel = NULL;
dest = strdup(outbound_profile->destination_number);
@ -1362,7 +1362,7 @@ static switch_call_cause_t lcr_outgoing_channel(switch_core_session_t *session,
} else if (var_event) {
char *session_uuid = switch_event_get_header(var_event, "ent_originate_aleg_uuid");
if (session_uuid) {
mysession = switch_core_session_locate(session_uuid);
mysession = locked_session = switch_core_session_locate(session_uuid);
}
cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name");
cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number");
@ -1464,8 +1464,8 @@ static switch_call_cause_t lcr_outgoing_channel(switch_core_session_t *session,
if (event) {
switch_event_destroy(&event);
}
if (mysession) {
switch_core_session_rwunlock(mysession);
if (locked_session) {
switch_core_session_rwunlock(locked_session);
}
lcr_destroy(routes.head);
switch_core_destroy_memory_pool(&pool);

View File

@ -50,6 +50,9 @@ static void event_handler(switch_event_t *event)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Delivery Failure\n");
DUMP_EVENT(event);
return;
} else if ( check_failure && switch_false(check_failure) ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SMS Delivery Success\n");
return;
}
@ -392,7 +395,7 @@ static switch_event_t *chatplan_hunt(switch_event_t *event)
static switch_status_t chat_send(switch_event_t *message_event)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_status_t status = SWITCH_STATUS_BREAK;
switch_event_t *exten;
int forwards = 0;
const char *var;
@ -425,19 +428,30 @@ static switch_status_t chat_send(switch_event_t *message_event)
for (hp = exten->headers; hp; hp = hp->next) {
status = switch_core_execute_chat_app(message_event, hp->name, hp->value);
if (!SWITCH_READ_ACCEPTABLE(status)) {
status = SWITCH_STATUS_SUCCESS;
break;
}
}
switch_event_destroy(&exten);
status = SWITCH_STATUS_BREAK;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SMS chatplan no actions found\n");
}
return status;
}
SWITCH_STANDARD_CHAT_APP(system_function)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Executing command: %s\n", data);
if (switch_system(data, SWITCH_TRUE) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Failed to execute command: %s\n", data);
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_CHAT_APP(stop_function)
{
switch_set_flag(message, EF_NO_CHAT_EXEC);
@ -531,6 +545,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sms_load)
SWITCH_ADD_CHAT_APP(chat_app_interface, "set", "set a variable", "set a variable", set_function, "", SCAF_NONE);
SWITCH_ADD_CHAT_APP(chat_app_interface, "send", "send the message as-is", "send the message as-is", send_function, "", SCAF_NONE);
SWITCH_ADD_CHAT_APP(chat_app_interface, "fire", "fire the message", "fire the message", fire_function, "", SCAF_NONE);
SWITCH_ADD_CHAT_APP(chat_app_interface, "system", "execute a system command", "execute a sytem command", system_function, "", SCAF_NONE);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;

View File

@ -2650,6 +2650,45 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
}
static switch_status_t list_profiles(const char *line, const char *cursor, switch_console_callback_match_t **matches)
{
mdl_profile_t *profile = NULL;
switch_hash_index_t *hi;
void *val;
const void *vvar;
switch_console_callback_match_t *my_matches = NULL;
switch_status_t status = SWITCH_STATUS_FALSE;
for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &vvar, NULL, &val);
profile = (mdl_profile_t *) val;
if (!strncmp("dl_logout", line, 9)) {
if (profile->handle) {
switch_console_push_match(&my_matches, profile->name);
}
} else if (!strncmp("dl_login", line, 8)) {
if (!switch_test_flag(profile, TFLAG_IO)) {
char *profile_name = switch_mprintf("profile=%s", profile->name);
switch_console_push_match(&my_matches, profile_name);
free(profile_name);
}
} else if (!strncmp("dl_pres", line, 7)) {
if (profile->user_flags & LDL_FLAG_COMPONENT) {
switch_console_push_match(&my_matches, profile->name);
}
} else {
switch_console_push_match(&my_matches, profile->name);
}
}
if (my_matches) {
*matches = my_matches;
status = SWITCH_STATUS_SUCCESS;
}
return status;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load)
{
switch_chat_interface_t *chat_interface;
@ -2726,6 +2765,15 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load)
SWITCH_ADD_API(api_interface, "dingaling", "DingaLing Menu", dingaling, DINGALING_SYNTAX);
SWITCH_ADD_CHAT(chat_interface, MDL_CHAT_PROTO, chat_send);
switch_console_set_complete("add dl_debug ::[true:false");
switch_console_set_complete("add dl_pres ::dingaling::list_profiles");
switch_console_set_complete("add dl_logout ::dingaling::list_profiles");
switch_console_set_complete("add dl_login ::dingaling::list_profiles");
switch_console_set_complete("add dl_login login=");
switch_console_set_complete("add dingaling status");
switch_console_set_complete("add dingaling reload");
switch_console_add_complete_func("::dingaling::list_profiles", list_profiles);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
@ -3042,7 +3090,7 @@ SWITCH_STANDARD_API(dingaling)
SWITCH_STANDARD_API(dl_login)
{
char *argv[10] = { 0 };
char *argv[20] = { 0 };
int argc = 0;
char *var, *val, *myarg = NULL;
mdl_profile_t *profile = NULL;
@ -3064,12 +3112,6 @@ SWITCH_STANDARD_API(dl_login)
argc = switch_separate_string(myarg, ';', argv, (sizeof(argv) / sizeof(argv[0])));
if (zstr(cmd) || argc != 1) {
stream->write_function(stream, "USAGE: %s\n", LOGIN_SYNTAX);
status = SWITCH_STATUS_SUCCESS;
goto done;
}
if (argv[0] && !strncasecmp(argv[0], "profile=", 8)) {
char *profile_name = argv[0] + 8;
profile = switch_core_hash_find(globals.profile_hash, profile_name);

View File

@ -0,0 +1,9 @@
This patch (updated to be applied today) was sent via Jira by royj@yandex.ru, with Jira issue FS-4338.
Apply in this way:
# patch -p6 < FREEBSD_patch.diff
I have not tested it, but it works for him.
Please open another Jira issue if anything wrong.
-giovanni

View File

@ -0,0 +1,171 @@
diff --git a/src/mod/endpoints/mod_gsmopen/Makefile b/src/mod/endpoints/mod_gsmopen/Makefile
index 18943c8..5324c52 100644
--- a/src/mod/endpoints/mod_gsmopen/Makefile
+++ b/src/mod/endpoints/mod_gsmopen/Makefile
@@ -1,5 +1,5 @@
MODNAME=mod_gsmopen
-LOCAL_CFLAGS += -I../../../../libs/spandsp/src -I../../../..//libs/tiff-4.0.2/libtiff -DGSMOPEN_C_VER=\"`git log -1 --format="%h" gsmopen_protocol.cpp`\" -DMODGSMOPEN_C_VER=\"`git log -1 --format="%h" mod_gsmopen.cpp`\"
+LOCAL_CFLAGS += -I/usr/local/include -I../../../../libs/spandsp/src -I../../../..//libs/tiff-4.0.2/libtiff -DGSMOPEN_C_VER=\"`git log -1 --format="%h" gsmopen_protocol.cpp`\" -DMODGSMOPEN_C_VER=\"`git log -1 --format="%h" mod_gsmopen.cpp`\"
LOCAL_LDFLAGS=-L../../../../libs/spandsp/src -lspandsp -lctb-0.16 -lgsmme
LOCAL_OBJS=gsmopen_protocol.o
include ../../../../build/modmake.rules
diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp
index 5bdda08..73ef93d 100644
--- a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp
+++ b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp
@@ -2356,7 +2356,7 @@ int ucs2_to_utf8(private_t *tech_pvt, char *ucs2_in, char *utf8_out, size_t outb
iconv_t iconv_format;
int iconv_res;
char *outbuf;
- char *inbuf;
+ //char *inbuf;
size_t inbytesleft;
int c;
char stringa[5];
@@ -2376,9 +2376,10 @@ int ucs2_to_utf8(private_t *tech_pvt, char *ucs2_in, char *utf8_out, size_t outb
}
outbuf = utf8_out;
- inbuf = converted;
+ const char *inbuf = converted;
- iconv_format = iconv_open("UTF8", "UCS-2BE");
+ //iconv_format = iconv_open("UTF8", "UCS-2BE");
+ iconv_format = iconv_open("UTF-8", "UCS-2BE");
//iconv_format = iconv_open("UTF8", "UCS2");
if (iconv_format == (iconv_t) -1) {
ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno));
@@ -2417,12 +2418,12 @@ int utf8_to_iso_8859_1(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, c
iconv_t iconv_format;
int iconv_res;
char *outbuf;
- char *inbuf;
+ //char *inbuf;
outbuf = iso_8859_1_out;
- inbuf = utf8_in;
+ const char *inbuf = utf8_in;
- iconv_format = iconv_open("ISO_8859-1", "UTF8");
+ iconv_format = iconv_open("ISO_8859-1", "UTF-8");
if (iconv_format == (iconv_t) -1) {
ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno));
return -1;
@@ -2467,7 +2468,7 @@ int iso_8859_1_to_utf8(private_t *tech_pvt, char *iso_8859_1_in, char *utf8_out,
iconv_t iconv_format;
int iconv_res;
char *outbuf;
- char *inbuf;
+ //char *inbuf;
size_t inbytesleft;
//int c;
//char stringa[5];
@@ -2477,9 +2478,9 @@ int iso_8859_1_to_utf8(private_t *tech_pvt, char *iso_8859_1_in, char *utf8_out,
DEBUGA_GSMOPEN("iso_8859_1_in=%s\n", GSMOPEN_P_LOG, iso_8859_1_in);
outbuf = utf8_out;
- inbuf = iso_8859_1_in;
+ const char *inbuf = iso_8859_1_in;
- iconv_format = iconv_open("UTF8", "ISO_8859-1");
+ iconv_format = iconv_open("UTF-8", "ISO_8859-1");
if (iconv_format == (iconv_t) -1) {
ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno));
return -1;
@@ -2514,7 +2515,7 @@ int utf8_to_ucs2(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *u
iconv_t iconv_format;
int iconv_res;
char *outbuf;
- char *inbuf;
+ //char *inbuf;
char converted[16000];
int i;
char stringa[16];
@@ -2523,9 +2524,9 @@ int utf8_to_ucs2(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *u
memset(converted, '\0', sizeof(converted));
outbuf = converted;
- inbuf = utf8_in;
+ const char *inbuf = utf8_in;
- iconv_format = iconv_open("UCS-2BE", "UTF8");
+ iconv_format = iconv_open("UCS-2BE", "UTF-8");
if (iconv_format == (iconv_t) -1) {
ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno));
return -1;
diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h
index d88528b..f8851cc 100644
--- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h
+++ b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h
@@ -10,7 +10,7 @@
/////////////////////////////////////////////////////////////////////////////
#include "ctb-0.16/serportx.h"
-#include <linux/serial.h>
+//#include <linux/serial.h>
#include <termios.h>
namespace ctb {
@@ -40,7 +40,7 @@ namespace ctb {
need the errors during a active connection, we must save the actual
error numbers in this separate structurs.
*/
- struct serial_icounter_struct save_info, last_info;
+ //struct serial_icounter_struct save_info, last_info;
/*!
\brief adaptor member function, to convert the plattform independent
diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp
index a369abc..d190567 100644
--- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp
+++ b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp
@@ -136,7 +136,7 @@ namespace ctb {
//
int SerialPort::Ioctl(int cmd, void* args)
{
- int count = 0;
+ /* int count = 0;
int err = 0;
struct serial_icounter_struct info;
SerialPort_EINFO einfo;
@@ -184,7 +184,8 @@ namespace ctb {
return -1;
}
last_info = info;
- return 0;
+ return 0;*/
+ return -1;
};
int SerialPort::IsOpen()
@@ -292,9 +293,9 @@ namespace ctb {
// request the actual numbers of breaks, framing, overrun
// and parity errors (because Linux summing all of them during
// system lifetime, not only while serial port is open.
- ioctl(fd,TIOCGICOUNT,&save_info);
+ //ioctl(fd,TIOCGICOUNT,&save_info);
// it's also careless, but we assume, that there was no error
- last_info = save_info;
+ //last_info = save_info;
// in case of a non-standard rate, the termios struct have to set
// with the B38400 rate, see above!
@@ -359,7 +360,7 @@ namespace ctb {
int SerialPort::SetBaudrateAny( int baudrate )
{
- struct serial_struct ser_info;
+ /* struct serial_struct ser_info;
int result = ioctl( fd, TIOCGSERIAL, &ser_info );
@@ -369,7 +370,8 @@ namespace ctb {
result = ioctl( fd, TIOCSSERIAL, &ser_info );
- return result;
+ return result;*/
+ return -1;
}
int SerialPort::SetBaudrateStandard( int baudrate )

View File

@ -331,7 +331,7 @@ struct private_object {
unsigned long ib_failed_calls;
unsigned long ob_failed_calls;
char controldevice_name[50]; /*!< \brief name of the serial device controlling the interface, possibly none */
char controldevice_name[512]; /*!< \brief name of the serial device controlling the interface, possibly none */
int controldevprotocol; /*!< \brief which protocol is used for serial control of this interface */
char controldevprotocolname[50]; /*!< \brief name of the serial device controlling protocol, one of "at" "fbus2" "no_serial" "alsa_voicemodem" */
int controldevfd; /*!< \brief serial controlling file descriptor for this interface */
@ -469,7 +469,7 @@ struct private_object {
int network_creg_not_supported;
char creg[128];
char controldevice_audio_name[50];
char controldevice_audio_name[512];
int controldev_audio_fd;
int controldevice_audio_speed;
int controldev_audio_dead;

View File

@ -2189,7 +2189,7 @@ int gsmopen_serial_write_AT_expect1(private_t *tech_pvt, const char *data, const
return -1;
}
at_result = gsmopen_serial_read_AT(tech_pvt, 1, 100000, seconds, expected_string, expect_crlf); // minimum 1/10th sec timeout
at_result = gsmopen_serial_read_AT(tech_pvt, 1, 500000, seconds, expected_string, expect_crlf); // minimum half a sec timeout
UNLOCKA(tech_pvt->controldev_lock);
POPPA_UNLOCKA(tech_pvt->controldev_lock);
@ -2700,6 +2700,8 @@ int gsmopen_hangup(private_t *tech_pvt)
int gsmopen_call(private_t *tech_pvt, char *rdest, int timeout)
{
int result;
//gsmopen_sleep(5000);
DEBUGA_GSMOPEN("Calling GSM, rdest is: %s\n", GSMOPEN_P_LOG, rdest);
//gsmopen_signaling_write(tech_pvt, "SET AGC OFF");
@ -2707,11 +2709,11 @@ int gsmopen_call(private_t *tech_pvt, char *rdest, int timeout)
//gsmopen_signaling_write(tech_pvt, "SET AEC OFF");
//gsmopen_sleep(10000);
gsmopen_serial_call(tech_pvt, rdest);
result=gsmopen_serial_call(tech_pvt, rdest);
//ERRORA("failed to communicate with GSM client, now exit\n", GSMOPEN_P_LOG);
//return -1;
//}
return 0;
return result;
}
int gsmopen_senddigit(private_t *tech_pvt, char digit)

View File

@ -160,6 +160,9 @@ rpcrt4.lib "..\..\..\..\debug\libtiff.lib" "..\..\..\..\libs\spandsp\src\debug\
<ClCompile Include="mod_gsmopen.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\w32\Library\FreeSwitchCore.2010.vcxproj">
<Project>{202d7a4e-760d-4d0e-afa1-d7459ced30ff}</Project>
</ProjectReference>
<ProjectReference Include="gsmlib\gsmlib-1.10-patched-13ubuntu\win32\gsmlib.2010.vcxproj">
<Project>{26c82fce-e0cf-4d10-a00c-d8e582ffeb53}</Project>
</ProjectReference>

View File

@ -1054,7 +1054,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
switch_call_cause_t *cancel_cause)
{
private_t *tech_pvt = NULL;
if ((*new_session = switch_core_session_request(gsmopen_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) {
int result;
if ((*new_session = switch_core_session_request_uuid(gsmopen_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool, switch_event_get_header(var_event, "origination_uuid"))) != 0) {
switch_channel_t *channel = NULL;
switch_caller_profile_t *caller_profile;
char *rdest;
@ -1171,8 +1174,11 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
switch_mutex_unlock(tech_pvt->flag_mutex);
switch_channel_set_state(channel, CS_INIT);
gsmopen_call(tech_pvt, rdest, 30);
result=gsmopen_call(tech_pvt, rdest, 30);
switch_mutex_unlock(globals.mutex);
if(result != 0){
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
return SWITCH_CAUSE_SUCCESS;
}
@ -1217,6 +1223,14 @@ static switch_status_t load_config(int reload_type)
}
switch_mutex_lock(globals.mutex);
set_global_dialplan("XML");
DEBUGA_GSMOPEN("Default globals.dialplan=%s\n", GSMOPEN_P_LOG, globals.dialplan);
set_global_destination("5000");
DEBUGA_GSMOPEN("Default globals.destination=%s\n", GSMOPEN_P_LOG, globals.destination);
set_global_context("default");
DEBUGA_GSMOPEN("Default globals.context=%s\n", GSMOPEN_P_LOG, globals.context);
if ((global_settings = switch_xml_child(cfg, "global_settings"))) {
for (param = switch_xml_child(global_settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@ -1250,16 +1264,16 @@ static switch_status_t load_config(int reload_type)
for (myinterface = switch_xml_child(interfaces, "interface"); myinterface; myinterface = myinterface->next) {
char *id = (char *) switch_xml_attr(myinterface, "id");
char *name = (char *) switch_xml_attr(myinterface, "name");
const char *context = "default";
const char *dialplan = "XML";
const char *destination = "5000";
const char *context = globals.context;
const char *dialplan = globals.dialplan;
const char *destination = globals.destination;
const char *controldevice_name = "/dev/ttyUSB3";
const char *controldevice_audio_name = "/dev/ttyUSB2";
char *digit_timeout = NULL;
char *max_digits = NULL;
char *hotline = NULL;
char *dial_regex = NULL;
char *hold_music = NULL;
char *hold_music = globals.hold_music;
char *fail_dial_regex = NULL;
const char *enable_callerid = "true";

View File

@ -709,10 +709,26 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
return status;
}
static void switch_channel_wait_for_state_or_greater(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state)
{
switch_assert(channel);
for (;;) {
if ((switch_channel_get_state(channel) < CS_HANGUP &&
switch_channel_get_state(channel) == switch_channel_get_running_state(channel) && switch_channel_get_running_state(channel) >= want_state) ||
(other_channel && switch_channel_down_nosig(other_channel)) || switch_channel_down(channel)) {
break;
}
switch_cond_next();
}
}
static switch_status_t find_non_loopback_bridge(switch_core_session_t *session, switch_core_session_t **br_session, const char **br_uuid)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
const char *a_uuid;
const char *a_uuid = NULL;
switch_core_session_t *sp;
*br_session = NULL;
@ -722,9 +738,17 @@ static switch_status_t find_non_loopback_bridge(switch_core_session_t *session,
while (a_uuid && (sp = switch_core_session_locate(a_uuid))) {
if (switch_core_session_check_interface(sp, loopback_endpoint_interface)) {
private_t *tech_pvt = switch_core_session_get_private(sp);
private_t *tech_pvt;
switch_channel_t *spchan = switch_core_session_get_channel(sp);
switch_channel_wait_for_state_or_greater(spchan, channel, CS_ROUTING);
tech_pvt = switch_core_session_get_private(sp);
if (tech_pvt->other_channel) {
a_uuid = switch_channel_get_partner_uuid(tech_pvt->other_channel);
}
a_uuid = switch_channel_get_partner_uuid(tech_pvt->other_channel);
switch_core_session_rwunlock(sp);
sp = NULL;
} else {
@ -783,9 +807,10 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
switch_channel_t *ch_a = NULL, *ch_b = NULL;
int good_to_go = 0;
switch_mutex_unlock(tech_pvt->mutex);
find_non_loopback_bridge(session, &br_a, &a_uuid);
find_non_loopback_bridge(tech_pvt->other_session, &br_b, &b_uuid);
switch_mutex_lock(tech_pvt->mutex);
if (br_a) {

View File

@ -191,7 +191,7 @@ static switch_status_t interface_exists(char *the_interface);
static switch_status_t channel_on_init(switch_core_session_t *session);
static switch_status_t channel_on_hangup(switch_core_session_t *session);
static switch_status_t channel_on_reset(switch_core_session_t *session);
//static switch_status_t channel_on_reset(switch_core_session_t *session);
static switch_status_t channel_on_destroy(switch_core_session_t *session);
static switch_status_t channel_on_routing(switch_core_session_t *session);
static switch_status_t channel_on_exchange_media(switch_core_session_t *session);
@ -645,7 +645,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
}
//DEBUGA_SKYPE("debugging_hangup 12\n", SKYPOPEN_P_LOG);
switch_channel_set_state(channel, CS_DESTROY);
//switch_channel_set_state(channel, CS_DESTROY);
return SWITCH_STATUS_SUCCESS;
}
@ -766,6 +766,7 @@ static switch_status_t channel_on_soft_execute(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
#if 0
static switch_status_t channel_on_reset(switch_core_session_t *session)
{
private_t *tech_pvt = NULL;
@ -788,6 +789,7 @@ static switch_status_t channel_on_reset(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
#endif //0
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
@ -1238,7 +1240,7 @@ switch_state_handler_table_t skypopen_state_handlers = {
/*.on_soft_execute */ channel_on_soft_execute,
/*.on_consume_media */ channel_on_consume_media,
/*.on_hibernate */ NULL,
/*.on_reset */ channel_on_reset,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ NULL,
/*.on_destroy */ channel_on_destroy
@ -2729,6 +2731,8 @@ int skypopen_partner_handle_ring(private_t *tech_pvt)
if (tech_pvt && tech_pvt->ringing_state == SKYPOPEN_RINGING_INIT) {
/* we are not inside an active call */
switch_channel_t *channel = NULL;
tech_pvt->interface_state = SKYPOPEN_STATE_PRERING;
gettimeofday(&tech_pvt->ring_time, NULL);
switch_copy_string(tech_pvt->callid_number, value, sizeof(tech_pvt->callid_number) - 1);
@ -2741,6 +2745,22 @@ int skypopen_partner_handle_ring(private_t *tech_pvt)
new_inbound_channel(tech_pvt);
switch_sleep(10000);
session = switch_core_session_locate(tech_pvt->session_uuid_str);
if (session) {
channel = switch_core_session_get_channel(session);
switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING);
if (channel) {
switch_channel_mark_ring_ready(channel);
DEBUGA_SKYPE("switch_channel_mark_ring_ready(channel);\n", SKYPOPEN_P_LOG);
} else {
ERRORA("no channel\n", SKYPOPEN_P_LOG);
}
switch_core_session_rwunlock(session);
} else {
ERRORA("no session\n", SKYPOPEN_P_LOG);
}
} else if (!tech_pvt || !tech_pvt->skype_call_id) {
ERRORA("No Call ID?\n", SKYPOPEN_P_LOG);
} else {

View File

@ -522,7 +522,15 @@ int skypopen_signaling_read(private_t *tech_pvt)
sprintf(msg_to_skype, "SET CHATMESSAGE %s SEEN", id);
skypopen_signaling_write(tech_pvt, msg_to_skype);
} else {
DEBUGA_SKYPE
("CHATMESSAGE %s is in position %d in the chatmessages array, type=%s, id=%s, chatname=%s, from_handle=%s, from_dispname=%s, body=%s NOT DELETED\n",
SKYPOPEN_P_LOG, id, i, tech_pvt->chatmessages[i].type, tech_pvt->chatmessages[i].id, tech_pvt->chatmessages[i].chatname,
tech_pvt->chatmessages[i].from_handle, tech_pvt->chatmessages[i].from_dispname, tech_pvt->chatmessages[i].body);
memset(&tech_pvt->chatmessages[i], '\0', sizeof(&tech_pvt->chatmessages[i]));
DEBUGA_SKYPE("chatmessage %s HAS BEEN DELETED\n", SKYPOPEN_P_LOG, id);
}
}
}
@ -631,6 +639,53 @@ int skypopen_signaling_read(private_t *tech_pvt)
//skypopen_sleep(10000);
}
if (!strcasecmp(prop, "VM_DURATION") && (!strcasecmp(value, "0"))) {
char msg_to_skype[1024];
NOTICA("We called a Skype contact and he started Skype voicemail on our skype_call: %s.\n", SKYPOPEN_P_LOG, id);
if (!strlen(tech_pvt->session_uuid_str)) {
DEBUGA_SKYPE("no tech_pvt->session_uuid_str\n", SKYPOPEN_P_LOG);
}
if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
if (!strlen(tech_pvt->session_uuid_str) || !strlen(tech_pvt->skype_call_id)
|| !strcasecmp(tech_pvt->skype_call_id, id)) {
skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPOPEN_P_LOG, id);
if (tech_pvt->skype_callflow != CALLFLOW_STATUS_EARLYMEDIA) {
tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS;
tech_pvt->interface_state = SKYPOPEN_STATE_UP;
if (tech_pvt->tcp_cli_thread == NULL) {
DEBUGA_SKYPE("START start_audio_threads\n", SKYPOPEN_P_LOG);
if (start_audio_threads(tech_pvt)) {
WARNINGA("start_audio_threads FAILED\n", SKYPOPEN_P_LOG);
return CALLFLOW_INCOMING_HANGUP;
}
}
//skypopen_sleep(1000);
sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id, tech_pvt->tcp_cli_port);
skypopen_signaling_write(tech_pvt, msg_to_skype);
//skypopen_sleep(1000);
sprintf(msg_to_skype, "#output ALTER CALL %s SET_OUTPUT PORT=\"%d\"", id, tech_pvt->tcp_srv_port);
skypopen_signaling_write(tech_pvt, msg_to_skype);
}
tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS;
if (skypopen_answered(tech_pvt) != SWITCH_STATUS_SUCCESS) {
sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id);
skypopen_signaling_write(tech_pvt, msg_to_skype);
}
} else {
DEBUGA_SKYPE("I'm on %s, skype_call %s is NOT MY call, ignoring\n", SKYPOPEN_P_LOG, tech_pvt->skype_call_id, id);
}
} else {
tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS;
DEBUGA_SKYPE("Back from REMOTEHOLD!\n", SKYPOPEN_P_LOG);
}
}
if (!strcasecmp(prop, "STATUS")) {
if (!strcasecmp(value, "RINGING")) {
@ -833,6 +888,8 @@ int skypopen_signaling_read(private_t *tech_pvt)
tech_pvt->skype_call_id[0] = '\0';
//skypopen_sleep(1000);
return CALLFLOW_INCOMING_HANGUP;
} else if (!strncmp(value, "VM_", 2)) {
DEBUGA_SKYPE ("Our skype_call %s is in Skype voicemail: %s\n", SKYPOPEN_P_LOG, id, value);
} else {
WARNINGA("skype_call: %s, STATUS: %s is not recognized\n", SKYPOPEN_P_LOG, id, value);
}

View File

@ -262,12 +262,14 @@ char *generate_pai_str(private_object_t *tech_pvt)
return NULL;
}
if (zstr((callee_name = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_name"))) &&
if (zstr((callee_name = switch_channel_get_variable(tech_pvt->channel, "initial_callee_id_name"))) &&
zstr((callee_name = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_name"))) &&
zstr((callee_name = switch_channel_get_variable(tech_pvt->channel, "sip_callee_id_name")))) {
callee_name = switch_channel_get_variable(tech_pvt->channel, "callee_id_name");
}
if (zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_number"))) &&
if (zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "initial_callee_id_number"))) &&
zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_number"))) &&
zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "sip_callee_id_number"))) &&
zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "callee_id_number")))) {
@ -2024,10 +2026,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
nua_ack(tech_pvt->nh,
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SOATAG_USER_SDP_STR(msg->string_arg),
SOATAG_REUSE_REJECTED(1),
SOATAG_RTP_SELECT(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
SIPTAG_PAYLOAD_STR(msg->string_arg),
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
TAG_END());
sofia_clear_flag(tech_pvt, TFLAG_3PCC_INVITE);
@ -2456,25 +2456,31 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
case SWITCH_MESSAGE_INDICATE_HOLD:
{
sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
switch_channel_set_flag(channel, CF_LEG_HOLDING);
sofia_glue_do_invite(session);
if (!zstr(msg->string_arg)) {
char message[256] = "";
const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent");
if (ua && switch_stristr("snom", ua)) {
snprintf(message, sizeof(message), "From:\r\nTo: \"%s\" %s\r\n", msg->string_arg, tech_pvt->caller_profile->destination_number);
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_PAYLOAD_STR(message), TAG_END());
} else if (ua && switch_stristr("polycom", ua)) {
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", msg->string_arg, tech_pvt->caller_profile->destination_number);
nua_update(tech_pvt->nh,
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
if (msg->numeric_arg) {
sofia_glue_toggle_hold(tech_pvt, 1);
} else {
sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
switch_channel_set_flag(channel, CF_LEG_HOLDING);
sofia_glue_do_invite(session);
if (!zstr(msg->string_arg)) {
char message[256] = "";
const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent");
if (ua && switch_stristr("snom", ua)) {
snprintf(message, sizeof(message), "From:\r\nTo: \"%s\" %s\r\n", msg->string_arg, tech_pvt->caller_profile->destination_number);
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_PAYLOAD_STR(message), TAG_END());
} else if (ua && switch_stristr("polycom", ua)) {
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", msg->string_arg, tech_pvt->caller_profile->destination_number);
nua_update(tech_pvt->nh,
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
}
}
}
}

View File

@ -389,6 +389,7 @@ struct mod_sofia_globals {
int tracelevel;
char *capture_server;
int rewrite_multicasted_fs_path;
int presence_flush;
};
extern struct mod_sofia_globals mod_sofia_globals;
@ -694,6 +695,7 @@ struct sofia_profile {
int ireg_seconds;
sofia_paid_type_t paid_type;
uint32_t rtp_digit_delay;
switch_queue_t *event_queue;
};
struct private_object {
@ -1013,6 +1015,7 @@ void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t
void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex);
void sofia_glue_actually_execute_sql_trans(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex);
void sofia_glue_execute_sql_now(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic);
void sofia_glue_execute_sql_soon(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic);
void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot);
void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now);
void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now);
@ -1206,6 +1209,8 @@ int sofia_recover_callback(switch_core_session_t *session);
void sofia_glue_set_name(private_object_t *tech_pvt, const char *channame);
private_object_t *sofia_glue_new_pvt(switch_core_session_t *session);
switch_status_t sofia_init(void);
void sofia_glue_fire_events(sofia_profile_t *profile);
void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event);
/* For Emacs:
* Local Variables:

View File

@ -1502,6 +1502,10 @@ static void our_sofia_event_callback(nua_event_t event,
nua_handle_bind(nh, NULL);
}
if (tech_pvt && (tech_pvt->nh == nh)) {
tech_pvt->nh = NULL;
}
nua_handle_destroy(nh);
nh = NULL;
}
@ -1555,7 +1559,7 @@ void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep)
{
sofia_dispatch_event_t *de = *dep;
switch_memory_pool_t *pool;
sofia_profile_t *profile = (*dep)->profile;
//sofia_profile_t *profile = (*dep)->profile;
switch_thread_data_t *td;
switch_core_new_memory_pool(&pool);
@ -1567,45 +1571,10 @@ void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep)
td->func = sofia_msg_thread_run_once;
td->obj = de;
switch_mutex_lock(profile->ireg_mutex);
switch_thread_pool_launch_thread(&td);
switch_mutex_unlock(profile->ireg_mutex);
}
#if 0
void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep)
{
sofia_dispatch_event_t *de = *dep;
switch_threadattr_t *thd_attr = NULL;
switch_memory_pool_t *pool;
switch_thread_t *thread;
sofia_profile_t *profile = (*dep)->profile;
switch_status_t status;
switch_core_new_memory_pool(&pool);
*dep = NULL;
de->pool = pool;
switch_mutex_lock(profile->ireg_mutex);
switch_threadattr_create(&thd_attr, de->pool);
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
status = switch_thread_create(&thread,
thd_attr,
sofia_msg_thread_run_once,
de,
de->pool);
switch_mutex_unlock(profile->ireg_mutex);
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot create threads!\n");
sofia_process_dispatch_event(&de);
}
}
#endif
void sofia_process_dispatch_event(sofia_dispatch_event_t **dep)
{
sofia_dispatch_event_t *de = *dep;
@ -1988,6 +1957,7 @@ void sofia_event_callback(nua_event_t event,
sofia_queue_message(de);
end:
//switch_cond_next();
return;
}
@ -2129,7 +2099,7 @@ void event_handler(switch_event_t *event)
contact_str = fixed_contact_str;
}
switch_mutex_lock(profile->ireg_mutex);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL, AF_INET);
@ -2146,7 +2116,7 @@ void event_handler(switch_event_t *event)
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s\n", from_user, from_host, contact_str);
}
switch_mutex_unlock(profile->ireg_mutex);
if (profile) {
sofia_glue_release_profile(profile);
@ -2489,6 +2459,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
#ifdef MANUAL_BYE
NUTAG_APPL_METHOD("BYE"),
#endif
NUTAG_APPL_METHOD("MESSAGE"),
NUTAG_SESSION_TIMER(profile->session_timeout),
NTATAG_MAX_PROCEEDING(profile->max_proceeding),
@ -2553,11 +2524,13 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
switch_mutex_init(&profile->gateway_mutex, SWITCH_MUTEX_NESTED, profile->pool);
switch_queue_create(&profile->event_queue, SOFIA_QUEUE_SIZE, profile->pool);
switch_snprintf(qname, sizeof(qname), "sofia:%s", profile->name);
switch_sql_queue_manager_init_name(qname,
&profile->qm,
1,
2,
profile->odbc_dsn ? profile->odbc_dsn : profile->dbname,
SWITCH_MAX_TRANS,
profile->pre_trans_execute,
@ -4841,7 +4814,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_refuse");
}
if (status >= 500 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
if (status >= 400 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
|| !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
|| !strcasecmp(sip->sip_reason->re_protocol, profile->username)) && sip->sip_reason->re_cause) {
tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
@ -6758,10 +6731,12 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
if ((a_session = switch_core_session_locate(br_a))) {
const char *moh = profile->hold_music;
switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
switch_caller_profile_t *prof = switch_channel_get_caller_profile(channel_b);
const char *tmp;
switch_core_event_hook_add_state_change(a_session, xfer_hanguphook);
switch_channel_set_variable(a_channel, "att_xfer_kill_uuid", switch_core_session_get_uuid(b_session));
switch_channel_set_variable(a_channel, "att_xfer_destination_number", prof->destination_number);
if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER) {
switch_channel_set_flag(a_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE);

View File

@ -6373,7 +6373,7 @@ void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t
switch_assert(sqlp && *sqlp);
sql = *sqlp;
switch_sql_queue_manager_push(profile->qm, sql, 0, !sql_already_dynamic);
switch_sql_queue_manager_push(profile->qm, sql, 1, !sql_already_dynamic);
if (sql_already_dynamic) {
*sqlp = NULL;
@ -6395,6 +6395,20 @@ void sofia_glue_execute_sql_now(sofia_profile_t *profile, char **sqlp, switch_bo
}
}
void sofia_glue_execute_sql_soon(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic)
{
char *sql;
switch_assert(sqlp && *sqlp);
sql = *sqlp;
switch_sql_queue_manager_push(profile->qm, sql, 0, !sql_already_dynamic);
if (sql_already_dynamic) {
*sqlp = NULL;
}
}
switch_cache_db_handle_t *_sofia_glue_get_db_handle(sofia_profile_t *profile, const char *file, const char *func, int line)
{
@ -6498,6 +6512,9 @@ switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile,
switch_cache_db_release_db_handle(&dbh);
sofia_glue_fire_events(profile);
return ret;
}
@ -6529,6 +6546,9 @@ char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex
switch_cache_db_release_db_handle(&dbh);
sofia_glue_fire_events(profile);
return ret;
}
@ -7139,6 +7159,23 @@ char *sofia_glue_get_host(const char *str, switch_memory_pool_t *pool)
return s;
}
void sofia_glue_fire_events(sofia_profile_t *profile)
{
void *pop = NULL;
while (profile->event_queue && switch_queue_trypop(profile->event_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
switch_event_t *event = (switch_event_t *) pop;
switch_event_fire(&event);
}
}
void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event)
{
switch_queue_push(profile->event_queue, *event);
*event = NULL;
}
/* For Emacs:
* Local Variables:

View File

@ -364,7 +364,9 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
if (!(mstatus > 199 && mstatus < 300)) {
status = SWITCH_STATUS_FALSE;
}
switch_event_add_header(message_event, SWITCH_STACK_BOTTOM, "Delivery-Result-Code", "%d", mstatus);
switch_mutex_lock(profile->flag_mutex);
switch_core_hash_delete(profile->chat_hash, uuid_str);
switch_mutex_unlock(profile->flag_mutex);
@ -1027,7 +1029,7 @@ static void conference_data_event_handler(switch_event_t *event)
switch_safe_free(dup_domain);
}
static void actual_sofia_presence_event_handler(switch_event_t *event)
static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event)
{
sofia_profile_t *profile = NULL;
char *from = switch_event_get_header(event, "from");
@ -1047,10 +1049,10 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
switch_console_callback_match_t *matches;
struct presence_helper helper = { 0 };
int hup = 0;
switch_event_t *s_event = NULL;
if (!mod_sofia_globals.running) {
return;
goto done;
}
if (zstr(proto) || !strcasecmp(proto, "any")) {
@ -1091,7 +1093,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
if (!mod_sofia_globals.profile_hash) {
return;
goto done;
}
if (from) {
@ -1171,7 +1173,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
}
switch_safe_free(sql);
return;
goto done;
}
if (zstr(event_type)) {
@ -1195,7 +1197,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
}
} else {
switch_safe_free(user);
return;
goto done;
}
if ((euser = strchr(user, '+'))) {
euser++;
@ -1203,7 +1205,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
euser = user;
}
} else {
return;
goto done;
}
switch (event->event_id) {
@ -1348,7 +1350,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
}
if (zstr(call_id)) {
sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and "
"sip_subscriptions.event != 'line-seize' "
"and sip_subscriptions.proto='%q' and (event='%q' or event='%q') and sub_to_user='%q' and "
@ -1364,8 +1366,8 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sofia_glue_execute_sql_soon(profile, &sql, SWITCH_TRUE);
sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
@ -1374,7 +1376,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
"sip_subscriptions.accept,sip_subscriptions.profile_name"
",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q',"
"sip_subscriptions.version, '%q',sip_subscriptions.orig_proto,sip_subscriptions.full_to,"
"sip_subscriptions.version+1, '%q',sip_subscriptions.orig_proto,sip_subscriptions.full_to,"
"sip_subscriptions.network_ip, sip_subscriptions.network_port "
"from sip_subscriptions "
"left join sip_presence on "
@ -1393,6 +1395,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
event_type, alt_event_type, euser, host, profile->sipip,
profile->extsipip ? profile->extsipip : "N/A", host);
} else {
sql = switch_mprintf("update sip_subscriptions set version=version+1 where sip_subscriptions.event != 'line-seize' and "
"hostname='%q' and profile_name = '%q' and sip_subscriptions.call_id='%q'",
mod_sofia_globals.hostname, profile->name, call_id);
@ -1402,7 +1405,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sofia_glue_execute_sql_soon(profile, &sql, SWITCH_TRUE);
sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
@ -1411,7 +1414,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
"sip_subscriptions.accept,sip_subscriptions.profile_name"
",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q',"
"sip_subscriptions.version, '%q',sip_subscriptions.orig_proto,sip_subscriptions.full_to,"
"sip_subscriptions.version+1, '%q',sip_subscriptions.orig_proto,sip_subscriptions.full_to,"
"sip_subscriptions.network_ip, sip_subscriptions.network_port "
"from sip_subscriptions "
"left join sip_presence on "
@ -1459,11 +1462,9 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name);
}
#if 0
if (hup && dh.hits < 1) {
/* so many phones get confused when whe hangup we have to reprobe to get them all to reset to absolute states so the lights stay correct */
switch_event_t *s_event;
if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
@ -1471,10 +1472,10 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", euser, host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
switch_event_fire(&s_event);
sofia_event_fire(profile, &s_event);
}
}
#endif
if (!zstr((char *) helper.stream.data)) {
char *this_sql = (char *) helper.stream.data;
@ -1509,11 +1510,24 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
switch_safe_free(sql);
switch_safe_free(user);
return s_event;
}
static int EVENT_THREAD_RUNNING = 0;
static int EVENT_THREAD_STARTED = 0;
static void do_flush(void)
{
void *pop = NULL;
while (mod_sofia_globals.presence_queue && switch_queue_trypop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
switch_event_t *event = (switch_event_t *) pop;
switch_event_destroy(&event);
}
}
void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread, void *obj)
{
void *pop;
@ -1544,6 +1558,15 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread
break;
}
if (mod_sofia_globals.presence_flush) {
switch_mutex_lock(mod_sofia_globals.mutex);
if (mod_sofia_globals.presence_flush) {
do_flush();
mod_sofia_globals.presence_flush = 0;
}
switch_mutex_unlock(mod_sofia_globals.mutex);
}
switch(event->event_id) {
case SWITCH_EVENT_MESSAGE_WAITING:
actual_sofia_presence_mwi_event_handler(event);
@ -1552,7 +1575,11 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread
conference_data_event_handler(event);
break;
default:
actual_sofia_presence_event_handler(event);
do {
switch_event_t *ievent = event;
event = actual_sofia_presence_event_handler(ievent);
switch_event_destroy(&ievent);
} while (event);
break;
}
@ -1561,10 +1588,7 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread
}
}
while (switch_queue_trypop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
switch_event_t *event = (switch_event_t *) pop;
switch_event_destroy(&event);
}
do_flush();
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Event Thread Ended\n");
@ -1606,13 +1630,23 @@ void sofia_presence_event_handler(switch_event_t *event)
{
switch_event_t *cloned_event;
switch_event_dup(&cloned_event, event);
switch_assert(cloned_event);
switch_queue_push(mod_sofia_globals.presence_queue, cloned_event);
if (!EVENT_THREAD_STARTED) {
sofia_presence_event_thread_start();
switch_yield(500000);
}
switch_event_dup(&cloned_event, event);
switch_assert(cloned_event);
if (switch_queue_trypush(mod_sofia_globals.presence_queue, cloned_event) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Presence queue overloaded.... Flushing queue\n");
switch_mutex_lock(mod_sofia_globals.mutex);
mod_sofia_globals.presence_flush = 1;
switch_mutex_unlock(mod_sofia_globals.mutex);
switch_event_destroy(&cloned_event);
}
}
@ -1640,7 +1674,7 @@ static int sofia_presence_sub_reg_callback(void *pArg, int argc, char **argv, ch
}
switch_event_fire(&event);
sofia_event_fire(profile, &event);
}
return 0;
}
@ -1653,7 +1687,7 @@ static int sofia_presence_sub_reg_callback(void *pArg, int argc, char **argv, ch
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_subtype", "probe");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto-specific-event-name", event_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "expires", expires);
switch_event_fire(&event);
sofia_event_fire(profile, &event);
}
return 0;
@ -1777,7 +1811,7 @@ static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char
}
}
switch_event_fire(&event);
sofia_event_fire(profile, &event);
}
switch_safe_free(free_me);
@ -4320,7 +4354,8 @@ void sofia_presence_handle_sip_i_message(int status,
if ((us = sofia_glue_get_unknown_header(sip, "X-FS-Sending-Message")) && !strcmp(us, switch_core_get_uuid())) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Not sending message to ourselves!\n");
goto end;
nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
return;
}
if (sip->sip_content_type && sip->sip_content_type->c_subtype) {

View File

@ -635,7 +635,7 @@ int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", argv[3]);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "expires", argv[6]);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "user-agent", argv[7]);
switch_event_fire(&s_event);
sofia_event_fire(profile, &s_event);
}
if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
@ -653,7 +653,7 @@ int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Unregistered");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&s_event);
sofia_event_fire(profile, &s_event);
}
}
@ -859,7 +859,6 @@ void sofia_reg_check_sync(sofia_profile_t *profile)
sql = switch_mprintf("delete from sip_registrations where expires > 0 and hostname='%q'", mod_sofia_globals.hostname);
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sql = switch_mprintf("delete from sip_presence where expires > 0 and hostname='%q'", mod_sofia_globals.hostname);
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
@ -2354,6 +2353,8 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
if (zstr(np)) {
nonce_cb_t cb = { 0 };
long nc_long = 0;
int sanity = 0;
first = 1;
if (nc) {
@ -2367,7 +2368,14 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
cb.nplen = nplen;
switch_assert(sql != NULL);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_nonce_callback, &cb);
do {
if (sanity) {
switch_yield(100000 * sanity);
}
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_nonce_callback, &cb);
} while(nc_long < 2 && ++sanity < 10 && zstr(np));
free(sql);
//if (!sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, np, nplen)) {

View File

@ -204,8 +204,8 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
bson_append_start_object(&cdr, "extension");
bson_append_string(&cdr, "name", caller_profile->caller_extension->extension_name);
bson_append_string(&cdr, "number", caller_profile->caller_extension->extension_number);
bson_append_string(&cdr, "name", switch_str_nil(caller_profile->caller_extension->extension_name));
bson_append_string(&cdr, "number", switch_str_nil(caller_profile->caller_extension->extension_number));
if (caller_profile->caller_extension->current_application) {
bson_append_string(&cdr, "current_app", caller_profile->caller_extension->current_application->application_name);

View File

@ -175,13 +175,8 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l
if (switch_queue_trypush(l->log_queue, dnode) == SWITCH_STATUS_SUCCESS) {
if (l->lost_logs) {
int ll = l->lost_logs;
switch_event_t *event;
l->lost_logs = 0;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Lost %d log lines!\n", ll);
if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "info", "lost %d log lines", ll);
switch_event_fire(&event);
}
}
} else {
switch_log_node_free(&dnode);
@ -378,11 +373,6 @@ static void event_handler(switch_event_t *event)
int le = l->lost_events;
l->lost_events = 0;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(l->session), SWITCH_LOG_CRIT, "Lost %d events!\n", le);
clone = NULL;
if (switch_event_create(&clone, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(clone, SWITCH_STACK_BOTTOM, "info", "lost %d events", le);
switch_event_fire(&clone);
}
}
} else {
if (++l->lost_events > MAX_MISSED) {

View File

@ -1161,6 +1161,8 @@ static int web_callback(void *pArg, int argc, char **argv, char **columnNames)
char title_b4[128] = "";
char title_aft[128 * 3 + 1] = "";
char *mp3, *m3u;
int uri_offset = 1;
const char *uuid = argv[0];
const char *created = argv[1];
const char *cid_name = argv[2];
@ -1178,8 +1180,10 @@ static int web_callback(void *pArg, int argc, char **argv, char **columnNames)
snprintf(title_b4, sizeof(title_b4), "%s <%s>", cid_name, cid_num);
switch_url_encode(title_b4, title_aft, sizeof(title_aft));
mp3 = switch_mprintf("http://%s:%s%s/mp3/%s/%s.mp3", holder->host, holder->port, holder->uri, uuid, cid_num);
m3u = switch_mprintf("http://%s:%s%s/m3u/mp3/%s/%s.mp3.m3u", holder->host, holder->port, holder->uri, uuid, cid_num);
if (!strncmp(holder->uri, "/webapi", 7)) uri_offset = 4;
mp3 = switch_mprintf("http://%s:%s/%s/mp3/%s/%s.mp3", holder->host, holder->port, holder->uri + uri_offset, uuid, cid_num);
m3u = switch_mprintf("http://%s:%s/%s/m3u/mp3/%s/%s.mp3.m3u", holder->host, holder->port, holder->uri + uri_offset, uuid, cid_num);
holder->stream->write_function(holder->stream, "[<a href=%s>mp3</a>] ", mp3);
holder->stream->write_function(holder->stream, "[<a href=%s>m3u</a>]</td></tr>\n", m3u);

View File

@ -335,6 +335,7 @@ Dbh::Dbh(char *dsn, char *user, char *pass)
{
switch_cache_db_connection_options_t options = { {0} };
const char *prefix = "core:";
switch_cache_db_handle_type_t type;
m_connected = false;
if (strstr(dsn, prefix) == dsn) {
@ -342,6 +343,12 @@ Dbh::Dbh(char *dsn, char *user, char *pass)
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) == SWITCH_STATUS_SUCCESS) {
m_connected = true;
}
} else if (!strncasecmp(dsn, "pgsql://", 8)) {
type = SCDB_TYPE_PGSQL;
options.pgsql_options.dsn = (char *)(dsn + 8);
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) == SWITCH_STATUS_SUCCESS) {
m_connected = true;
}
} else {
options.odbc_options.dsn = dsn;
options.odbc_options.user = user;

View File

@ -129,6 +129,7 @@ struct switch_channel {
switch_mutex_t *dtmf_mutex;
switch_mutex_t *flag_mutex;
switch_mutex_t *state_mutex;
switch_mutex_t *thread_mutex;
switch_mutex_t *profile_mutex;
switch_core_session_t *session;
switch_channel_state_t state;
@ -352,6 +353,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel,
switch_mutex_init(&(*channel)->dtmf_mutex, SWITCH_MUTEX_NESTED, pool);
switch_mutex_init(&(*channel)->flag_mutex, SWITCH_MUTEX_NESTED, pool);
switch_mutex_init(&(*channel)->state_mutex, SWITCH_MUTEX_NESTED, pool);
switch_mutex_init(&(*channel)->thread_mutex, SWITCH_MUTEX_NESTED, pool);
switch_mutex_init(&(*channel)->profile_mutex, SWITCH_MUTEX_NESTED, pool);
(*channel)->hangup_cause = SWITCH_CAUSE_NONE;
(*channel)->name = "";
@ -1925,6 +1927,32 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_name_state(const char *nam
return CS_DESTROY;
}
static inline void careful_set(switch_channel_t *channel, switch_channel_state_t *state, switch_channel_state_t val) {
if (switch_mutex_trylock(channel->thread_mutex) == SWITCH_STATUS_SUCCESS) {
*state = val;
switch_mutex_unlock(channel->thread_mutex);
} else {
switch_mutex_t *mutex = switch_core_session_get_mutex(channel->session);
int x = 0;
for (x = 0; x < 100; x++) {
if (switch_mutex_trylock(mutex) == SWITCH_STATUS_SUCCESS) {
*state = val;
switch_mutex_unlock(mutex);
break;
} else {
switch_cond_next();
}
}
if (x == 100) {
*state = val;
}
}
}
SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(switch_channel_t *channel, switch_channel_state_t state,
const char *file, const char *func, int line)
{
@ -1950,7 +1978,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(
switch_mutex_lock(channel->state_mutex);
channel->running_state = state;
careful_set(channel, &channel->running_state, state);
if (state <= CS_DESTROY) {
switch_event_t *event;
@ -2218,7 +2246,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_DEBUG, "(%s) State Change %s -> %s\n",
channel->name, state_names[last_state], state_names[state]);
channel->state = state;
careful_set(channel, &channel->state, state);
if (state == CS_HANGUP && !channel->hangup_cause) {
channel->hangup_cause = SWITCH_CAUSE_NORMAL_CLEARING;
@ -2240,6 +2268,16 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
return channel->state;
}
SWITCH_DECLARE(void) switch_channel_state_thread_lock(switch_channel_t *channel)
{
switch_mutex_lock(channel->thread_mutex);
}
SWITCH_DECLARE(void) switch_channel_state_thread_unlock(switch_channel_t *channel)
{
switch_mutex_unlock(channel->thread_mutex);
}
SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *channel, switch_event_t *event)
{
switch_caller_profile_t *caller_profile, *originator_caller_profile = NULL, *originatee_caller_profile = NULL;
@ -2254,7 +2292,7 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann
originatee_caller_profile = caller_profile->originatee_caller_profile;
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", switch_channel_state_name(channel->state));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", switch_channel_state_name(channel->running_state));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", switch_channel_callstate2str(channel->callstate));
switch_snprintf(state_num, sizeof(state_num), "%d", channel->state);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State-Number", state_num);

View File

@ -1245,6 +1245,11 @@ SWITCH_DECLARE(switch_channel_t *) switch_core_session_get_channel(switch_core_s
return session->channel;
}
SWITCH_DECLARE(switch_mutex_t *) switch_core_session_get_mutex(switch_core_session_t *session)
{
return session->mutex;
}
SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(switch_core_session_t *session)
{
switch_status_t status;
@ -1530,13 +1535,23 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_worker(switch_th
while(session_manager.ready) {
switch_status_t check_status;
pop = NULL;
if (check) {
check_status = switch_queue_trypop(session_manager.thread_queue, &pop);
} else {
switch_mutex_lock(session_manager.mutex);
session_manager.popping++;
switch_mutex_unlock(session_manager.mutex);
check_status = switch_queue_pop(session_manager.thread_queue, &pop);
switch_mutex_lock(session_manager.mutex);
session_manager.popping--;
switch_mutex_unlock(session_manager.mutex);
}
if (check_status == SWITCH_STATUS_SUCCESS) {
if (check_status == SWITCH_STATUS_SUCCESS && pop) {
switch_thread_data_t *td = (switch_thread_data_t *) pop;
if (!td) break;
@ -1614,7 +1629,6 @@ static switch_status_t check_queue(void)
switch_mutex_unlock(session_manager.mutex);
while (x < ttl) {
switch_thread_t *thread;
switch_threadattr_t *thd_attr;
@ -1653,13 +1667,32 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_manager(switch_t
switch_yield(100000);
if (++x == 300) {
switch_queue_interrupt_all(session_manager.thread_queue);
x = 0;
if (session_manager.popping) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,
"Thread pool: running:%d busy:%d popping:%d\n", session_manager.running, session_manager.busy, session_manager.popping);
if (session_manager.popping) {
int i = 0;
switch_mutex_lock(session_manager.mutex);
for (i = 0; i < session_manager.popping; i++) {
switch_queue_trypush(session_manager.thread_queue, NULL);
}
switch_mutex_unlock(session_manager.mutex);
}
x--;
continue;
} else {
x = 0;
}
}
check_queue();
}
return NULL;
}

View File

@ -293,6 +293,17 @@ SWITCH_DECLARE(void) switch_cache_db_flush_handles(void)
SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t **dbh)
{
if (dbh && *dbh) {
switch((*dbh)->type) {
case SCDB_TYPE_PGSQL:
{
switch_pgsql_flush((*dbh)->native_handle.pgsql_dbh);
}
break;
default:
break;
}
switch_mutex_lock(sql_manager.dbh_mutex);
(*dbh)->last_used = switch_epoch_time_now(NULL);
@ -406,7 +417,7 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
switch (type) {
case SCDB_TYPE_PGSQL:
{
db_name = connection_options->odbc_options.dsn;
db_name = connection_options->pgsql_options.dsn;
odbc_user = NULL;
odbc_pass = NULL;
}
@ -835,7 +846,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans_full(sw
switch(dbh->type) {
case SCDB_TYPE_CORE_DB:
{
switch_cache_db_execute_sql_real(dbh, "BEGIN", &errmsg);
switch_cache_db_execute_sql_real(dbh, "BEGIN EXCLUSIVE", &errmsg);
}
break;
case SCDB_TYPE_ODBC:
@ -1497,7 +1508,7 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm)
switch(qm->event_db->type) {
case SCDB_TYPE_CORE_DB:
{
switch_cache_db_execute_sql_real(qm->event_db, "BEGIN", &errmsg);
switch_cache_db_execute_sql_real(qm->event_db, "BEGIN EXCLUSIVE", &errmsg);
}
break;
case SCDB_TYPE_ODBC:
@ -2957,6 +2968,8 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
case SCDB_TYPE_ODBC:
{
char *err;
int result = 0;
switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid, read_bit_rate, sent_callee_name from channels", "DROP TABLE channels", create_channels_sql);
switch_cache_db_test_reactive(sql_manager.dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql);
switch_cache_db_test_reactive(sql_manager.dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql);
@ -2973,12 +2986,72 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
switch_cache_db_test_reactive(sql_manager.dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql);
switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql);
if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
switch_cache_db_execute_sql(sql_manager.dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err);
} else {
switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels where hostname='';delete from channels where hostname='';", &err);
switch(sql_manager.dbh->type) {
case SCDB_TYPE_CORE_DB:
{
switch_cache_db_execute_sql_real(sql_manager.dbh, "BEGIN EXCLUSIVE", &err);
}
break;
case SCDB_TYPE_ODBC:
{
switch_odbc_status_t result;
if ((result = switch_odbc_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.odbc_dbh, 0)) != SWITCH_ODBC_SUCCESS) {
char tmp[100];
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result);
err = strdup(tmp);
}
}
break;
case SCDB_TYPE_PGSQL:
{
switch_pgsql_status_t result;
if ((result = switch_pgsql_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.pgsql_dbh, 0)) != SWITCH_PGSQL_SUCCESS) {
char tmp[100];
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result);
err = strdup(tmp);
}
}
break;
}
switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels where hostname=''", &err);
if (!err) {
switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels where hostname=''", &err);
switch(sql_manager.dbh->type) {
case SCDB_TYPE_CORE_DB:
{
switch_cache_db_execute_sql_real(sql_manager.dbh, "COMMIT", &err);
}
break;
case SCDB_TYPE_ODBC:
{
if (switch_odbc_SQLEndTran(sql_manager.dbh->native_handle.odbc_dbh, 1) != SWITCH_ODBC_SUCCESS ||
switch_odbc_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.odbc_dbh, 1) != SWITCH_ODBC_SUCCESS) {
char tmp[100];
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to commit transaction.", result);
err = strdup(tmp);
}
}
break;
case SCDB_TYPE_PGSQL:
{
if (switch_pgsql_SQLEndTran(sql_manager.dbh->native_handle.pgsql_dbh, 1) != SWITCH_PGSQL_SUCCESS ||
switch_pgsql_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.pgsql_dbh, 1) != SWITCH_PGSQL_SUCCESS ||
switch_pgsql_finish_results(sql_manager.dbh->native_handle.pgsql_dbh) != SWITCH_PGSQL_SUCCESS) {
char tmp[100];
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to commit transaction.", result);
err = strdup(tmp);
}
}
break;
}
}
if (err) {
runtime.odbc_dsn = NULL;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Transactions not supported on your DB, disabling non-SQLite support; using SQLite\n");
@ -3069,6 +3142,9 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL, sql_manager.memory_pool);
}
switch_cache_db_release_db_handle(&sql_manager.dbh);
return SWITCH_STATUS_SUCCESS;
}

View File

@ -521,11 +521,13 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
switch_ivr_parse_all_events(session);
if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) {
switch_channel_state_thread_lock(session->channel);
switch_channel_set_flag(session->channel, CF_THREAD_SLEEPING);
if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) {
switch_thread_cond_wait(session->cond, session->mutex);
}
switch_channel_clear_flag(session->channel, CF_THREAD_SLEEPING);
switch_channel_state_thread_unlock(session->channel);
}
switch_ivr_parse_all_events(session);

View File

@ -37,7 +37,7 @@
#include "tpl.h"
//#define SWITCH_EVENT_RECYCLE
#define DISPATCH_QUEUE_LEN 100
#define DISPATCH_QUEUE_LEN 10000
//#define DEBUG_DISPATCH_QUEUES
/*! \brief A node to store binded events */
@ -291,6 +291,8 @@ static void *SWITCH_THREAD_FUNC switch_event_dispatch_thread(switch_thread_t *th
}
static int PENDING = 0;
static switch_status_t switch_event_queue_dispatch_event(switch_event_t **eventp)
{
@ -302,11 +304,14 @@ static switch_status_t switch_event_queue_dispatch_event(switch_event_t **eventp
while (event) {
int launch = 0;
switch_mutex_lock(EVENT_QUEUE_MUTEX);
if (switch_queue_size(EVENT_DISPATCH_QUEUE) > (unsigned int)(DISPATCH_QUEUE_LEN * DISPATCH_THREAD_COUNT)) {
launch++;
if (!PENDING && switch_queue_size(EVENT_DISPATCH_QUEUE) > (unsigned int)(DISPATCH_QUEUE_LEN * DISPATCH_THREAD_COUNT)) {
if (SOFT_MAX_DISPATCH + 1 > MAX_DISPATCH) {
launch++;
PENDING++;
}
}
switch_mutex_unlock(EVENT_QUEUE_MUTEX);
@ -315,6 +320,10 @@ static switch_status_t switch_event_queue_dispatch_event(switch_event_t **eventp
if (SOFT_MAX_DISPATCH + 1 < MAX_DISPATCH) {
switch_event_launch_dispatch_threads(SOFT_MAX_DISPATCH + 1);
}
switch_mutex_lock(EVENT_QUEUE_MUTEX);
PENDING--;
switch_mutex_unlock(EVENT_QUEUE_MUTEX);
}
*eventp = NULL;
@ -472,7 +481,6 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping dispatch queues\n");
for(x = 0; x < (uint32_t)DISPATCH_THREAD_COUNT; x++) {
switch_queue_trypush(EVENT_DISPATCH_QUEUE, NULL);
}
@ -487,8 +495,8 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void)
}
x = 0;
while (x < 10000 && THREAD_COUNT) {
switch_cond_next();
while (x < 100 && THREAD_COUNT) {
switch_yield(100000);
if (THREAD_COUNT == last) {
x++;
}
@ -1139,17 +1147,21 @@ SWITCH_DECLARE(void) switch_event_destroy(switch_event_t **event)
for (hp = ep->headers; hp;) {
this = hp;
hp = hp->next;
FREE(this->name);
if (this->idx) {
int i = 0;
if (!this->array) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "INDEX WITH NO ARRAY WTF?? [%s][%s]\n", this->name, this->value);
} else {
int i = 0;
for (i = 0; i < this->idx; i++) {
FREE(this->array[i]);
for (i = 0; i < this->idx; i++) {
FREE(this->array[i]);
}
FREE(this->array);
}
FREE(this->array);
}
FREE(this->name);
FREE(this->value);

View File

@ -153,7 +153,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
if (!switch_channel_media_ready(channel)) {
for (elapsed=0; elapsed<(ms/20); elapsed++) {
for (elapsed=0; switch_channel_up(channel) && elapsed<(ms/20); elapsed++) {
if (switch_channel_test_flag(channel, CF_BREAK)) {
switch_channel_clear_flag(channel, CF_BREAK);
return SWITCH_STATUS_BREAK;

View File

@ -316,7 +316,16 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
if ((b_state = switch_channel_down_nosig(chan_b))) {
goto end_of_bridge_loop;
}
if (switch_channel_test_flag(chan_a, CF_HOLD_ON_BRIDGE)) {
switch_core_session_message_t hmsg = { 0 };
switch_channel_clear_flag(chan_a, CF_HOLD_ON_BRIDGE);
hmsg.message_id = SWITCH_MESSAGE_INDICATE_HOLD;
hmsg.from = __FILE__;
hmsg.numeric_arg = 1;
switch_core_session_receive_message(session_a, &hmsg);
}
if (read_frame_count > DEFAULT_LEAD_FRAMES && switch_channel_media_ack(chan_a) && switch_core_session_private_event_count(session_a)) {
switch_channel_set_flag(chan_b, CF_SUSPEND);
msg.numeric_arg = 42;
@ -1556,6 +1565,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu
originatee_channel = switch_core_session_get_channel(originatee_session);
if (switch_channel_test_flag(originator_channel, CF_LEG_HOLDING)) {
switch_channel_set_flag(originator_channel, CF_HOLD_ON_BRIDGE);
}
if (switch_channel_test_flag(originatee_channel, CF_LEG_HOLDING)) {
switch_channel_set_flag(originatee_channel, CF_HOLD_ON_BRIDGE);
}
if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(originatee_channel, CF_DIALPLAN)) {
switch_channel_flip_cid(originatee_channel);
switch_channel_set_flag(originatee_channel, CF_DIALPLAN);

View File

@ -512,6 +512,7 @@ static switch_status_t do_chat_send(switch_event_t *message_event)
switch_chat_interface_t *ci;
switch_status_t status = SWITCH_STATUS_FALSE;
switch_hash_index_t *hi;
switch_event_t *dup = NULL;
const void *var;
void *val;
const char *proto;
@ -563,12 +564,21 @@ static switch_status_t do_chat_send(switch_event_t *message_event)
if ((ci = (switch_chat_interface_t *) val)) {
if (ci->chat_send && !strncasecmp(ci->interface_name, "GLOBAL_", 7)) {
status = ci->chat_send(message_event);
if (status == SWITCH_STATUS_BREAK) {
if (status == SWITCH_STATUS_SUCCESS) {
/* The event was handled by an extension in the chatplan,
* so the event will be duplicated, modified and queued again,
* but it won't be processed by the chatplan again.
* So this copy of the event can be destroyed by the caller.
*/
switch_mutex_unlock(loadable_modules.mutex);
return SWITCH_STATUS_SUCCESS;
} else if (status == SWITCH_STATUS_BREAK) {
/* The event went through the chatplan, but no extension matched
* to handle the sms messsage. It'll be attempted to be delivered
* directly, and unless that works the sms delivery will have failed.
*/
do_skip = 1;
status = SWITCH_STATUS_SUCCESS;
}
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Chat Interface Error [%s]!\n", dest_proto);
break;
}
@ -588,14 +598,20 @@ static switch_status_t do_chat_send(switch_event_t *message_event)
}
}
if (status != SWITCH_STATUS_SUCCESS) {
switch_event_t *dup;
switch_event_dup(&dup, message_event);
switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "true");
switch_event_fire(&dup);
switch_event_dup(&dup, message_event);
if ( switch_true(switch_event_get_header(message_event, "blocking")) ) {
if (status == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "false");
} else {
switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "true");
}
} else {
switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Nonblocking-Delivery", "true");
}
switch_event_fire(&dup);
return status;
}
@ -1766,8 +1782,8 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autolo
switch_loadable_module_runtime();
chat_globals.running = 1;
memset(&chat_globals, 0, sizeof(chat_globals));
chat_globals.running = 1;
chat_globals.pool = loadable_modules.pool;
switch_mutex_init(&chat_globals.mutex, SWITCH_MUTEX_NESTED, chat_globals.pool);

View File

@ -43,7 +43,7 @@
struct switch_pgsql_handle {
char *dsn;
const char *sql;
char *sql;
PGconn* con;
int sock;
switch_pgsql_state_t state;
@ -96,6 +96,122 @@ SWITCH_DECLARE(switch_pgsql_handle_t *) switch_pgsql_handle_new(const char *dsn)
return NULL;
}
#ifdef SWITCH_HAVE_PGSQL
static int db_is_up(switch_pgsql_handle_t *handle)
{
int ret = 0;
switch_event_t *event;
char *err_str = NULL;
int max_tries = DEFAULT_PGSQL_RETRIES;
int code = 0, recon = 0;
if (handle) {
max_tries = handle->num_retries;
if (max_tries < 1)
max_tries = DEFAULT_PGSQL_RETRIES;
}
top:
if (!handle) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Handle\n");
goto done;
}
if (!handle->con) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Connection\n");
goto done;
}
/* Try a non-blocking read on the connection to gobble up any EOF from a closed connection and mark the connection BAD if it is closed. */
PQconsumeInput(handle->con);
if (PQstatus(handle->con) == CONNECTION_BAD) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "PQstatus returned bad connection; reconnecting...\n");
handle->state = SWITCH_PGSQL_STATE_ERROR;
PQreset(handle->con);
if (PQstatus(handle->con) == CONNECTION_BAD) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PQstatus returned bad connection -- reconnection failed!\n");
goto error;
}
handle->state = SWITCH_PGSQL_STATE_CONNECTED;
handle->sock = PQsocket(handle->con);
}
/* if (!PQsendQuery(handle->con, "SELECT 1")) {
code = __LINE__;
goto error;
}
if(switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) {
code = __LINE__;
goto error;
}
if (!result || result->status != PGRES_COMMAND_OK) {
code = __LINE__;
goto error;
}
switch_pgsql_free_result(&result);
switch_pgsql_finish_results(handle);
*/
ret = 1;
goto done;
error:
err_str = switch_pgsql_handle_get_error(handle);
if (PQstatus(handle->con) == CONNECTION_BAD) {
handle->state = SWITCH_PGSQL_STATE_ERROR;
PQreset(handle->con);
if (PQstatus(handle->con) == CONNECTION_OK) {
handle->state = SWITCH_PGSQL_STATE_CONNECTED;
recon = SWITCH_PGSQL_SUCCESS;
handle->sock = PQsocket(handle->con);
}
}
max_tries--;
if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Failure-Message", "The sql server is not responding for DSN %s [%s][%d]",
switch_str_nil(handle->dsn), switch_str_nil(err_str), code);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The sql server is not responding for DSN %s [%s][%d]\n",
switch_str_nil(handle->dsn), switch_str_nil(err_str), code);
if (recon == SWITCH_PGSQL_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection has been re-established");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "The connection has been re-established\n");
} else {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection could not be re-established");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The connection could not be re-established\n");
}
if (!max_tries) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "Giving up!");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up!\n");
}
switch_event_fire(&event);
}
if (!max_tries) {
goto done;
}
switch_safe_free(err_str);
switch_yield(1000000);
goto top;
done:
switch_safe_free(err_str);
return ret;
}
#endif
SWITCH_DECLARE(void) switch_pgsql_set_num_retries(switch_pgsql_handle_t *handle, int num_retries)
{
#ifdef SWITCH_HAVE_PGSQL
@ -117,7 +233,7 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_disconnect(switch_pgsq
PQfinish(handle->con);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Disconnected from [%s]\n", handle->dsn);
}
switch_safe_free(handle->sql);
handle->state = SWITCH_PGSQL_STATE_DOWN;
return SWITCH_PGSQL_SUCCESS;
@ -131,13 +247,14 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_send_query(switch_pgsql_handl
#ifdef SWITCH_HAVE_PGSQL
char *err_str;
switch_safe_free(handle->sql);
handle->sql = strdup(sql);
if (!PQsendQuery(handle->con, sql)) {
err_str = switch_pgsql_handle_get_error(handle);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to send query (%s) to database: %s\n", sql, err_str);
switch_pgsql_finish_results(handle);
goto error;
}
handle->sql = sql;
return SWITCH_PGSQL_SUCCESS;
error:
@ -159,6 +276,8 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_cancel_real(const char *file,
ret = SWITCH_PGSQL_FAIL;
}
PQfreeCancel(cancel);
switch_pgsql_flush(handle);
#endif
return ret;
}
@ -192,12 +311,29 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsq
fds[0].fd = handle->sock;
fds[0].events |= POLLIN;
fds[0].events |= POLLERR;
fds[0].events |= POLLNVAL;
fds[0].events |= POLLHUP;
fds[0].events |= POLLPRI;
fds[0].events |= POLLRDNORM;
fds[0].events |= POLLRDBAND;
/* Wait for the PostgreSQL socket to be ready for data reads. */
if ((poll_res = poll(&fds[0], 1, wait_time)) > -1 ) {
if (fds[0].revents & POLLIN) {
if ((poll_res = poll(&fds[0], 1, wait_time)) > 0 ) {
if (fds[0].revents & POLLHUP || fds[0].revents & POLLNVAL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PGSQL socket closed or invalid while waiting for result for query (%s)\n", handle->sql);
goto error;
} else if (fds[0].revents & POLLERR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql);
goto error;
} else if (fds[0].revents & POLLIN || fds[0].revents & POLLPRI || fds[0].revents & POLLRDNORM || fds[0].revents & POLLRDBAND) {
/* Then try to consume any input waiting. */
if (PQconsumeInput(handle->con)) {
if (PQstatus(handle->con) == CONNECTION_BAD) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Connection terminated while waiting for result.\n");
handle->state = SWITCH_PGSQL_STATE_ERROR;
goto error;
}
/* And check to see if we have a full result ready for reading */
if (!PQisBusy(handle->con)) {
/* If we can pull a full result without blocking, then break this loop */
@ -211,11 +347,8 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsq
switch_pgsql_cancel(handle);
goto error;
}
} else if (fds[0].revents & POLLERR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql);
goto error;
}
} else {
} else if (poll_res == -1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql);
goto error;
}
@ -228,15 +361,13 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsq
goto error;
}
}
} else {
/* If we had an error trying to consume input, report it and cancel the query. */
err_str = switch_pgsql_handle_get_error(handle);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str);
switch_safe_free(err_str);
switch_pgsql_cancel(handle);
/* switch_pgsql_cancel(handle); */
goto error;
}
@ -289,11 +420,17 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsq
free(res);
res = NULL;
*result_out = NULL;
goto error;
}
return SWITCH_PGSQL_SUCCESS;
error:
/* Make sure the failed connection does not have any transactions marked as in progress */
switch_pgsql_flush(handle);
/* Try to reconnect to the DB if we were dropped */
db_is_up(handle);
#endif
return SWITCH_PGSQL_FAIL;
}
@ -337,115 +474,6 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const cha
#endif
}
#ifdef SWITCH_HAVE_PGSQL
static int db_is_up(switch_pgsql_handle_t *handle)
{
int ret = 0;
switch_event_t *event;
char *err_str = NULL;
int max_tries = DEFAULT_PGSQL_RETRIES;
int code = 0, recon = 0;
if (handle) {
max_tries = handle->num_retries;
if (max_tries < 1)
max_tries = DEFAULT_PGSQL_RETRIES;
}
top:
if (!handle) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Handle\n");
goto done;
}
if (!handle->con) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Connection\n");
goto done;
}
if (PQstatus(handle->con) == CONNECTION_BAD) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "PQstatus returned bad connection; reconnecting...\n");
handle->state = SWITCH_PGSQL_STATE_ERROR;
PQreset(handle->con);
if (PQstatus(handle->con) == CONNECTION_BAD) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PQstatus returned bad connection -- reconnection failed!\n");
goto error;
}
handle->state = SWITCH_PGSQL_STATE_CONNECTED;
}
/* if (!PQsendQuery(handle->con, "SELECT 1")) {
code = __LINE__;
goto error;
}
if(switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) {
code = __LINE__;
goto error;
}
if (!result || result->status != PGRES_COMMAND_OK) {
code = __LINE__;
goto error;
}
switch_pgsql_free_result(&result);
switch_pgsql_finish_results(handle);
*/
ret = 1;
goto done;
error:
err_str = switch_pgsql_handle_get_error(handle);
if (PQstatus(handle->con) == CONNECTION_BAD) {
handle->state = SWITCH_PGSQL_STATE_ERROR;
PQreset(handle->con);
if (PQstatus(handle->con) == CONNECTION_OK) {
handle->state = SWITCH_PGSQL_STATE_CONNECTED;
recon = SWITCH_PGSQL_SUCCESS;
}
}
max_tries--;
if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Failure-Message", "The sql server is not responding for DSN %s [%s][%d]",
switch_str_nil(handle->dsn), switch_str_nil(err_str), code);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The sql server is not responding for DSN %s [%s][%d]\n",
switch_str_nil(handle->dsn), switch_str_nil(err_str), code);
if (recon == SWITCH_PGSQL_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection has been re-established");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "The connection has been re-established\n");
} else {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection could not be re-established");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The connection could not be re-established\n");
}
if (!max_tries) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "Giving up!");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up!\n");
}
switch_event_fire(&event);
}
if (!max_tries) {
goto done;
}
switch_safe_free(err_str);
switch_yield(1000000);
goto top;
done:
switch_safe_free(err_str);
return ret;
}
#endif
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_connect(switch_pgsql_handle_t *handle)
{
@ -479,7 +507,8 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_connect(switch_pgsql_h
#endif
}
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err)
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string_detailed(const char *file, const char *func, int line,
switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err)
{
#ifdef SWITCH_HAVE_PGSQL
switch_pgsql_status_t sstatus = SWITCH_PGSQL_SUCCESS;
@ -488,7 +517,7 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgs
handle->affected_rows = 0;
if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) {
if (switch_pgsql_handle_exec_base_detailed(file, func, line, handle, sql, err) == SWITCH_PGSQL_FAIL) {
goto error;
}
@ -533,11 +562,15 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgs
#endif
}
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql_handle_t *handle, const char *sql, char **err)
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base_detailed(const char *file, const char *func, int line,
switch_pgsql_handle_t *handle, const char *sql, char **err)
{
#ifdef SWITCH_HAVE_PGSQL
char *err_str = NULL, *er = NULL;
switch_pgsql_flush(handle);
handle->affected_rows = 0;
if (!db_is_up(handle)) {
@ -548,11 +581,14 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql
if (handle->auto_commit == SWITCH_FALSE && handle->in_txn == SWITCH_FALSE) {
if (switch_pgsql_send_query(handle, "BEGIN") != SWITCH_PGSQL_SUCCESS) {
er = strdup("Error sending BEGIN!");
switch_pgsql_finish_results(handle);
if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) {
db_is_up(handle); /* If finish_results failed, maybe the db went dead */
}
goto error;
}
if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) {
db_is_up(handle);
er = strdup("Error sending BEGIN!");
goto error;
}
@ -561,7 +597,9 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql
if (switch_pgsql_send_query(handle, sql) != SWITCH_PGSQL_SUCCESS) {
er = strdup("Error sending query!");
switch_pgsql_finish_results(handle);
if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) {
db_is_up(handle);
}
goto error;
}
@ -584,7 +622,7 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql
if (err_str) {
if (!switch_stristr("already exists", err_str) && !switch_stristr("duplicate key name", err_str)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str));
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str));
}
if (err) {
*err = err_str;
@ -596,10 +634,11 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql
return SWITCH_PGSQL_FAIL;
}
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec(switch_pgsql_handle_t *handle, const char *sql, char **err)
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_detailed(const char *file, const char *func, int line,
switch_pgsql_handle_t *handle, const char *sql, char **err)
{
#ifdef SWITCH_HAVE_PGSQL
if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) {
if (switch_pgsql_handle_exec_base_detailed(file, func, line, handle, sql, err) == SWITCH_PGSQL_FAIL) {
goto error;
}
@ -789,6 +828,29 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLSetAutoCommitAttr(switch_p
#endif
}
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_flush(switch_pgsql_handle_t *handle)
{
#ifdef SWITCH_HAVE_PGSQL
PGresult *tmp = NULL;
int x = 0;
/* Make sure the query is fully cleared */
while ((tmp = PQgetResult(handle->con)) != NULL) {
PQclear(tmp);
x++;
}
if (x) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Flushing %d results\n", x);
}
return SWITCH_PGSQL_SUCCESS;
#else
return (switch_pgsql_status_t) SWITCH_FALSE;
#endif
}
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLEndTran(switch_pgsql_handle_t *handle, switch_bool_t commit)
{
#ifdef SWITCH_HAVE_PGSQL

View File

@ -3145,8 +3145,8 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t
rtp_session->rtcp_fresh_frame = 1;
rtp_session->stats.rtcp.packet_count += sr->pc;
rtp_session->stats.rtcp.octet_count += sr->oc;
rtp_session->stats.rtcp.packet_count += ntohl(sr->pc);
rtp_session->stats.rtcp.octet_count += ntohl(sr->oc);
rtp_session->stats.rtcp.peer_ssrc = ntohl(sr->ssrc);
/* sender report */

View File

@ -881,7 +881,7 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to,
from = "freeswitch";
}
#ifdef WIN32
switch_snprintf(buf, B64BUFFLEN, "type %s | %s -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to);
switch_snprintf(buf, B64BUFFLEN, "type \"%s\" | \"%s\" -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to);
#else
switch_snprintf(buf, B64BUFFLEN, "/bin/cat %s | %s -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to);
#endif

View File

@ -2458,7 +2458,7 @@ static char *switch_xml_toxml_r(switch_xml_t xml, char **s, switch_size_t *len,
*len += sprintf(*s + *len, "%s", XML_INDENT); /* indent */
}
}
*len += sprintf(*s + (*len), "</%s>", xml->name); /* close tag */
*len += sprintf(*s + (*len), "</%s>\n", xml->name); /* close tag */
}
while (txt[off] && off < xml->off)