Merge remote branch 'fsorig/master'

This commit is contained in:
Moises Silva 2010-12-14 16:24:05 -05:00
commit e5855be613
14 changed files with 172 additions and 68 deletions

View File

@ -102,7 +102,7 @@ CORE_CFLAGS += -I$(switch_srcdir)/libs/pcre
CORE_CFLAGS += -I$(switch_srcdir)/libs/speex/include -Ilibs/speex/include
CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/include
CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/crypto/include -Ilibs/srtp/crypto/include
CORE_CFLAGS += -I$(switch_srcdir)/libs/spandsp/src
CORE_CFLAGS += -I$(switch_srcdir)/libs/spandsp/src -I$(switch_srcdir)/libs/tiff-3.8.2/libtiff
CORE_LIBS = libs/apr-util/libaprutil-1.la libs/apr/libapr-1.la
CORE_LIBS += libs/sqlite/libsqlite3.la libs/pcre/libpcre.la libs/speex/libspeex/libspeexdsp.la

View File

@ -31,7 +31,7 @@ PROJECT_NAME = FreeSWITCH
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 1.0.4
PROJECT_NUMBER = 1.0.6
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.

View File

@ -28,6 +28,11 @@
#include "stfu.h"
//#define DB_JB 1
#ifndef UINT_MAX
# define UINT_MAX 4294967295U
#endif
#ifdef _MSC_VER
/* warning C4706: assignment within conditional expression*/
#pragma warning(disable: 4706)
@ -123,6 +128,7 @@ static stfu_status_t stfu_n_resize_aqueue(stfu_queue_t *queue, uint32_t qlen)
static void stfu_n_init_aqueue(stfu_queue_t *queue, uint32_t qlen)
{
queue->array = calloc(qlen, sizeof(struct stfu_frame));
assert(queue->array != NULL);
memset(queue->array, 0, sizeof(struct stfu_frame) * qlen);
@ -166,6 +172,7 @@ stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen)
stfu_status_t s;
if (i->qlen == i->max_qlen) {
printf("FUCKER1\n");
return STFU_IT_FAILED;
}
@ -173,6 +180,7 @@ stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen)
if (i->qlen < i->max_qlen) {
qlen = i->max_qlen;
} else {
printf("FUCKER2\n");
return STFU_IT_FAILED;
}
}
@ -196,6 +204,12 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_
return NULL;
}
memset(i, 0, sizeof(*i));
#ifdef DB_JB
printf("INIT %u %u\n", qlen, max_qlen);
#endif
i->qlen = qlen;
i->max_qlen = max_qlen;
i->orig_qlen = qlen;
@ -281,10 +295,11 @@ stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets)
stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uint32_t pt, void *data, size_t datalen, int last)
{
uint32_t index;
uint32_t index = 0;
stfu_frame_t *frame;
size_t cplen = 0;
int good_seq = 0, good_ts = 0;
uint32_t min_seq = UINT_MAX, min_ts = UINT_MAX, min_index = 0;
if (!i->samples_per_packet && ts && i->last_rd_ts) {
i->ts_diff = ts - i->last_rd_ts;
@ -305,11 +320,11 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin
}
}
if (seq && seq == i->last_seq + 1) {
if ((seq && seq == i->last_seq + 1) || (i->last_seq > 65500 && seq == 0)) {
good_seq = 1;
}
if (ts && ts == i->last_rd_ts + i->samples_per_packet) {
if ((ts && ts == i->last_rd_ts + i->samples_per_packet) || (i->last_rd_ts > 4294900000 && ts < 5000)) {
good_ts = 1;
}
@ -322,21 +337,20 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin
i->period_packet_in_count++;
i->session_packet_in_count++;
if (i->session_packet_in_count == 150) {
return STFU_IT_WORKED;
}
i->period_need_range_avg = i->period_need_range / (i->period_missing_count || 1);
if (i->period_missing_count > i->qlen * 2) {
#ifdef DB_JB
printf("resize %u %u\n", i->qlen, i->qlen + 1);
#endif
stfu_n_resize(i, i->qlen + 1);
stfu_n_reset_counters(i);
}
if (i->qlen > i->orig_qlen && (i->consecutive_good_count > i->decrement_time || i->period_clean_count > i->decrement_time)) {
stfu_n_resize(i, i->qlen - 1);
stfu_n_reset_counters(i);
stfu_n_sync(i, i->qlen);
} else {
if (i->qlen > i->orig_qlen && (i->consecutive_good_count > i->decrement_time || i->period_clean_count > i->decrement_time)) {
stfu_n_resize(i, i->qlen - 1);
stfu_n_reset_counters(i);
stfu_n_sync(i, i->qlen);
}
}
if ((i->period_packet_in_count > i->period_time)) {
@ -379,13 +393,31 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin
return STFU_IM_DONE;
}
for(index = 0; index < i->out_queue->array_size; index++) {
for(index = 0; index < i->in_queue->array_size; index++) {
if (i->in_queue->array[index].was_read) {
min_index = index;
break;
}
if (i->in_queue->array[index].seq < min_seq) {
min_seq = i->in_queue->array[index].seq;
min_index = index;
}
if (i->in_queue->array[index].ts < min_ts) {
min_ts = i->in_queue->array[index].ts;
min_index = index;
}
}
index = i->in_queue->array_len++;
index = min_index;
if (i->in_queue->array_len < i->in_queue->array_size) {
i->in_queue->array_len++;
}
assert(index < i->in_queue->array_size);
frame = &i->in_queue->array[index];
@ -450,7 +482,7 @@ static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t
for(i = 0; i < queue->real_array_size; i++) {
frame = &queue->array[i];
if ((seq && frame->seq == seq) || frame->ts == ts) {
if (((seq || in->last_seq) && frame->seq == seq) || frame->ts == ts) {
*r_frame = frame;
queue->last_index = i;
frame->was_read = 1;
@ -468,7 +500,8 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
stfu_frame_t *rframe = NULL;
int found = 0;
if (!i->samples_per_packet || ((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) {
if (!i->samples_per_packet || !i->out_queue->array_len) {
//|| ((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) {
return NULL;
}
@ -481,7 +514,11 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
if (i->cur_seq == 0) {
i->cur_seq = i->out_queue->array[0].seq;
} else {
i->cur_seq++;
i->cur_seq++;
/* if we bother using this for anything that doesn't have 16 bit seq, we'll make this a param */
if (i->cur_seq == 65535) {
i->cur_seq = 0;
}
}
if (!(found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, i->cur_seq, &rframe))) {
@ -496,7 +533,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
i->cur_seq = rframe->seq;
i->cur_ts = rframe->ts;
}
i->sync--;
i->sync = 0;
}
@ -546,8 +583,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
#ifdef DB_JB
if (found) {
printf("O: %u:%u %u\n", rframe->seq, rframe->seq, rframe->plc);
assert(found && rframe->seq);
printf("O: %u:%u %u %d\n", rframe->seq, rframe->ts, rframe->plc, rframe->seq - i->last_seq);
} else {
printf("DATA: %u %u %d %s %d\n", i->packet_count, i->consecutive_good_count, i->out_queue->last_jitter, found ? "found" : "not found", i->qlen);
}
@ -579,6 +615,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
rframe = &i->out_queue->int_frame;
rframe->dlen = i->plc_len;
#if 0
if (i->last_frame) {
/* poor man's plc.. Copy the last frame, but we flag it so you can use a better one if you wish */
if (i->miss_count) {
@ -587,7 +624,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
memcpy(rframe->data, i->last_frame->data, rframe->dlen);
}
}
#endif
rframe->ts = i->cur_ts;
i->miss_count++;

View File

@ -4366,6 +4366,8 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc
}
}
switch_channel_set_variable(channel, "last_transfered_conference", argv[2]);
unlock_member(member);
stream->write_function(stream, "OK Member '%d' sent to conference %s.\n", member->id, argv[2]);
@ -5374,6 +5376,14 @@ SWITCH_STANDARD_APP(conference_function)
}
#endif
if (switch_channel_test_flag(channel, CF_RECOVERED)) {
const char *check = switch_channel_get_variable(channel, "last_transfered_conference");
if (!zstr(check)) {
conf_name = (char *) check;
}
}
switch_event_create(&params, SWITCH_EVENT_COMMAND);
switch_assert(params);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "conf_name", conf_name);

View File

@ -1,6 +1,6 @@
# Comment/uncomment the following line to disable/enable debugging
#DEBUG = y
LDDINC=/usr/src/linux-headers-2.6.32-26-server/include
#LDDINC=/usr/src/linux-headers-2.6.32-26-server/include
# Add your debugging flag (or not) to CFLAGS
ifeq ($(DEBUG),y)

View File

@ -60,15 +60,16 @@ MODULE_LICENSE("Dual BSD/GPL");
static struct scull_dev *scull_devices; /* allocated in scull_init_module */
#define GIOVA_BLK 3840
#define GIOVA_SLEEP 40000
#define GIOVA_BLK 1920
#define GIOVA_SLEEP 20
void my_timer_callback_inq( unsigned long data )
{
struct scull_dev *dev = (void *)data;
//dev->readable=1;
wake_up_interruptible(&dev->inq);
mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) );
mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
}
@ -76,8 +77,9 @@ void my_timer_callback_outq( unsigned long data )
{
struct scull_dev *dev = (void *)data;
//dev->writable=1;
wake_up_interruptible(&dev->outq);
mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) );
mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
}
/* The clone-specific data structure includes a key field */
@ -117,9 +119,9 @@ static struct scull_dev *scull_c_lookfor_device(dev_t key)
printk(" Timer installing\n");
setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr );
setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr );
printk( "Starting timer to fire in %dms (%ld)\n", GIOVA_SLEEP/1000, jiffies );
mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) );
mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) );
printk( "Starting timer to fire in %dms (%ld)\n", GIOVA_SLEEP, jiffies );
mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
/* place it in the list */
list_add(&lptr->list, &scull_c_list);
@ -170,10 +172,14 @@ ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
{
struct scull_dev *dev = filp->private_data;
DEFINE_WAIT(wait);
prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
schedule();
finish_wait(&dev->inq, &wait);
DEFINE_WAIT(wait);
prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
schedule();
finish_wait(&dev->inq, &wait);
//memset(buf, 255, count);
//wait_event_interruptible(dev->inq, dev->readable);
//dev->readable=0;
return count;
}
@ -182,10 +188,13 @@ ssize_t scull_write(struct file *filp, const char __user *buf, size_t count,
loff_t *f_pos)
{
struct scull_dev *dev = filp->private_data;
DEFINE_WAIT(wait);
prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE);
schedule();
finish_wait(&dev->outq, &wait);
DEFINE_WAIT(wait);
prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE);
schedule();
finish_wait(&dev->outq, &wait);
//wait_event_interruptible(dev->outq, dev->writable);
//dev->writable=0;
return count;
@ -250,7 +259,7 @@ void scull_cleanup_module(void)
}
/* And all the cloned devices */
/* And all the cloned devices */
list_for_each_entry_safe(lptr, next, &scull_c_list, list) {
ret= del_timer( &lptr->device.timer_inq );
if (ret) printk("The inq timer was still in use...\n");
@ -259,7 +268,7 @@ void scull_cleanup_module(void)
list_del(&lptr->list);
kfree(lptr);
}
printk("Timer uninstalling\n");
printk("Timer uninstalling\n");
/* cleanup_module is never called if registering failed */
unregister_chrdev_region(devno, scull_nr_devs);

