#include <apr_general.h>
#include <apr_thread_proc.h>
#include <apr_thread_mutex.h>
+#include <apr_thread_cond.h>
#include <apr_thread_rwlock.h>
#include <apr_file_io.h>
#include <apr_poll.h>
#include <apr_strings.h>
#include <apr_network_io.h>
#include <apr_poll.h>
-
#include <assert.h>
//#include <time.h>
SWITCH_DECLARE(switch_status) switch_core_session_set_read_codec(switch_core_session *session, switch_codec *codec);
SWITCH_DECLARE(switch_status) switch_core_session_set_write_codec(switch_core_session *session, switch_codec *codec);
SWITCH_DECLARE(switch_memory_pool *) switch_core_session_get_pool(switch_core_session *session);
+SWITCH_DECLARE(void) pbx_core_session_signal_state_change(switch_core_session *session);
#ifdef __cplusplus
}
struct switch_codec_implementation {
int samples_per_second;
int bits_per_second;
- int nanoseconds_per_frame;
+ int microseconds_per_frame;
int samples_per_frame;
int bytes_per_frame;
int encoded_bytes_per_frame;
typedef apr_pollfd_t switch_pollfd_t;
typedef apr_pollset_t switch_pollset_t;
typedef apr_file_t switch_file_t;
+typedef apr_thread_cond_t switch_thread_cond_t;
#define SWITCH_UNSPEC APR_UNSPEC
#define SWITCH_POLLIN APR_POLLIN
#define SWITCH_READ APR_READ
#define SWITCH_FPROT_UREAD APR_FPROT_UREAD
#define SWITCH_FPROT_GREAD APR_FPROT_GREAD
+\r
+#define switch_thread_cond_create apr_thread_cond_create\r
+#define switch_thread_cond_wait apr_thread_cond_wait\r
+#define switch_thread_cond_timedwait apr_thread_cond_timedwait\r
+#define switch_thread_cond_signal apr_thread_cond_signal\r
+#define switch_thread_cond_broadcast apr_thread_cond_broadcast\r
+#define switch_thread_cond_destroy apr_thread_cond_destroy\r
+
#define switch_poll_setup apr_poll_setup
#define switch_pollset_create apr_pollset_create
#define switch_pollset_add apr_pollset_add
#define switch_file_read apr_file_read
#define switch_file_write apr_file_write
-#define SWITCH_FOPEN_READ APR_FOPEN_READ\r
-#define SWITCH_FOPEN_WRITE APR_FOPEN_WRITE\r
-#define SWITCH_FOPEN_CREATE APR_FOPEN_CREATE\r
-#define SWITCH_FOPEN_APPEND APR_FOPEN_APPEND\r
-#define SWITCH_FOPEN_TRUNCATE APR_FOPEN_TRUNCATE\r
-#define SWITCH_FOPEN_BINARY APR_FOPEN_BINARY\r
-#define SWITCH_FOPEN_EXCL APR_FOPEN_EXCL\r
-#define SWITCH_FOPEN_BUFFERED APR_FOPEN_BUFFERED\r
-#define SWITCH_FOPEN_DELONCLOSE APR_FOPEN_DELONCLOSE\r
-#define SWITCH_FOPEN_XTHREAD APR_FOPEN_XTHREAD\r
-#define SWITCH_FOPEN_SHARELOCK APR_FOPEN_SHARELOCK\r
-#define SWITCH_FOPEN_NOCLEANUP APR_FOPEN_NOCLEANUP\r
-#define SWITCH_FOPEN_SENDFILE_ENABLED APR_FOPEN_SENDFILE_ENABLED\r
-#define SWITCH_FOPEN_LARGEFILE APR_FOPEN_LARGEFILE\r
-\r
+#define SWITCH_FOPEN_READ APR_FOPEN_READ
+#define SWITCH_FOPEN_WRITE APR_FOPEN_WRITE
+#define SWITCH_FOPEN_CREATE APR_FOPEN_CREATE
+#define SWITCH_FOPEN_APPEND APR_FOPEN_APPEND
+#define SWITCH_FOPEN_TRUNCATE APR_FOPEN_TRUNCATE
+#define SWITCH_FOPEN_BINARY APR_FOPEN_BINARY
+#define SWITCH_FOPEN_EXCL APR_FOPEN_EXCL
+#define SWITCH_FOPEN_BUFFERED APR_FOPEN_BUFFERED
+#define SWITCH_FOPEN_DELONCLOSE APR_FOPEN_DELONCLOSE
+#define SWITCH_FOPEN_XTHREAD APR_FOPEN_XTHREAD
+#define SWITCH_FOPEN_SHARELOCK APR_FOPEN_SHARELOCK
+#define SWITCH_FOPEN_NOCLEANUP APR_FOPEN_NOCLEANUP
+#define SWITCH_FOPEN_SENDFILE_ENABLED APR_FOPEN_SENDFILE_ENABLED
+#define SWITCH_FOPEN_LARGEFILE APR_FOPEN_LARGEFILE
+
#define SWITCH_FPROT_USETID APR_FPROT_USETID
data->running = -1;
}
} else {
- switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Bad Frame.... %d Bubye!\n", read_frame->datalen);
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Bad Frame....Bubye!\n");
data->running = -1;
}
switch_yield(100);
int local_sdp_audio_port;
char call_id[50];
int ssrc;
- //switch_mutex_t *rtp_lock;
+ switch_mutex_t *rtp_lock;
};
memset(tech_pvt, 0, sizeof(*tech_pvt));
channel = switch_core_session_get_channel(*new_session);
switch_core_session_set_private(*new_session, tech_pvt);
- //switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session));
+ switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session));
tech_pvt->session = *new_session;
} else {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
{
int loops = 0;
if (tech_pvt->rtp_session) {
- //switch_mutex_lock(tech_pvt->rtp_lock);
+ switch_mutex_lock(tech_pvt->rtp_lock);
while(loops < 10 && (switch_test_flag(tech_pvt, TFLAG_READING) || switch_test_flag(tech_pvt, TFLAG_WRITING))) {
switch_yield(10000);
ccrtp4c_destroy(&tech_pvt->rtp_session);
tech_pvt->rtp_session = NULL;
- //switch_mutex_unlock(tech_pvt->rtp_lock);
+ switch_mutex_unlock(tech_pvt->rtp_lock);
}
}
- //switch_mutex_lock(tech_pvt->rtp_lock);
+ switch_mutex_lock(tech_pvt->rtp_lock);
if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
bw = tech_pvt->read_codec.implementation->bits_per_second;
- ms = tech_pvt->read_codec.implementation->nanoseconds_per_frame;
+ ms = tech_pvt->read_codec.implementation->microseconds_per_frame;
} else {
switch_channel_get_raw_mode(channel, NULL, NULL, NULL, &ms, &bw);
bw *= 8;
tech_pvt->remote_sdp_audio_ip,
tech_pvt->remote_sdp_audio_port,
tech_pvt->read_codec.codec_interface->ianacode,
- ms,
- ms * 15);
+ ms ,
+ ms * 20);
if (tech_pvt->rtp_session) {
tech_pvt->ssrc = ccrtp4c_get_ssrc(tech_pvt->rtp_session);
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Oh oh?\n");
}
- //switch_mutex_unlock(tech_pvt->rtp_lock);
+ switch_mutex_unlock(tech_pvt->rtp_lock);
}
static switch_status exosip_answer_channel(switch_core_session *session)
struct private_object *tech_pvt = NULL;
size_t bytes = 0, samples = 0, frames=0, ms=0;
switch_channel *channel = NULL;
+ switch_time_t reference, now;
+ int mult = 2;
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) {
bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
samples = tech_pvt->read_codec.implementation->samples_per_frame;
+ ms = tech_pvt->read_codec.implementation->microseconds_per_frame;
} else {
assert(0);
}
assert(tech_pvt->rtp_session != NULL);
tech_pvt->read_frame.datalen = 0;
+ reference = switch_time_now();
+ reference += (ms * mult);
while(!switch_test_flag(tech_pvt, TFLAG_BYE) && switch_test_flag(tech_pvt, TFLAG_IO) && tech_pvt->read_frame.datalen == 0) {
if ((tech_pvt->read_frame.datalen =
ccrtp4c_read(tech_pvt->rtp_session,
bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
frames = (tech_pvt->read_frame.datalen / bytes);
samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
- ms = frames * tech_pvt->read_codec.implementation->nanoseconds_per_frame / 1000;
+ ms = frames * tech_pvt->read_codec.implementation->microseconds_per_frame;
tech_pvt->timestamp_recv += samples;
break;
}
+
+ now = switch_time_now();
+ if (now >= reference) {
+ printf("TO\n");
+ //memset(tech_pvt->read_buf, 0, bytes *2);
+ //tech_pvt->timestamp_recv += (samples * mult);
+ //reference += (ms * mult);
+ //tech_pvt->read_frame.datalen = bytes *2;
+ //break;
+ }
+
switch_yield(100);
}
if (!switch_test_flag(tech_pvt, TFLAG_RTP)) {
activate_rtp(tech_pvt);
+ //return SWITCH_STATUS_SUCCESS;
}
if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
frames = (frame->datalen / bytes);
samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
- ms = frames * tech_pvt->read_codec.implementation->nanoseconds_per_frame / 1000;
+ ms = frames * tech_pvt->read_codec.implementation->microseconds_per_frame / 1000;
} else {
assert(0);
}
channel = switch_core_session_get_channel(session);
switch_core_session_set_private(session, tech_pvt);
tech_pvt->session = session;
- //switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
+ switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
} else {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
switch_core_session_destroy(&session);
} else {
int ms;
switch_set_flag(tech_pvt, TFLAG_USING_CODEC);
- ms = tech_pvt->write_codec.implementation->nanoseconds_per_frame / 1000;
+ ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000;
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Inbound Codec %s/%d %d ms\n", dname, rate, ms);
tech_pvt->read_frame.codec = &tech_pvt->read_codec;
switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
} else {
int ms;
switch_set_flag(tech_pvt, TFLAG_USING_CODEC);
- ms = tech_pvt->write_codec.implementation->nanoseconds_per_frame / 1000;
+ ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000;
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Outbound Codec %s/%d %d ms\n", dname, rate, ms);
tech_pvt->read_frame.codec = &tech_pvt->read_codec;
switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
static const switch_codec_implementation g711u_8k_60ms_implementation = {
/*.samples_per_second*/ 8000,
/*.bits_per_second*/ 19200,
- /*.nanoseconds_per_frame*/ 60000,
+ /*.microseconds_per_frame*/ 60000,
/*.samples_per_frame*/ 480,
/*.bytes_per_frame*/ 960,
/*.encoded_bytes_per_frame*/ 480,
static const switch_codec_implementation g711u_8k_30ms_implementation = {
/*.samples_per_second*/ 8000,
/*.bits_per_second*/ 96000,
- /*.nanoseconds_per_frame*/ 30000,
+ /*.microseconds_per_frame*/ 30000,
/*.samples_per_frame*/ 240,
/*.bytes_per_frame*/ 480,
/*.encoded_bytes_per_frame*/ 240,
static const switch_codec_implementation g711u_8k_implementation = {
/*.samples_per_second*/ 8000,
/*.bits_per_second*/ 64000,
- /*.nanoseconds_per_frame*/ 20000,
+ /*.microseconds_per_frame*/ 20000,
/*.samples_per_frame*/ 160,
/*.bytes_per_frame*/ 320,
/*.encoded_bytes_per_frame*/ 160,
static const switch_codec_implementation g711a_8k_implementation = {
/*.samples_per_second*/ 8000,
/*.bits_per_second*/ 64000,
- /*.nanoseconds_per_frame*/ 20000,
+ /*.microseconds_per_frame*/ 20000,
/*.samples_per_frame*/ 160,
/*.bytes_per_frame*/ 320,
/*.encoded_bytes_per_frame*/ 160,
switch_core_codec_destroy(&codec);
- switch_channel_set_state(channel, CS_HANGUP);
+ switch_channel_hangup(channel);
}
static const switch_application_interface playback_application_interface = {
/*.samples_per_frame = */ 640,
/*.bytes_per_frame = */ 1280,
/*.encoded_bytes_per_frame = */ 1280,
- /*.nanoseconds_per_frame = */ 20000,
+ /*.microseconds_per_frame = */ 20000,
/*.number_of_channels = */ 1,
/*.pref_frames_per_packet = */ 1,
/*.max_frames_per_packet = */ 1,
static const switch_codec_implementation raw_16k_implementation = {
/*.samples_per_second = */ 16000,
/*.bits_per_second = */ 256000,
- /*.nanoseconds_per_frame = */ 20000,
+ /*.microseconds_per_frame = */ 20000,
/*.samples_per_frame = */ 320,
/*.bytes_per_frame = */ 640,
/*.encoded_bytes_per_frame = */ 640,
static const switch_codec_implementation raw_8k_implementation = {
/*.samples_per_second = */ 8000,
/*.bits_per_second = */ 128000,
- /*.nanoseconds_per_frame = */ 20000,
+ /*.microseconds_per_frame = */ 20000,
/*.samples_per_frame = */ 160,
/*.bytes_per_frame = */ 320,
/*.encoded_bytes_per_frame = */ 320,
static const switch_codec_implementation raw_8k_30ms_implementation = {
/*.samples_per_second*/ 8000,
/*.bits_per_second*/ 128000,
- /*.nanoseconds_per_frame*/ 30000,
+ /*.microseconds_per_frame*/ 30000,
/*.samples_per_frame*/ 240,
/*.bytes_per_frame*/ 480,
/*.encoded_bytes_per_frame*/ 480,
if (ok) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s State Change %s -> %s\n", channel->name, state_names[last_state], state_names[state]);
channel->state = state;
+ pbx_core_session_signal_state_change(channel->session);
} else {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s Invalid State Change %s -> %s\n", channel->name, state_names[last_state], state_names[state]);
+ //we won't tolerate an invalid state change so we can make sure we are as robust as a nice cup of dark coffee!
assert(0);
}
return channel->state;
assert(channel != NULL);
if (channel->state < CS_HANGUP) {
channel->state = CS_HANGUP;
+ pbx_core_session_signal_state_change(channel->session);
}
-
return channel->state;
}
unsigned char *raw_read_buf[3200];
unsigned char *enc_read_buf[3200];
+ switch_mutex_t *mutex;
+ switch_thread_cond_t *cond;
+
void *private;
};
}
for(iptr = codec_interface->implementations; iptr; iptr = iptr->next) {
- if ((!rate || rate == iptr->samples_per_second) && (!ms || ms == (iptr->nanoseconds_per_frame / 1000))) {
+ if ((!rate || rate == iptr->samples_per_second) && (!ms || ms == (iptr->microseconds_per_frame / 1000))) {
implementation = iptr;
break;
}
switch_core_session_kill_channel(session, SWITCH_SIG_KILL);
- thread_session->running = -1;
- while(thread_session->running) {
- switch_yield(100);
+ if (thread_session->running > 0) {
+ thread_session->running = -1;
+
+ while(thread_session->running) {
+ switch_yield(1000);
+ }
}
}
}
+SWITCH_DECLARE(void) pbx_core_session_signal_state_change(switch_core_session *session)
+{
+ switch_thread_cond_signal(session->cond);
+}
+
SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session)
{
switch_channel_state state = CS_NEW, laststate = CS_HANGUP;
driver_event_handlers = endpoint_interface->event_handlers;
assert(driver_event_handlers != NULL);
+ switch_mutex_lock(session->mutex);
+
while ((state = switch_channel_get_state(session->channel)) != CS_DONE) {
if (state != laststate) {
switch ( state ) {
}
laststate = state;
}
- //I should fall asleep here if possible!!!
- switch_yield(1000);
- }
+ if (state < CS_DONE) {
+ switch_thread_cond_wait(session->cond, session->mutex);
+ }
+ }
}
SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session **session)
session->enc_write_frame.data = session->enc_write_buf;
session->enc_read_frame.data = session->enc_read_buf;
+ switch_mutex_init(&session->mutex, SWITCH_MUTEX_NESTED ,session->pool);
+ switch_thread_cond_create(&session->cond, session->pool);
+
return session;
}
ptr->iananame,
ptr->interface_name,
impl->samples_per_second,
- impl->nanoseconds_per_frame / 1000);
+ impl->microseconds_per_frame / 1000);
}
switch_core_hash_insert(loadable_modules.codec_hash,