View File

@ -34,6 +34,8 @@ struct scull_dev {
wait_queue_head_t outq; /* read and write queues */
struct timer_list timer_inq;
struct timer_list timer_outq;
int readable;
int writable;
//unsigned long read_howmany;
//unsigned long write_howmany;
//unsigned long read_sleeped_acc;

View File

@ -723,7 +723,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
NUTAG_SESSION_TIMER(session_timeout),
TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
@ -739,7 +739,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
NUTAG_SESSION_TIMER(session_timeout),
TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
SIPTAG_CONTENT_TYPE_STR("application/sdp"),

View File

@ -1717,16 +1717,9 @@ void launch_sofia_profile_thread(sofia_profile_t *profile)
static void logger(void *logarg, char const *fmt, va_list ap)
{
/* gcc 4.4 gets mad at us for testing if (ap) so let's try to work around it....*/
void *ap_ptr = (void *) (intptr_t) ap;
if (!fmt) return;
if (ap_ptr) {
switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, fmt, ap);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, "%s", fmt);
}
switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, fmt, ap);
}
static su_log_t *sofia_get_logger(const char *name)
@ -6274,6 +6267,27 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
for (x = 0; x < profile->nat_acl_count; x++) {
last_acl = profile->nat_acl[x];
if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) {
/* NAT mode double check logic and examples.
Example 1: the contact_host is 192.168.1.100 and the network_ip is also 192.168.1.100 the end point
is most likely behind nat with us so we need to veto that decision to turn on nat processing.
Example 2: the contact_host is 192.168.1.100 and the network_ip is 192.0.2.100 which is a public internet ip
the remote endpoint is likely behind a remote nat traversing the public internet.
This secondary check is here to double check the conclusion of nat settigs to ensure we don't set net
in cases where we don't really need to be doing this.
Why would you want to do this? Well if your FreeSWITCH is behind nat and you want to talk to endpoints behind
remote NAT over the public internet in addition to endpoints behind nat with you. This simplifies that process.
*/
if ((ok = switch_check_network_list_ip(network_ip, last_acl))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Endpoint is already inside nat with us.\n");
ok = 0;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Decision stands they are behind nat.\n");
}
break;
}
}

View File

@ -2342,7 +2342,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
nua_invite(tech_pvt->nh,
NUTAG_AUTOANSWER(0),
NUTAG_SESSION_TIMER(session_timeout),
TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
@ -3153,19 +3153,19 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
if ((val = switch_channel_get_variable(tech_pvt->channel, "jitterbuffer_msec"))) {
int len = atoi(val);
int maxlen = 50;
int maxlen = 0;
char *p;
if ((p = strchr(val, ':'))) {
p++;
maxlen = atoi(val);
maxlen = atoi(p);
}
if (len < 20 || len > 10000) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR,
"Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", len);
} else {
int qlen, maxqlen = 0;
int qlen, maxqlen = 50;
qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000);
@ -5060,9 +5060,20 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName
const char *port = switch_channel_get_variable(channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
const char *r_ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE);
const char *r_port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE);
const char *use_uuid;
sofia_set_flag(tech_pvt, TFLAG_RECOVERING);
if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid"))) {
if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel),
use_uuid);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
switch_channel_get_name(channel), use_uuid);
}
}
if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && ip && port) {
const char *tmp;
tech_pvt->iananame = tech_pvt->rm_encoding = (char *) switch_channel_get_variable(channel, "sip_use_codec_name");

View File

@ -732,11 +732,21 @@ SWITCH_DECLARE(switch_status_t) switch_socket_recv(switch_socket_t *sock, char *
SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool)
{
switch_sockaddr_t *new_sa;
unsigned short family = APR_INET;
new_sa = apr_pcalloc(pool, sizeof(apr_sockaddr_t));
switch_assert(new_sa);
new_sa->pool = pool;
memset(new_sa, 0, sizeof(new_sa));
new_sa->family = family;
new_sa->sa.sin.sin_family = family;
new_sa->salen = sizeof(struct sockaddr_in);
new_sa->addr_str_len = 16;
new_sa->ipaddr_ptr = &(new_sa->sa.sin.sin_addr);
new_sa->ipaddr_len = sizeof(struct in_addr);
*sa = new_sa;
return SWITCH_STATUS_SUCCESS;
}

View File

@ -325,13 +325,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
switch_thread_rwlock_unlock(session->bug_rwlock);
}
status = switch_core_codec_decode(use_codec,
session->read_codec,
read_frame->data,
read_frame->datalen,
session->read_impl.actual_samples_per_second,
session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate,
&read_frame->flags);
if (switch_test_flag(read_frame, SFF_PLC)) {
session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet;
session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t);
memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen);
status = SWITCH_STATUS_SUCCESS;
} else {
status = switch_core_codec_decode(use_codec,
session->read_codec,
read_frame->data,
read_frame->datalen,
session->read_impl.actual_samples_per_second,
session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate,
&read_frame->flags);
}
if (status == SWITCH_STATUS_SUCCESS) {
if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && !session->plc) {

View File

@ -1573,10 +1573,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done playing file\n");
if (read_impl.samples_per_second) {
switch_channel_set_variable_printf(channel, "playback_seconds", "%d", fh->samples_out / read_impl.samples_per_second);
switch_channel_set_variable_printf(channel, "playback_ms", "%d", fh->samples_out / (read_impl.samples_per_second / 1000));
switch_channel_set_variable_printf(channel, "playback_seconds", "%d", fh->samples_in / read_impl.samples_per_second);
switch_channel_set_variable_printf(channel, "playback_ms", "%d", fh->samples_in / (read_impl.samples_per_second / 1000));
}
switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_out);
switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_in);
switch_core_session_io_write_lock(session);
switch_channel_set_private(channel, "__fh", NULL);
@ -1761,6 +1761,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session,
switch_assert(session);
if (!digit_timeout) {
digit_timeout = timeout;
}
if (max_digits < min_digits) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
"Max digits %u is less than Min %u, forcing Max to %u\n", max_digits, min_digits, min_digits);

View File

@ -1667,7 +1667,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *
if (rtp_session->jb) {
stfu_n_resize(rtp_session->jb, queue_frames);
} else {
rtp_session->jb = stfu_n_init(queue_frames, max_queue_frames || 50, samples_per_packet, samples_per_second);
rtp_session->jb = stfu_n_init(queue_frames, max_queue_frames ? max_queue_frames : 50, samples_per_packet, samples_per_second);
}
READ_DEC(rtp_session);