diff --git a/Freeswitch.2008.express.sln b/Freeswitch.2008.express.sln
index 672406bda2..ad3cafe5cd 100644
--- a/Freeswitch.2008.express.sln
+++ b/Freeswitch.2008.express.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
+# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchConsole", "w32\Console\FreeSwitchConsole.2008.vcproj", "{1AF3A893-F7BE-43DD-B697-8AB2397C0D67}"
ProjectSection(ProjectDependencies) = postProject
{202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
@@ -11,6 +11,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchCoreLib", "w32\Li
ProjectSection(ProjectDependencies) = postProject
{8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9}
{89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C}
+ {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}
{F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3}
{03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
diff --git a/Makefile.am b/Makefile.am
index da89572c6f..df1ee2e0d0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -276,7 +276,8 @@ bin_PROGRAMS = freeswitch fs_cli fs_ivrd tone2wav fs_encode
##
## fs_cli ()
##
-fs_cli_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c libs/esl/src/esl_threadmutex.c libs/esl/fs_cli.c libs/esl/src/esl_json.c
+fs_cli_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c \
+ libs/esl/src/esl_threadmutex.c libs/esl/fs_cli.c libs/esl/src/esl_json.c libs/esl/src/esl_buffer.c
fs_cli_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include
fs_cli_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS) -lm
@@ -304,7 +305,8 @@ tone2wav_LDADD = libfreeswitch.la
##
## fs_ivrd ()
##
-fs_ivrd_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c libs/esl/src/esl_threadmutex.c libs/esl/ivrd.c libs/esl/src/esl_json.c
+fs_ivrd_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c \
+ libs/esl/src/esl_threadmutex.c libs/esl/ivrd.c libs/esl/src/esl_json.c libs/esl/src/esl_buffer.c
fs_ivrd_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include
fs_ivrd_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS) -lm
diff --git a/libs/esl/Makefile b/libs/esl/Makefile
index a180406bda..ab50bac4d9 100644
--- a/libs/esl/Makefile
+++ b/libs/esl/Makefile
@@ -9,9 +9,9 @@ CXXFLAGS=$(BASE_FLAGS) -Wall -Werror -Wno-unused-variable
MYLIB=libesl.a
LIBS=-lncurses -lpthread -lesl -lm
LDFLAGS=-L.
-OBJS=src/esl.o src/esl_event.o src/esl_threadmutex.o src/esl_config.o src/esl_json.o
-SRC=src/esl.c src/esl_json.c src/esl_event.c src/esl_threadmutex.c src/esl_config.c src/esl_oop.cpp src/esl_json.c
-HEADERS=src/include/esl_config.h src/include/esl_event.h src/include/esl.h src/include/esl_threadmutex.h src/include/esl_oop.h src/include/esl_json.h
+OBJS=src/esl.o src/esl_event.o src/esl_threadmutex.o src/esl_config.o src/esl_json.o src/esl_buffer.o
+SRC=src/esl.c src/esl_json.c src/esl_event.c src/esl_threadmutex.c src/esl_config.c src/esl_oop.cpp src/esl_json.c src/esl_buffer.c
+HEADERS=src/include/esl_config.h src/include/esl_event.h src/include/esl.h src/include/esl_threadmutex.h src/include/esl_oop.h src/include/esl_json.h src/include/esl_buffer.h
SOLINK=-shared -Xlinker -x
# comment the next line to disable c++ (no swig mods for you then)
OBJS += src/esl_oop.o
diff --git a/libs/esl/src/esl.2008.vcproj b/libs/esl/src/esl.2008.vcproj
index 101348dd59..89daa17d9e 100644
--- a/libs/esl/src/esl.2008.vcproj
+++ b/libs/esl/src/esl.2008.vcproj
@@ -290,6 +290,10 @@
RelativePath=".\esl.c"
>
+
+
@@ -316,6 +320,10 @@
RelativePath=".\include\esl.h"
>
+
+
diff --git a/libs/esl/src/esl.2010.vcxproj b/libs/esl/src/esl.2010.vcxproj
index b215fe4bc8..fd5e3a8353 100644
--- a/libs/esl/src/esl.2010.vcxproj
+++ b/libs/esl/src/esl.2010.vcxproj
@@ -128,6 +128,7 @@
+
@@ -135,6 +136,7 @@
+
diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c
index ce582d3837..f5bab62fcb 100644
--- a/libs/esl/src/esl.c
+++ b/libs/esl/src/esl.c
@@ -428,6 +428,10 @@ ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t s
esl_mutex_create(&handle->mutex);
}
+ if (!handle->packet_buf) {
+ esl_buffer_create(&handle->packet_buf, BUF_CHUNK, BUF_START, 0);
+ }
+
handle->connected = 1;
esl_send_recv(handle, "connect\n\n");
@@ -632,6 +636,10 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *
if (!handle->mutex) {
esl_mutex_create(&handle->mutex);
}
+
+ if (!handle->packet_buf) {
+ esl_buffer_create(&handle->packet_buf, BUF_CHUNK, BUF_START, 0);
+ }
handle->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
@@ -805,6 +813,11 @@ ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle)
esl_mutex_destroy(&mutex);
}
+ if (handle->packet_buf) {
+ esl_buffer_destroy(&handle->packet_buf);
+ }
+
+
return status;
}
@@ -825,7 +838,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
if (check_q) {
esl_mutex_lock(handle->mutex);
- if (handle->race_event) {
+ if (handle->race_event || esl_buffer_packet_count(handle->packet_buf)) {
esl_mutex_unlock(handle->mutex);
return esl_recv_event(handle, check_q, save_event);
}
@@ -894,12 +907,15 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
}
+static esl_ssize_t handle_recv(esl_handle_t *handle, void *data, esl_size_t datalen)
+{
+ return recv(handle->sock, data, datalen, 0);
+}
ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event)
{
char *c;
esl_ssize_t rrval;
- int crc = 0;
esl_event_t *revent = NULL;
char *beg;
char *hname, *hval;
@@ -907,7 +923,6 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
char *cl;
esl_ssize_t len;
int zc = 0;
- int bread = 0;
if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
return ESL_FAIL;
@@ -916,9 +931,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
esl_mutex_lock(handle->mutex);
if (!handle->connected || handle->sock == ESL_SOCK_INVALID) {
- handle->connected = 0;
- esl_mutex_unlock(handle->mutex);
- return ESL_FAIL;
+ goto fail;
}
esl_event_safe_destroy(&handle->last_event);
@@ -932,76 +945,62 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
goto parse_event;
}
- memset(handle->header_buf, 0, sizeof(handle->header_buf));
+
+ while(!revent && handle->connected) {
+ esl_size_t len1;
+
+ if ((len1 = esl_buffer_read_packet(handle->packet_buf, handle->socket_buf, sizeof(handle->socket_buf)))) {
+ char *data = (char *) handle->socket_buf;
+ char *p, *e;
+
+ esl_event_create(&revent, ESL_EVENT_CLONE);
+ revent->event_id = ESL_EVENT_SOCKET_DATA;
+ esl_event_add_header_string(revent, ESL_STACK_BOTTOM, "Event-Name", "SOCKET_DATA");
+
+ hname = p = data;
+ while(p) {
+ hname = p;
+ p = NULL;
- c = handle->header_buf;
- beg = c;
+ if ((hval = strchr(hname, ':'))) {
+ *hval++ = '\0';
+ while(*hval == ' ' || *hval == '\t') hval++;
- while(handle->connected) {
- if (bread + 2 >= sizeof(handle->header_buf)) {
- esl_log(ESL_LOG_CRIT, "OUT OF BUFFER SPACE!\n");
- handle->connected = 0;
- esl_mutex_unlock(handle->mutex);
- return ESL_DISCONNECTED;
+ if ((e = strchr(hval, '\n'))) {
+ *e++ = '\0';
+ while(*e == '\n' || *e == '\r') e++;
+
+ if (hname && hval) {
+ esl_url_decode(hval);
+ esl_log(ESL_LOG_DEBUG, "RECV HEADER [%s] = [%s]\n", hname, hval);
+ esl_event_add_header_string(revent, ESL_STACK_BOTTOM, hname, hval);
+ }
+
+ p = e;
+ }
+ }
+ }
+
+ break;
}
- rrval = recv(handle->sock, c, 1, 0);
+ rrval = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf));
+
if (rrval == 0) {
if (++zc >= 100) {
- handle->connected = 0;
- esl_mutex_unlock(handle->mutex);
- return ESL_DISCONNECTED;
+ goto fail;
}
+ continue;
} else if (rrval < 0) {
strerror_r(handle->errnum, handle->err, sizeof(handle->err));
goto fail;
- } else {
- zc = 0;
-
- if (*c == '\n') {
-
- *(c+1) = '\0';
-
- if (++crc == 2) {
- break;
- }
-
- if (!revent) {
- esl_event_create(&revent, ESL_EVENT_CLONE);
- revent->event_id = ESL_EVENT_SOCKET_DATA;
- esl_event_add_header_string(revent, ESL_STACK_BOTTOM, "Event-Name", "SOCKET_DATA");
-
- }
-
- hname = beg;
- hval = col = NULL;
-
- if (hname && (col = strchr(hname, ':'))) {
- hval = col + 1;
- *col = '\0';
- while(*hval == ' ') hval++;
- }
-
- *c = '\0';
-
- if (hname && hval) {
- esl_url_decode(hval);
- esl_log(ESL_LOG_DEBUG, "RECV HEADER [%s] = [%s]\n", hname, hval);
- esl_event_add_header_string(revent, ESL_STACK_BOTTOM, hname, hval);
- }
-
- c = beg;
- bread = 0;
- continue;
-
- } else {
- crc = 0;
- }
-
- c++;
}
- }
+ zc = 0;
+
+ esl_buffer_write(handle->packet_buf, handle->socket_buf, rrval);
+ }
+
if (!revent) {
goto fail;
}
@@ -1016,12 +1015,28 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
*(body + len) = '\0';
do {
- esl_ssize_t r;
- if ((r = recv(handle->sock, body + sofar, len - sofar, 0)) < 0) {
- strerror_r(handle->errnum, handle->err, sizeof(handle->err));
- goto fail;
+ esl_ssize_t r,s = esl_buffer_inuse(handle->packet_buf);
+
+ if (s >= len) {
+ sofar = esl_buffer_read(handle->packet_buf, body, len);
+ } else {
+ r = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf));
+
+ if (r < 0) {
+ strerror_r(handle->errnum, handle->err, sizeof(handle->err));
+ goto fail;
+ } else if (r == 0) {
+ if (++zc >= 100) {
+ goto fail;
+ }
+ continue;
+ }
+
+ zc = 0;
+
+ esl_buffer_write(handle->packet_buf, handle->socket_buf, r);
}
- sofar += r;
+
} while (sofar < len);
revent->body = body;
@@ -1123,6 +1138,8 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
fail:
+ esl_mutex_unlock(handle->mutex);
+
handle->connected = 0;
return ESL_FAIL;
diff --git a/libs/esl/src/esl_buffer.c b/libs/esl/src/esl_buffer.c
new file mode 100644
index 0000000000..8032169fe3
--- /dev/null
+++ b/libs/esl/src/esl_buffer.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2010, Anthony Minessale II
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "esl_buffer.h"
+
+static unsigned buffer_id = 0;
+
+struct esl_buffer {
+ unsigned char *data;
+ unsigned char *head;
+ esl_size_t used;
+ esl_size_t actually_used;
+ esl_size_t datalen;
+ esl_size_t max_len;
+ esl_size_t blocksize;
+ unsigned id;
+ int loops;
+};
+
+
+ESL_DECLARE(esl_status_t) esl_buffer_create(esl_buffer_t **buffer, esl_size_t blocksize, esl_size_t start_len, esl_size_t max_len)
+{
+ esl_buffer_t *new_buffer;
+
+ new_buffer = malloc(sizeof(*new_buffer));
+ if (new_buffer) {
+ memset(new_buffer, 0, sizeof(*new_buffer));
+
+ if (start_len) {
+ new_buffer->data = malloc(start_len);
+ if (!new_buffer->data) {
+ free(new_buffer);
+ return ESL_FAIL;
+ }
+ memset(new_buffer->data, 0, start_len);
+ }
+
+ new_buffer->max_len = max_len;
+ new_buffer->datalen = start_len;
+ new_buffer->id = buffer_id++;
+ new_buffer->blocksize = blocksize;
+ new_buffer->head = new_buffer->data;
+
+ *buffer = new_buffer;
+ return ESL_SUCCESS;
+ }
+
+ return ESL_FAIL;
+}
+
+ESL_DECLARE(esl_size_t) esl_buffer_len(esl_buffer_t *buffer)
+{
+
+ assert(buffer != NULL);
+
+ return buffer->datalen;
+
+}
+
+
+ESL_DECLARE(esl_size_t) esl_buffer_freespace(esl_buffer_t *buffer)
+{
+ assert(buffer != NULL);
+
+
+ if (buffer->max_len) {
+ return (esl_size_t) (buffer->max_len - buffer->used);
+ }
+ return 1000000;
+
+}
+
+ESL_DECLARE(esl_size_t) esl_buffer_inuse(esl_buffer_t *buffer)
+{
+ assert(buffer != NULL);
+
+ return buffer->used;
+}
+
+ESL_DECLARE(esl_size_t) esl_buffer_seek(esl_buffer_t *buffer, esl_size_t datalen)
+{
+ esl_size_t reading = 0;
+
+ assert(buffer != NULL);
+
+ if (buffer->used < 1) {
+ buffer->used = 0;
+ return 0;
+ } else if (buffer->used >= datalen) {
+ reading = datalen;
+ } else {
+ reading = buffer->used;
+ }
+
+ buffer->used = buffer->actually_used - reading;
+ buffer->head = buffer->data + reading;
+
+ return reading;
+}
+
+ESL_DECLARE(esl_size_t) esl_buffer_toss(esl_buffer_t *buffer, esl_size_t datalen)
+{
+ esl_size_t reading = 0;
+
+ assert(buffer != NULL);
+
+ if (buffer->used < 1) {
+ buffer->used = 0;
+ return 0;
+ } else if (buffer->used >= datalen) {
+ reading = datalen;
+ } else {
+ reading = buffer->used;
+ }
+
+ buffer->used -= reading;
+ buffer->head += reading;
+
+ return buffer->used;
+}
+
+ESL_DECLARE(void) esl_buffer_set_loops(esl_buffer_t *buffer, int loops)
+{
+ buffer->loops = loops;
+}
+
+ESL_DECLARE(esl_size_t) esl_buffer_read_loop(esl_buffer_t *buffer, void *data, esl_size_t datalen)
+{
+ esl_size_t len;
+ if ((len = esl_buffer_read(buffer, data, datalen)) < datalen) {
+ if (buffer->loops == 0) {
+ return len;
+ }
+ buffer->head = buffer->data;
+ buffer->used = buffer->actually_used;
+ len = esl_buffer_read(buffer, (char*)data + len, datalen - len);
+ buffer->loops--;
+ }
+ return len;
+}
+
+ESL_DECLARE(esl_size_t) esl_buffer_read(esl_buffer_t *buffer, void *data, esl_size_t datalen)
+{
+ esl_size_t reading = 0;
+
+ assert(buffer != NULL);
+ assert(data != NULL);
+
+
+ if (buffer->used < 1) {
+ buffer->used = 0;
+ return 0;
+ } else if (buffer->used >= datalen) {
+ reading = datalen;
+ } else {
+ reading = buffer->used;
+ }
+
+ memcpy(data, buffer->head, reading);
+ buffer->used -= reading;
+ buffer->head += reading;
+
+ /* if (buffer->id == 4) printf("%u o %d = %d\n", buffer->id, (unsigned)reading, (unsigned)buffer->used); */
+ return reading;
+}
+
+
+ESL_DECLARE(esl_size_t) esl_buffer_packet_count(esl_buffer_t *buffer)
+{
+ char *pe, *p, *e, *head = (char *) buffer->head;
+ esl_size_t x = 0;
+
+ assert(buffer != NULL);
+
+ e = (head + buffer->used);
+
+ for (p = head; p && *p && p < e; p++) {
+ if (*p == '\n') {
+ pe = p+1;
+ if (*pe == '\r') pe++;
+ if (pe <= e && *pe == '\n') {
+ p = pe++;
+ x++;
+ }
+ }
+ }
+
+ return x;
+}
+
+ESL_DECLARE(esl_size_t) esl_buffer_read_packet(esl_buffer_t *buffer, void *data, esl_size_t maxlen)
+{
+ char *pe, *p, *e, *head = (char *) buffer->head;
+ esl_size_t datalen = 0;
+
+ assert(buffer != NULL);
+ assert(data != NULL);
+
+ e = (head + buffer->used);
+
+ for (p = head; p && *p && p < e; p++) {
+ if (*p == '\n') {
+ pe = p+1;
+ if (*pe == '\r') pe++;
+ if (pe <= e && *pe == '\n') {
+ pe++;
+ datalen = pe - head;
+ if (datalen > maxlen) {
+ datalen = maxlen;
+ }
+ break;
+ }
+ }
+ }
+
+ return esl_buffer_read(buffer, data, datalen);
+}
+
+ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, esl_size_t datalen)
+{
+ esl_size_t freespace, actual_freespace;
+
+ assert(buffer != NULL);
+ assert(data != NULL);
+ assert(buffer->data != NULL);
+
+ if (!datalen) {
+ return buffer->used;
+ }
+
+ actual_freespace = buffer->datalen - buffer->actually_used;
+ if (actual_freespace < datalen && (!buffer->max_len || (buffer->used + datalen <= buffer->max_len))) {
+ memmove(buffer->data, buffer->head, buffer->used);
+ buffer->head = buffer->data;
+ buffer->actually_used = buffer->used;
+ }
+
+ freespace = buffer->datalen - buffer->used;
+
+ /*
+ if (buffer->data != buffer->head) {
+ memmove(buffer->data, buffer->head, buffer->used);
+ buffer->head = buffer->data;
+ }
+ */
+
+ if (freespace < datalen) {
+ esl_size_t new_size, new_block_size;
+ void *data1;
+
+ new_size = buffer->datalen + datalen;
+ new_block_size = buffer->datalen + buffer->blocksize;
+
+ if (new_block_size > new_size) {
+ new_size = new_block_size;
+ }
+ buffer->head = buffer->data;
+ data1 = realloc(buffer->data, new_size);
+ if (!data1) {
+ return 0;
+ }
+ buffer->data = data1;
+ buffer->head = buffer->data;
+ buffer->datalen = new_size;
+ }
+
+
+ freespace = buffer->datalen - buffer->used;
+
+ if (freespace < datalen) {
+ return 0;
+ } else {
+ memcpy(buffer->head + buffer->used, data, datalen);
+ buffer->used += datalen;
+ buffer->actually_used += datalen;
+ }
+ /* if (buffer->id == 4) printf("%u i %d = %d\n", buffer->id, (unsigned)datalen, (unsigned)buffer->used); */
+
+ return buffer->used;
+}
+
+ESL_DECLARE(void) esl_buffer_zero(esl_buffer_t *buffer)
+{
+ assert(buffer != NULL);
+ assert(buffer->data != NULL);
+
+ buffer->used = 0;
+ buffer->actually_used = 0;
+ buffer->head = buffer->data;
+}
+
+ESL_DECLARE(esl_size_t) esl_buffer_zwrite(esl_buffer_t *buffer, const void *data, esl_size_t datalen)
+{
+ esl_size_t w;
+
+ if (!(w = esl_buffer_write(buffer, data, datalen))) {
+ esl_buffer_zero(buffer);
+ return esl_buffer_write(buffer, data, datalen);
+ }
+
+ return w;
+}
+
+ESL_DECLARE(void) esl_buffer_destroy(esl_buffer_t **buffer)
+{
+ if (*buffer) {
+ free((*buffer)->data);
+ free(*buffer);
+ }
+
+ *buffer = NULL;
+}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
diff --git a/libs/esl/src/include/esl.h b/libs/esl/src/include/esl.h
index 9f28c3d925..99ab53ae95 100644
--- a/libs/esl/src/include/esl.h
+++ b/libs/esl/src/include/esl.h
@@ -251,6 +251,7 @@ typedef int esl_filehandle_t;
#include "esl_json.h"
typedef int16_t esl_port_t;
+typedef size_t esl_size_t;
typedef enum {
ESL_SUCCESS,
@@ -259,7 +260,11 @@ typedef enum {
ESL_DISCONNECTED
} esl_status_t;
+#define BUF_CHUNK 65536 * 50
+#define BUF_START 65536 * 100
+
#include
+#include
/*! \brief A handle that will hold the socket information and
different events received. */
@@ -273,7 +278,8 @@ typedef struct {
/*! The error number reported by the OS */
int errnum;
/*! The inner contents received by the socket. Used only internally. */
- char header_buf[4196];
+ esl_buffer_t *packet_buf;
+ char socket_buf[65536];
/*! Last command reply */
char last_reply[1024];
/*! Las command reply when called with esl_send_recv */
diff --git a/libs/esl/src/include/esl_buffer.h b/libs/esl/src/include/esl_buffer.h
new file mode 100644
index 0000000000..c7901e4ede
--- /dev/null
+++ b/libs/esl/src/include/esl_buffer.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2010, Anthony Minessale II
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "esl.h"
+#ifndef ESL_BUFFER_H
+#define ESL_BUFFER_H
+/**
+ * @defgroup esl_buffer Buffer Routines
+ * @ingroup buffer
+ * The purpose of this module is to make a plain buffering interface that can be used for read/write buffers
+ * throughout the application.
+ * @{
+ */
+struct esl_buffer;
+typedef struct esl_buffer esl_buffer_t;
+
+/*! \brief Allocate a new dynamic esl_buffer
+ * \param buffer returned pointer to the new buffer
+ * \param blocksize length to realloc by as data is added
+ * \param start_len ammount of memory to reserve initially
+ * \param max_len length the buffer is allowed to grow to
+ * \return status
+ */
+ESL_DECLARE(esl_status_t) esl_buffer_create(esl_buffer_t **buffer, esl_size_t blocksize, esl_size_t start_len, esl_size_t max_len);
+
+/*! \brief Get the length of a esl_buffer_t
+ * \param buffer any buffer of type esl_buffer_t
+ * \return int size of the buffer.
+ */
+ESL_DECLARE(esl_size_t) esl_buffer_len(esl_buffer_t *buffer);
+
+/*! \brief Get the freespace of a esl_buffer_t
+ * \param buffer any buffer of type esl_buffer_t
+ * \return int freespace in the buffer.
+ */
+ESL_DECLARE(esl_size_t) esl_buffer_freespace(esl_buffer_t *buffer);
+
+/*! \brief Get the in use amount of a esl_buffer_t
+ * \param buffer any buffer of type esl_buffer_t
+ * \return int ammount of buffer curently in use
+ */
+ESL_DECLARE(esl_size_t) esl_buffer_inuse(esl_buffer_t *buffer);
+
+/*! \brief Read data from a esl_buffer_t up to the ammount of datalen if it is available. Remove read data from buffer.
+ * \param buffer any buffer of type esl_buffer_t
+ * \param data pointer to the read data to be returned
+ * \param datalen amount of data to be returned
+ * \return int ammount of data actually read
+ */
+ESL_DECLARE(esl_size_t) esl_buffer_read(esl_buffer_t *buffer, void *data, esl_size_t datalen);
+
+ESL_DECLARE(esl_size_t) esl_buffer_read_packet(esl_buffer_t *buffer, void *data, esl_size_t maxlen);
+ESL_DECLARE(esl_size_t) esl_buffer_packet_count(esl_buffer_t *buffer);
+
+/*! \brief Read data endlessly from a esl_buffer_t
+ * \param buffer any buffer of type esl_buffer_t
+ * \param data pointer to the read data to be returned
+ * \param datalen amount of data to be returned
+ * \return int ammount of data actually read
+ * \note Once you have read all the data from the buffer it will loop around.
+ */
+ESL_DECLARE(esl_size_t) esl_buffer_read_loop(esl_buffer_t *buffer, void *data, esl_size_t datalen);
+
+/*! \brief Assign a number of loops to read
+ * \param buffer any buffer of type esl_buffer_t
+ * \param loops the number of loops (-1 for infinite)
+ */
+ESL_DECLARE(void) esl_buffer_set_loops(esl_buffer_t *buffer, int32_t loops);
+
+/*! \brief Write data into a esl_buffer_t up to the length of datalen
+ * \param buffer any buffer of type esl_buffer_t
+ * \param data pointer to the data to be written
+ * \param datalen amount of data to be written
+ * \return int amount of buffer used after the write, or 0 if no space available
+ */
+ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, esl_size_t datalen);
+
+/*! \brief Remove data from the buffer
+ * \param buffer any buffer of type esl_buffer_t
+ * \param datalen amount of data to be removed
+ * \return int size of buffer, or 0 if unable to toss that much data
+ */
+ESL_DECLARE(esl_size_t) esl_buffer_toss(esl_buffer_t *buffer, esl_size_t datalen);
+
+/*! \brief Remove all data from the buffer
+ * \param buffer any buffer of type esl_buffer_t
+ */
+ESL_DECLARE(void) esl_buffer_zero(esl_buffer_t *buffer);
+
+/*! \brief Destroy the buffer
+ * \param buffer buffer to destroy
+ * \note only neccessary on dynamic buffers (noop on pooled ones)
+ */
+ESL_DECLARE(void) esl_buffer_destroy(esl_buffer_t **buffer);
+
+/*! \brief Seek to offset from the beginning of the buffer
+ * \param buffer buffer to seek
+ * \param datalen offset in bytes
+ * \return new position
+ */
+ESL_DECLARE(esl_size_t) esl_buffer_seek(esl_buffer_t *buffer, esl_size_t datalen);
+
+/** @} */
+
+ESL_DECLARE(esl_size_t) esl_buffer_zwrite(esl_buffer_t *buffer, const void *data, esl_size_t datalen);
+
+#endif
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c
index ef3989c19c..c459a57c11 100755
--- a/libs/freetdm/mod_freetdm/mod_freetdm.c
+++ b/libs/freetdm/mod_freetdm/mod_freetdm.c
@@ -802,7 +802,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio
phy_id = ftdm_channel_get_ph_id(tech_pvt->ftdmchan);
ftdm_log(FTDM_LOG_DEBUG, "Got Freeswitch message in R2 channel %d [%d]\n", phy_id, msg->message_id);
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
return SWITCH_STATUS_SUCCESS;
}
@@ -849,7 +849,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
return SWITCH_STATUS_SUCCESS;
}
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
return SWITCH_STATUS_SUCCESS;
}
@@ -892,7 +892,7 @@ static switch_status_t channel_receive_message_fxo(switch_core_session_t *sessio
return SWITCH_STATUS_FALSE;
}
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
return SWITCH_STATUS_SUCCESS;
}
@@ -924,7 +924,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio
return SWITCH_STATUS_FALSE;
}
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
return SWITCH_STATUS_SUCCESS;
}
@@ -981,7 +981,7 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_PROGRESS:
case SWITCH_MESSAGE_INDICATE_ANSWER:
- if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
if ((var = switch_channel_get_variable(channel, "freetdm_pre_buffer_size"))) {
int tmp = atoi(var);
if (tmp > -1) {
@@ -1363,7 +1363,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
tech_pvt->caller_profile = caller_profile;
- switch_channel_set_flag(channel, CF_OUTBOUND);
switch_channel_set_state(channel, CS_INIT);
if (ftdm_channel_add_token(ftdmchan, switch_core_session_get_uuid(*new_session), ftdm_channel_get_token_count(ftdmchan)) != FTDM_SUCCESS) {
switch_core_session_destroy(new_session);
@@ -1811,7 +1810,9 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
}
- if (channel_a && channel_b && !switch_channel_test_flag(channel_a, CF_OUTBOUND) && !switch_channel_test_flag(channel_b, CF_OUTBOUND)) {
+ if (channel_a && channel_b && switch_channel_direction(channel_a) == SWITCH_CALL_DIRECTION_INBOUND &&
+ switch_channel_direction(channel_b) == SWITCH_CALL_DIRECTION_INBOUND) {
+
cause = SWITCH_CAUSE_ATTENDED_TRANSFER;
if (br_a_uuid && br_b_uuid) {
switch_ivr_uuid_bridge(br_a_uuid, br_b_uuid);
diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c
index 7320934a49..f40196499c 100644
--- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c
+++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c
@@ -53,42 +53,48 @@ static struct {
float txgain;
} zt_globals;
+#if defined(__FreeBSD__)
+typedef unsigned long ioctlcmd;
+#else
+typedef int ioctlcmd;
+#endif
+
/**
* \brief General IOCTL codes
*/
struct ioctl_codes {
- int GET_BLOCKSIZE;
- int SET_BLOCKSIZE;
- int FLUSH;
- int SYNC;
- int GET_PARAMS;
- int SET_PARAMS;
- int HOOK;
- int GETEVENT;
- int IOMUX;
- int SPANSTAT;
- int MAINT;
- int GETCONF;
- int SETCONF;
- int CONFLINK;
- int CONFDIAG;
- int GETGAINS;
- int SETGAINS;
- int SPANCONFIG;
- int CHANCONFIG;
- int SET_BUFINFO;
- int GET_BUFINFO;
- int AUDIOMODE;
- int ECHOCANCEL;
- int HDLCRAWMODE;
- int HDLCFCSMODE;
- int SPECIFY;
- int SETLAW;
- int SETLINEAR;
- int GETCONFMUTE;
- int ECHOTRAIN;
- int SETTXBITS;
- int GETRXBITS;
+ ioctlcmd GET_BLOCKSIZE;
+ ioctlcmd SET_BLOCKSIZE;
+ ioctlcmd FLUSH;
+ ioctlcmd SYNC;
+ ioctlcmd GET_PARAMS;
+ ioctlcmd SET_PARAMS;
+ ioctlcmd HOOK;
+ ioctlcmd GETEVENT;
+ ioctlcmd IOMUX;
+ ioctlcmd SPANSTAT;
+ ioctlcmd MAINT;
+ ioctlcmd GETCONF;
+ ioctlcmd SETCONF;
+ ioctlcmd CONFLINK;
+ ioctlcmd CONFDIAG;
+ ioctlcmd GETGAINS;
+ ioctlcmd SETGAINS;
+ ioctlcmd SPANCONFIG;
+ ioctlcmd CHANCONFIG;
+ ioctlcmd SET_BUFINFO;
+ ioctlcmd GET_BUFINFO;
+ ioctlcmd AUDIOMODE;
+ ioctlcmd ECHOCANCEL;
+ ioctlcmd HDLCRAWMODE;
+ ioctlcmd HDLCFCSMODE;
+ ioctlcmd SPECIFY;
+ ioctlcmd SETLAW;
+ ioctlcmd SETLINEAR;
+ ioctlcmd GETCONFMUTE;
+ ioctlcmd ECHOTRAIN;
+ ioctlcmd SETTXBITS;
+ ioctlcmd GETRXBITS;
};
/**
diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c
index 8425372ef5..6a75dc85ff 100644
--- a/libs/openzap/mod_openzap/mod_openzap.c
+++ b/libs/openzap/mod_openzap/mod_openzap.c
@@ -821,7 +821,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_RINGING:
{
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
} else {
zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
@@ -830,7 +830,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio
break;
case SWITCH_MESSAGE_INDICATE_PROGRESS:
{
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA);
} else {
@@ -841,7 +841,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio
break;
case SWITCH_MESSAGE_INDICATE_ANSWER:
{
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED);
} else {
/* lets make the ozmod_r2 module life easier by moving thru each
@@ -888,7 +888,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_RINGING:
{
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
} else {
zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
@@ -897,7 +897,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
break;
case SWITCH_MESSAGE_INDICATE_PROGRESS:
{
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_MEDIA);
} else {
@@ -914,7 +914,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
break;
case SWITCH_MESSAGE_INDICATE_ANSWER:
{
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED);
} else {
/* Don't skip messages in the ISDN call setup
@@ -957,7 +957,7 @@ static switch_status_t channel_receive_message_fxo(switch_core_session_t *sessio
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_PROGRESS:
case SWITCH_MESSAGE_INDICATE_ANSWER:
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED);
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA);
@@ -991,7 +991,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_PROGRESS:
case SWITCH_MESSAGE_INDICATE_ANSWER:
- if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED);
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA);
@@ -1000,7 +1000,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio
}
break;
case SWITCH_MESSAGE_INDICATE_RINGING:
- if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
if (!switch_channel_test_flag(channel, CF_ANSWERED) &&
!switch_channel_test_flag(channel, CF_EARLY_MEDIA) &&
@@ -1052,7 +1052,7 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_PROGRESS:
case SWITCH_MESSAGE_INDICATE_ANSWER:
- if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
if ((var = switch_channel_get_variable(channel, "openzap_pre_buffer_size"))) {
int tmp = atoi(var);
if (tmp > -1) {
@@ -1327,7 +1327,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
tech_pvt->caller_profile = caller_profile;
- switch_channel_set_flag(channel, CF_OUTBOUND);
switch_channel_set_state(channel, CS_INIT);
if (zap_channel_add_token(zchan, switch_core_session_get_uuid(*new_session), zchan->token_count) != ZAP_SUCCESS) {
switch_core_session_destroy(new_session);
@@ -1678,7 +1677,9 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
}
- if (channel_a && channel_b && !switch_channel_test_flag(channel_a, CF_OUTBOUND) && !switch_channel_test_flag(channel_b, CF_OUTBOUND)) {
+ if (channel_a && channel_b && switch_channel_direction(channel_a) == SWITCH_CALL_DIRECTION_INBOUND &&
+ switch_channel_direction(channel_b) == SWITCH_CALL_DIRECTION_INBOUND) {
+
cause = SWITCH_CAUSE_ATTENDED_TRANSFER;
if (br_a_uuid && br_b_uuid) {
switch_ivr_uuid_bridge(br_a_uuid, br_b_uuid);
diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c
index 547c337278..2ffb86fdb6 100644
--- a/libs/stfu/stfu.c
+++ b/libs/stfu/stfu.c
@@ -33,11 +33,21 @@
# define UINT_MAX 4294967295U
#endif
+#ifndef UINT16_MAX
+# define UINT16_MAX 65535
+#endif
+
#ifdef _MSC_VER
/* warning C4706: assignment within conditional expression*/
#pragma warning(disable: 4706)
+/* warning C4996: 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strdup. See online help for details. */
+#pragma warning(disable:4996)
#endif
+#define least1(_z) (_z ? _z : 1)
+
+static int stfu_log_level = 7;
+
struct stfu_queue {
struct stfu_frame *array;
struct stfu_frame int_frame;
@@ -53,13 +63,13 @@ typedef struct stfu_queue stfu_queue_t;
struct stfu_instance {
struct stfu_queue a_queue;
struct stfu_queue b_queue;
+ struct stfu_queue c_queue;
struct stfu_queue *in_queue;
struct stfu_queue *out_queue;
+ struct stfu_queue *old_queue;
struct stfu_frame *last_frame;
uint32_t cur_ts;
- uint32_t cur_seq;
uint32_t last_wr_ts;
- uint32_t last_wr_seq;
uint32_t last_rd_ts;
uint32_t samples_per_packet;
uint32_t samples_per_second;
@@ -76,6 +86,7 @@ struct stfu_instance {
uint32_t period_packet_in_count;
uint32_t period_packet_out_count;
uint32_t period_missing_count;
+
uint32_t period_need_range;
uint32_t period_need_range_avg;
uint32_t period_clean_count;
@@ -86,25 +97,55 @@ struct stfu_instance {
uint32_t session_packet_in_count;
uint32_t session_packet_out_count;
- uint32_t sync;
+ uint32_t sync_out;
+ uint32_t sync_in;
int32_t ts_diff;
int32_t last_ts_diff;
int32_t same_ts;
- uint32_t last_seq;
-
uint32_t period_time;
uint32_t decrement_time;
uint32_t plc_len;
+ uint32_t plc_pt;
+ uint32_t diff;
+ uint32_t diff_total;
+ uint8_t ready;
+ uint8_t debug;
+ char *name;
stfu_n_call_me_t callback;
void *udata;
};
static void stfu_n_reset_counters(stfu_instance_t *i);
+static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...);
+static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...);
+
+stfu_logger_t stfu_log = null_logger;
+
+void stfu_global_set_logger(stfu_logger_t logger)
+{
+ if (logger) {
+ stfu_log = logger;
+ } else {
+ stfu_log = null_logger;
+ }
+}
+
+void stfu_global_set_default_logger(int level)
+{
+ if (level < 0 || level > 7) {
+ level = 7;
+ }
+
+ stfu_log = default_logger;
+ stfu_log_level = level;
+}
+
+
static stfu_status_t stfu_n_resize_aqueue(stfu_queue_t *queue, uint32_t qlen)
{
@@ -151,12 +192,27 @@ void stfu_n_destroy(stfu_instance_t **i)
if (i && *i) {
ii = *i;
*i = NULL;
+ if (ii->name) free(ii->name);
free(ii->a_queue.array);
free(ii->b_queue.array);
+ free(ii->c_queue.array);
free(ii);
}
}
+void stfu_n_debug(stfu_instance_t *i, const char *name)
+{
+ if (i->name) free(i->name);
+
+ if (name) {
+ i->name = strdup(name);
+ i->debug = 1;
+ } else {
+ i->name = strdup("none");
+ i->debug = 0;
+ }
+}
+
void stfu_n_report(stfu_instance_t *i, stfu_report_t *r)
{
assert(i);
@@ -172,7 +228,6 @@ 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;
}
@@ -180,13 +235,14 @@ 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;
}
}
if ((s = stfu_n_resize_aqueue(&i->a_queue, qlen)) == STFU_IT_WORKED) {
s = stfu_n_resize_aqueue(&i->b_queue, qlen);
+ s = stfu_n_resize_aqueue(&i->c_queue, qlen);
+
i->qlen = qlen;
i->max_plc = 5;
i->last_frame = NULL;
@@ -205,11 +261,6 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_
}
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;
@@ -217,8 +268,12 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_
stfu_n_init_aqueue(&i->a_queue, qlen);
stfu_n_init_aqueue(&i->b_queue, qlen);
+ stfu_n_init_aqueue(&i->c_queue, qlen);
+
i->in_queue = &i->a_queue;
i->out_queue = &i->b_queue;
+ i->old_queue = &i->c_queue;
+ i->name = strdup("none");
i->max_plc = i->qlen / 2;
@@ -232,9 +287,9 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_
static void stfu_n_reset_counters(stfu_instance_t *i)
{
-#ifdef DB_JB
- printf("COUNTER RESET........\n");
-#endif
+ if (stfu_log != null_logger && i->debug) {
+ stfu_log(STFU_LOG_EMERG, "%s COUNTER RESET........\n", i->name);
+ }
if (i->callback) {
i->callback(i, i->udata);
@@ -248,36 +303,44 @@ static void stfu_n_reset_counters(stfu_instance_t *i)
i->period_packet_in_count = 0;
i->period_packet_out_count = 0;
i->period_missing_count = 0;
+
i->period_need_range = 0;
i->period_need_range_avg = 0;
+
+ i->diff = 0;
+ i->diff_total = 0;
+
}
void stfu_n_reset(stfu_instance_t *i)
{
-#ifdef DB_JB
- printf("RESET\n");
-#endif
+ if (stfu_log != null_logger && i->debug) {
+ stfu_log(STFU_LOG_EMERG, "%s RESET\n", i->name);
+ }
+
+ i->ready = 0;
i->in_queue = &i->a_queue;
i->out_queue = &i->b_queue;
+ i->old_queue = &i->c_queue;
+
i->in_queue->array_len = 0;
i->out_queue->array_len = 0;
i->out_queue->wr_len = 0;
i->last_frame = NULL;
-
i->in_queue->last_jitter = 0;
i->out_queue->last_jitter = 0;
+
stfu_n_reset_counters(i);
-
- i->last_seq = 0;
-
+ stfu_n_sync(i, 1);
+
i->cur_ts = 0;
- i->cur_seq = 0;
i->last_wr_ts = 0;
- i->last_wr_seq = 0;
i->last_rd_ts = 0;
i->miss_count = 0;
i->packet_count = 0;
+
+
}
stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets)
@@ -286,20 +349,39 @@ stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets)
if (packets > i->qlen) {
stfu_n_reset(i);
} else {
- i->sync = packets;
+ i->sync_out = packets;
+ i->sync_in = packets;
}
return STFU_IT_WORKED;
}
-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)
+static void stfu_n_swap(stfu_instance_t *i)
+{
+ stfu_queue_t *last_in = i->in_queue, *last_out = i->out_queue, *last_old = i->old_queue;
+
+ i->ready = 1;
+
+ i->in_queue = last_out;
+ i->out_queue = last_old;
+ i->old_queue = last_in;
+
+ i->in_queue->array_len = 0;
+ i->out_queue->wr_len = 0;
+ i->last_frame = NULL;
+ i->miss_count = 0;
+ i->in_queue->last_index = 0;
+ i->out_queue->last_index = 0;
+ i->out_queue->last_jitter = 0;
+}
+
+stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, int last)
{
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;
+ int good_ts = 0;
if (!i->samples_per_packet && ts && i->last_rd_ts) {
i->ts_diff = ts - i->last_rd_ts;
@@ -320,16 +402,27 @@ 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) || (i->last_seq > 65500 && seq == 0)) {
- good_seq = 1;
- }
-
- if ((ts && ts == i->last_rd_ts + i->samples_per_packet) || (i->last_rd_ts > 4294900000 && ts < 5000)) {
+ if (i->sync_in) {
good_ts = 1;
+ i->sync_in = 0;
+ } else {
+
+ if ((ts && ts == i->last_rd_ts + i->samples_per_packet) || (i->last_rd_ts > 4294900000 && ts < 5000)) {
+ good_ts = 1;
+ }
+
+ if (i->last_wr_ts) {
+ if ((ts <= i->last_wr_ts && (i->last_wr_ts != UINT_MAX || ts == i->last_wr_ts))) {
+ stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts);
+ if (i->in_queue->array_len < i->in_queue->array_size) {
+ i->in_queue->array_len++;
+ }
+ return STFU_ITS_TOO_LATE;
+ }
+ }
}
-
- if (good_seq || good_ts) {
+ if (good_ts) {
i->period_clean_count++;
i->session_clean_count++;
}
@@ -337,12 +430,12 @@ 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++;
- i->period_need_range_avg = i->period_need_range / (i->period_missing_count || 1);
+ i->period_need_range_avg = i->period_need_range / least1(i->period_missing_count);
if (i->period_missing_count > i->qlen * 2) {
-#ifdef DB_JB
- printf("resize %u %u\n", i->qlen, i->qlen + 1);
-#endif
+ if (stfu_log != null_logger && i->debug) {
+ stfu_log(STFU_LOG_EMERG, "%s resize %u %u\n", i->name, i->qlen, i->qlen + 1);
+ }
stfu_n_resize(i, i->qlen + 1);
stfu_n_reset_counters(i);
} else {
@@ -353,7 +446,24 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin
}
}
+
+ i->diff = 0;
+
+ if (i->last_wr_ts) {
+ if (ts < 1000 && i->last_wr_ts > (UINT_MAX - 1000)) {
+ i->diff = abs(((UINT_MAX - i->last_wr_ts) + ts) / i->samples_per_packet);
+ } else if (ts) {
+ i->diff = abs(i->last_wr_ts - ts) / i->samples_per_packet;
+ }
+ }
+
+ i->diff_total += i->diff;
+
if ((i->period_packet_in_count > i->period_time)) {
+ uint32_t avg;
+
+ avg = i->diff_total / least1(i->period_packet_in_count);
+
i->period_packet_in_count = 0;
if (i->period_missing_count == 0 && i->qlen > i->orig_qlen) {
@@ -364,68 +474,38 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin
stfu_n_reset_counters(i);
}
-#ifdef DB_JB
- printf("%u i=%u/%u - g:%u/%u c:%u/%u b:%u - %u/%u - %u %d\n",
- i->qlen, i->period_packet_in_count, i->period_time, i->consecutive_good_count,
- i->decrement_time, i->period_clean_count, i->decrement_time, i->consecutive_bad_count,
- seq, ts,
- i->period_missing_count, i->period_need_range_avg);
-#endif
+
+
+ if (stfu_log != null_logger && i->debug) {
+ stfu_log(STFU_LOG_EMERG, "%s %u i=%u/%u - g:%u/%u c:%u/%u b:%u - %u:%u - %u %d %u %u %d %d\n", i->name,
+ i->qlen, i->period_packet_in_count, i->period_time, i->consecutive_good_count,
+ i->decrement_time, i->period_clean_count, i->decrement_time, i->consecutive_bad_count,
+ ts, ts / i->samples_per_packet,
+ i->period_missing_count, i->period_need_range_avg,
+ i->last_wr_ts, ts, i->diff, i->diff_total / least1(i->period_packet_in_count));
+ }
if (last || i->in_queue->array_len == i->in_queue->array_size) {
- stfu_queue_t *other_queue;
-
- other_queue = i->in_queue;
- i->in_queue = i->out_queue;
- i->out_queue = other_queue;
-
- i->in_queue->array_len = 0;
- i->out_queue->wr_len = 0;
- i->last_frame = NULL;
- i->miss_count = 0;
- i->in_queue->last_index = 0;
- i->out_queue->last_index = 0;
- i->out_queue->last_jitter = 0;
+ stfu_n_swap(i);
}
if (last) {
return STFU_IM_DONE;
}
- 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 = min_index;
-
- if (i->in_queue->array_len < i->in_queue->array_size) {
- i->in_queue->array_len++;
- }
-
+ index = i->in_queue->array_len++;
assert(index < i->in_queue->array_size);
-
frame = &i->in_queue->array[index];
+ if (i->in_queue->array_len == i->in_queue->array_size) {
+ stfu_n_swap(i);
+ }
+
if ((cplen = datalen) > sizeof(frame->data)) {
cplen = sizeof(frame->data);
}
- i->last_seq = seq;
i->last_rd_ts = ts;
i->packet_count++;
@@ -433,44 +513,13 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin
frame->pt = pt;
frame->ts = ts;
- frame->seq = seq;
frame->dlen = cplen;
frame->was_read = 0;
return STFU_IT_WORKED;
}
-static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_frame_t **r_frame)
-{
- uint32_t i = 0;
- stfu_frame_t *frame = NULL;
- stfu_queue_t *queue;
-
- assert(r_frame);
-
- *r_frame = NULL;
-
- for (queue = in->out_queue ; queue && queue != in->in_queue ; queue = in->in_queue) {
-
- for(i = 0; i < queue->real_array_size; i++) {
- frame = &queue->array[i];
- if (!frame->was_read) {
- *r_frame = frame;
- queue->last_index = i;
- frame->was_read = 1;
- in->period_packet_out_count++;
- in->session_packet_out_count++;
- return 1;
- }
- }
-
- }
-
- return 0;
-}
-
-
-static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t ts, uint32_t seq, stfu_frame_t **r_frame)
+static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_queue_t *queue, stfu_frame_t **r_frame)
{
uint32_t i = 0;
stfu_frame_t *frame = NULL;
@@ -481,8 +530,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 || in->last_seq) && frame->seq == seq) || frame->ts == ts) {
+ if (!frame->was_read) {
*r_frame = frame;
queue->last_index = i;
frame->was_read = 1;
@@ -492,6 +540,34 @@ static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t
}
}
+ return 0;
+}
+
+
+static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_frame)
+{
+ uint32_t i = 0;
+ stfu_frame_t *frame = NULL;
+
+ if (r_frame) {
+ *r_frame = NULL;
+ }
+
+ for(i = 0; i < queue->array_size; i++) {
+ frame = &queue->array[i];
+
+ if (frame->ts == ts) {
+ if (r_frame) {
+ *r_frame = frame;
+ queue->last_index = i;
+ frame->was_read = 1;
+ in->period_packet_out_count++;
+ in->session_packet_out_count++;
+ }
+ return 1;
+ }
+ }
+
return 0;
}
@@ -500,48 +576,76 @@ 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->array_len) {
- //|| ((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) {
- return NULL;
- }
-
- if (i->cur_ts == 0) {
- i->cur_ts = i->out_queue->array[0].ts;
- } else {
- i->cur_ts += i->samples_per_packet;
+ if (!i->samples_per_packet) {
+ return NULL;
}
- if (i->cur_seq == 0) {
- i->cur_seq = i->out_queue->array[0].seq;
+ if (!i->ready) {
+ if (stfu_log != null_logger && i->debug) {
+ stfu_log(STFU_LOG_EMERG, "%s XXXSKIP\n", i->name);
+ }
+ return NULL;
+ }
+
+
+ if (i->cur_ts == 0 && i->last_wr_ts < 1000) {
+ uint32_t x = 0;
+ for (x = 0; x < i->out_queue->array_len; x++) {
+ if (!i->out_queue->array[x].was_read) {
+ i->cur_ts = i->out_queue->array[x].ts;
+ break;
+ }
+ if (i->cur_ts == 0) {
+ if (stfu_log != null_logger && i->debug) {
+ stfu_log(STFU_LOG_EMERG, "%s XXXPUNT\n", i->name);
+ return NULL;
+ }
+ }
+ }
} else {
- 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;
+ i->cur_ts = i->cur_ts + i->samples_per_packet;
+ }
+
+ found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, &rframe);
+
+ if (found) {
+ if (i->out_queue->array_len) {
+ i->out_queue->array_len--;
+ }
+ } else {
+ found = stfu_n_find_frame(i, i->in_queue, i->cur_ts, &rframe);
+
+ if (!found) {
+ found = stfu_n_find_frame(i, i->old_queue, i->cur_ts, &rframe);
}
}
- if (!(found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, i->cur_seq, &rframe))) {
- found = stfu_n_find_frame(i, i->in_queue, i->cur_ts, i->cur_seq, &rframe);
+ if (i->sync_out) {
+ if (!found) {
+ if ((found = stfu_n_find_any_frame(i, i->out_queue, &rframe))) {
+ i->cur_ts = rframe->ts;
+ }
+
+ if (stfu_log != null_logger && i->debug) {
+ stfu_log(STFU_LOG_EMERG, "%s SYNC %u %u:%u\n", i->name, i->sync_out, i->cur_ts, i->cur_ts / i->samples_per_packet);
+ }
+
+ }
+ i->sync_out = 0;
}
- if (!found && i->sync) {
-#ifdef DB_JB
- printf("SYNC %u\n", i->sync);
-#endif
- if ((found = stfu_n_find_any_frame(i, &rframe))) {
- i->cur_seq = rframe->seq;
- i->cur_ts = rframe->ts;
+ if (!i->cur_ts) {
+ if (stfu_log != null_logger && i->debug) {
+ stfu_log(STFU_LOG_EMERG, "%s NO TS\n", i->name);
}
- i->sync = 0;
+ return NULL;
}
if (!found && i->samples_per_packet) {
-#ifdef DB_JB
- int y;
+ uint32_t y;
stfu_frame_t *frame = NULL;
-#endif
+
int32_t delay = i->last_rd_ts - i->cur_ts;
uint32_t need = abs(i->last_rd_ts - i->cur_ts) / i->samples_per_packet;
@@ -550,30 +654,33 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
i->session_missing_count++;
i->period_need_range += need;
-#ifdef DB_JB
- printf("MISSING %u %u %u %u %d %u %d\n", i->cur_seq, i->cur_ts, i->packet_count, i->last_rd_ts, delay, i->qlen, need);
-#endif
+ if (stfu_log != null_logger && i->debug) {
+ stfu_log(STFU_LOG_EMERG, "%s MISSING %u:%u %u %u %d %u %d\n", i->name,
+ i->cur_ts, i->cur_ts / i->samples_per_packet, i->packet_count, i->last_rd_ts, delay, i->qlen, need);
+ }
if (i->packet_count > i->orig_qlen * 100 && delay > 0 && need > i->qlen && need < (i->qlen + 5)) {
i->packet_count = 0;
}
-#ifdef DB_JB
- for(y = 0; y < i->out_queue->array_size; y++) {
- if ((y % 5) == 0) printf("\n");
- frame = &i->out_queue->array[y];
- printf("%u:%u\t", frame->seq, frame->ts);
- }
- printf("\n\n");
+ if (stfu_log != null_logger && i->debug) {
+ stfu_log(STFU_LOG_EMERG, "%s ", i->name);
+ for(y = 0; y < i->out_queue->array_size; y++) {
+ if ((y % 5) == 0) stfu_log(STFU_LOG_EMERG, "\n%s ", i->name);
+ frame = &i->out_queue->array[y];
+ stfu_log(STFU_LOG_EMERG, "%u:%u\t", frame->ts, frame->ts / i->samples_per_packet);
+ }
+ stfu_log(STFU_LOG_EMERG, "\n%s ", i->name);
- for(y = 0; y < i->in_queue->array_size; y++) {
- if ((y % 5) == 0) printf("\n");
- frame = &i->in_queue->array[y];
- printf("%u:%u\t", frame->seq, frame->ts);
+ for(y = 0; y < i->in_queue->array_size; y++) {
+ if ((y % 5) == 0) stfu_log(STFU_LOG_EMERG, "\n%s ", i->name);
+ frame = &i->in_queue->array[y];
+ stfu_log(STFU_LOG_EMERG, "%u:%u\t", frame->ts, frame->ts / i->samples_per_packet);
+ }
+ stfu_log(STFU_LOG_EMERG, "\n%s\n\n\n", i->name);
+
}
- printf("\n\n");
-#endif
if (delay < 0) {
stfu_n_reset(i);
@@ -581,14 +688,11 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
}
}
-#ifdef DB_JB
- if (found) {
- 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);
+ if (stfu_log != null_logger && i->debug) {
+ if (found) {
+ stfu_log(STFU_LOG_EMERG, "%s O: %u:%u %u\n", i->name, rframe->ts, rframe->ts / i->samples_per_packet, rframe->plc);
+ }
}
-#endif
-
if (found) {
i->consecutive_good_count++;
@@ -602,36 +706,28 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
if (found) {
i->last_frame = rframe;
- i->out_queue->wr_len++;
- i->last_wr_ts = rframe->ts;
- i->last_wr_seq = rframe->seq;
- i->miss_count = 0;
+ i->out_queue->wr_len++;
+ i->last_wr_ts = rframe->ts;
+
+ i->miss_count = 0;
if (rframe->dlen) {
i->plc_len = rframe->dlen;
}
+
+ i->plc_pt = rframe->pt;
+
} else {
i->last_wr_ts = i->cur_ts;
- i->last_wr_seq = i->cur_seq;
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) {
- memset(rframe->data, 255, rframe->dlen);
- } else {
- memcpy(rframe->data, i->last_frame->data, rframe->dlen);
- }
- }
-#endif
+ rframe->pt = i->plc_pt;
rframe->ts = i->cur_ts;
-
i->miss_count++;
-
-#ifdef DB_JB
- printf("PLC %d %d %ld %u %u\n", i->miss_count, rframe->plc, rframe->dlen, rframe->seq, rframe->ts);
-#endif
+
+ if (stfu_log != null_logger && i->debug) {
+ stfu_log(STFU_LOG_EMERG, "%s PLC %d %d %ld %u:%u\n", i->name,
+ i->miss_count, rframe->plc, rframe->dlen, rframe->ts, rframe->ts / i->samples_per_packet);
+ }
if (i->miss_count > i->max_plc) {
stfu_n_reset(i);
@@ -639,9 +735,138 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
}
}
- return rframe;
+ return rframe;
}
+#ifdef WIN32
+#ifndef vsnprintf
+#define vsnprintf _vsnprintf
+#endif
+#endif
+
+
+int vasprintf(char **ret, const char *format, va_list ap);
+
+int stfu_vasprintf(char **ret, const char *fmt, va_list ap)
+{
+#if !defined(WIN32) && !defined(__sun)
+ return vasprintf(ret, fmt, ap);
+#else
+ char *buf;
+ int len;
+ size_t buflen;
+ va_list ap2;
+ char *tmp = NULL;
+
+#ifdef _MSC_VER
+#if _MSC_VER >= 1500
+ /* hack for incorrect assumption in msvc header files for code analysis */
+ __analysis_assume(tmp);
+#endif
+ ap2 = ap;
+#else
+ va_copy(ap2, ap);
+#endif
+
+ len = vsnprintf(tmp, 0, fmt, ap2);
+
+ if (len > 0 && (buf = malloc((buflen = (size_t) (len + 1)))) != NULL) {
+ len = vsnprintf(buf, buflen, fmt, ap);
+ *ret = buf;
+ } else {
+ *ret = NULL;
+ len = -1;
+ }
+
+ va_end(ap2);
+ return len;
+#endif
+}
+
+
+
+
+int stfu_snprintf(char *buffer, size_t count, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = vsnprintf(buffer, count-1, fmt, ap);
+ if (ret < 0)
+ buffer[count-1] = '\0';
+ va_end(ap);
+ return ret;
+}
+
+static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
+{
+ if (file && func && line && level && fmt) {
+ return;
+ }
+ return;
+}
+
+
+
+static const char *LEVEL_NAMES[] = {
+ "EMERG",
+ "ALERT",
+ "CRIT",
+ "ERROR",
+ "WARNING",
+ "NOTICE",
+ "INFO",
+ "DEBUG",
+ NULL
+};
+
+static const char *cut_path(const char *in)
+{
+ const char *p, *ret = in;
+ char delims[] = "/\\";
+ char *i;
+
+ for (i = delims; *i; i++) {
+ p = in;
+ while ((p = strchr(p, *i)) != 0) {
+ ret = ++p;
+ }
+ }
+ return ret;
+}
+
+
+static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
+{
+ const char *fp;
+ char *data;
+ va_list ap;
+ int ret;
+
+ if (level < 0 || level > 7) {
+ level = 7;
+ }
+ if (level > stfu_log_level) {
+ return;
+ }
+
+ fp = cut_path(file);
+
+ va_start(ap, fmt);
+
+ ret = stfu_vasprintf(&data, fmt, ap);
+
+ if (ret != -1) {
+ fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], file, line, func, data);
+ free(data);
+ }
+
+ va_end(ap);
+
+}
+
+
/* For Emacs:
* Local Variables:
* mode:c
diff --git a/libs/stfu/stfu.h b/libs/stfu/stfu.h
index d2760b27bc..ad769c62e2 100644
--- a/libs/stfu/stfu.h
+++ b/libs/stfu/stfu.h
@@ -38,6 +38,8 @@ extern "C" {
#include
#include
#include
+#include
+
#ifdef _MSC_VER
#ifndef uint32_t
@@ -62,6 +64,85 @@ typedef unsigned long in_addr_t;
#endif
#include
+
+
+#ifdef WIN32
+#include
+#include
+typedef SOCKET stfu_socket_t;
+typedef unsigned __int64 uint64_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int8 uint8_t;
+typedef __int64 int64_t;
+typedef __int32 int32_t;
+typedef __int16 int16_t;
+typedef __int8 int8_t;
+typedef intptr_t stfu_ssize_t;
+typedef int stfu_filehandle_t;
+#define STFU_SOCK_INVALID INVALID_SOCKET
+#define strerror_r(num, buf, size) strerror_s(buf, size, num)
+#if defined(STFU_DECLARE_STATIC)
+#define STFU_DECLARE(type) type __stdcall
+#define STFU_DECLARE_NONSTD(type) type __cdecl
+#define STFU_DECLARE_DATA
+#elif defined(STFU_EXPORTS)
+#define STFU_DECLARE(type) __declspec(dllexport) type __stdcall
+#define STFU_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl
+#define STFU_DECLARE_DATA __declspec(dllexport)
+#else
+#define STFU_DECLARE(type) __declspec(dllimport) type __stdcall
+#define STFU_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl
+#define STFU_DECLARE_DATA __declspec(dllimport)
+#endif
+#else
+#define STFU_DECLARE(type) type
+#define STFU_DECLARE_NONSTD(type) type
+#define STFU_DECLARE_DATA
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#define STFU_SOCK_INVALID -1
+typedef int stfu_socket_t;
+typedef ssize_t stfu_ssize_t;
+typedef int stfu_filehandle_t;
+#endif
+
+
+#define STFU_PRE __FILE__, __FUNCTION__, __LINE__
+#define STFU_LOG_LEVEL_DEBUG 7
+#define STFU_LOG_LEVEL_INFO 6
+#define STFU_LOG_LEVEL_NOTICE 5
+#define STFU_LOG_LEVEL_WARNING 4
+#define STFU_LOG_LEVEL_ERROR 3
+#define STFU_LOG_LEVEL_CRIT 2
+#define STFU_LOG_LEVEL_ALERT 1
+#define STFU_LOG_LEVEL_EMERG 0
+
+#define STFU_LOG_DEBUG STFU_PRE, STFU_LOG_LEVEL_DEBUG
+#define STFU_LOG_INFO STFU_PRE, STFU_LOG_LEVEL_INFO
+#define STFU_LOG_NOTICE STFU_PRE, STFU_LOG_LEVEL_NOTICE
+#define STFU_LOG_WARNING STFU_PRE, STFU_LOG_LEVEL_WARNING
+#define STFU_LOG_ERROR STFU_PRE, STFU_LOG_LEVEL_ERROR
+#define STFU_LOG_CRIT STFU_PRE, STFU_LOG_LEVEL_CRIT
+#define STFU_LOG_ALERT STFU_PRE, STFU_LOG_LEVEL_ALERT
+#define STFU_LOG_EMERG STFU_PRE, STFU_LOG_LEVEL_EMERG
+typedef void (*stfu_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...);
+
+
+int stfu_vasprintf(char **ret, const char *fmt, va_list ap);
+
+extern stfu_logger_t stfu_log;
+
+/*! Sets the logger for libstfu. Default is the null_logger */
+void stfu_global_set_logger(stfu_logger_t logger);
+/*! Sets the default log level for libstfu */
+void stfu_global_set_default_logger(int level);
+
#define STFU_DATALEN 16384
#define STFU_QLEN 300
#define STFU_MAX_TRACK 256
@@ -69,13 +150,13 @@ typedef unsigned long in_addr_t;
typedef enum {
STFU_IT_FAILED,
STFU_IT_WORKED,
- STFU_IM_DONE
+ STFU_IM_DONE,
+ STFU_ITS_TOO_LATE
} stfu_status_t;
struct stfu_frame {
uint32_t ts;
uint32_t pt;
- uint32_t seq;
uint8_t data[STFU_DATALEN];
size_t dlen;
uint8_t was_read;
@@ -100,14 +181,15 @@ void stfu_n_report(stfu_instance_t *i, stfu_report_t *r);
void stfu_n_destroy(stfu_instance_t **i);
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second);
stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen);
-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);
+stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, int last);
stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i);
void stfu_n_reset(stfu_instance_t *i);
stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets);
void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata);
+void stfu_n_debug(stfu_instance_t *i, const char *name);
#define stfu_im_done(i) stfu_n_add_data(i, 0, NULL, 0, 1)
-#define stfu_n_eat(i,t,s,p,d,l) stfu_n_add_data(i, t, s, p, d, l, 0)
+#define stfu_n_eat(i,t,p,d,l) stfu_n_add_data(i, t, p, d, l, 0)
#ifdef __cplusplus
}
diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h
index e3e9f665a3..c48a40e6d1 100644
--- a/src/include/switch_rtp.h
+++ b/src/include/switch_rtp.h
@@ -234,6 +234,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *
uint32_t max_queue_frames,
uint32_t samples_per_packet, uint32_t samples_per_second);
+SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name);
+
SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session);
/*!
diff --git a/src/include/switch_types.h b/src/include/switch_types.h
index d020775d48..e04f437eb3 100644
--- a/src/include/switch_types.h
+++ b/src/include/switch_types.h
@@ -1095,6 +1095,7 @@ typedef enum {
CF_BRIDGE_NOWRITE,
CF_RECOVERED,
CF_JITTERBUFFER,
+ CF_DIALPLAN,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
CF_FLAG_MAX
} switch_channel_flag_t;
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index 9b170a32e0..53ce82b4cb 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -2456,7 +2456,7 @@ static void conference_loop_output(conference_member_t *member)
switch_event_destroy(&event);
}
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
/* test to see if outbound channel has answered */
if (switch_channel_test_flag(channel, CF_ANSWERED) && !switch_test_flag(member->conference, CFLAG_ANSWERED)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG,
@@ -2599,7 +2599,7 @@ static void conference_loop_output(conference_member_t *member)
switch_channel_cause2str(switch_channel_get_cause(channel)));
/* if it's an outbound channel, store the release cause in the conference struct, we might need it */
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
member->conference->bridge_hangup_cause = switch_channel_get_cause(channel);
}
@@ -5446,7 +5446,7 @@ SWITCH_STANDARD_APP(conference_function)
launch_conference_thread(conference);
} else {
- int enforce_security = !switch_channel_test_flag(channel, CF_OUTBOUND);
+ int enforce_security = switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND;
const char *pvar = switch_channel_get_variable(channel, "conference_enforce_security");
if (pvar) {
@@ -5655,7 +5655,7 @@ SWITCH_STANDARD_APP(conference_function)
} else {
/* if we're not using "bridge:" set the conference answered flag */
/* and this isn't an outbound channel, answer the call */
- if (!switch_channel_test_flag(channel, CF_OUTBOUND))
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND)
switch_set_flag(conference, CFLAG_ANSWERED);
}
diff --git a/src/mod/applications/mod_spy/mod_spy.c b/src/mod/applications/mod_spy/mod_spy.c
index 5093ad8f22..cb8981d264 100644
--- a/src/mod/applications/mod_spy/mod_spy.c
+++ b/src/mod/applications/mod_spy/mod_spy.c
@@ -131,7 +131,6 @@ SWITCH_STANDARD_API(dump_hash)
static switch_status_t process_event(switch_event_t *event)
{
switch_core_session_t *session = NULL;
- switch_channel_t *channel;
char *username[3] = { 0 };
char *domain[3] = { 0 };
char key[512];
@@ -172,18 +171,19 @@ static switch_status_t process_event(switch_event_t *event)
return SWITCH_STATUS_FALSE;
}
- session = switch_core_session_locate(uuid);
- channel = switch_core_session_get_channel(session);
+ if ((session = switch_core_session_locate(uuid))) {
+ switch_channel_t *channel = switch_core_session_get_channel(session);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop \n", uuid, key);
- my_uuid = switch_event_get_header(event, "Unique-ID");
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop \n", uuid, key);
+ my_uuid = switch_event_get_header(event, "Unique-ID");
- switch_channel_set_variable(channel, "spy_uuid", my_uuid);
+ switch_channel_set_variable(channel, "spy_uuid", my_uuid);
- switch_channel_set_state(channel, CS_EXCHANGE_MEDIA);
- switch_channel_set_flag(channel, CF_BREAK);
+ switch_channel_set_state(channel, CS_EXCHANGE_MEDIA);
+ switch_channel_set_flag(channel, CF_BREAK);
- switch_core_session_rwunlock(session);
+ switch_core_session_rwunlock(session);
+ }
return SWITCH_STATUS_SUCCESS;
}
diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp
index 7e20b7c25e..13e433557d 100644
--- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp
+++ b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp
@@ -1324,7 +1324,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
caller_profile = tech_pvt->caller_profile;
caller_profile->destination_number = rdest;
- switch_channel_set_flag(channel, CF_OUTBOUND);
switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
switch_channel_set_state(channel, CS_INIT);
gsmopen_call(tech_pvt, rdest, 30);
diff --git a/src/mod/endpoints/mod_h323/mod_h323.cpp b/src/mod/endpoints/mod_h323/mod_h323.cpp
index 74fb6ae11a..3d79917434 100644
--- a/src/mod/endpoints/mod_h323/mod_h323.cpp
+++ b/src/mod/endpoints/mod_h323/mod_h323.cpp
@@ -725,7 +725,6 @@ FSH323Connection::FSH323Connection(FSH323EndPoint& endpoint, H323Transport* tran
name += outbound_profile->destination_number;
switch_channel_set_name(m_fsChannel, name);
- switch_channel_set_flag(m_fsChannel, CF_OUTBOUND);
switch_channel_set_state(m_fsChannel, CS_INIT);
}
@@ -1508,7 +1507,7 @@ switch_status_t FSH323Connection::receive_message(switch_core_session_message_t
break;
}
case SWITCH_MESSAGE_INDICATE_ANSWER: {
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
return SWITCH_STATUS_FALSE;
}
AnsweringCall(H323Connection::AnswerCallNow);
diff --git a/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp b/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp
index 3abbe3ecfb..1b126eb277 100644
--- a/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp
+++ b/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp
@@ -868,7 +868,6 @@ switch_status_t Board::KhompPvt::justStart(switch_caller_profile_t *profile)
_caller_profile = switch_caller_profile_clone(_session, profile);
switch_channel_set_caller_profile(channel, _caller_profile);
- switch_channel_set_flag(channel, CF_OUTBOUND);
switch_channel_set_state(channel, CS_INIT);
}
else
diff --git a/src/mod/endpoints/mod_opal/mod_opal.cpp b/src/mod/endpoints/mod_opal/mod_opal.cpp
index 8935bbb06d..0760588019 100644
--- a/src/mod/endpoints/mod_opal/mod_opal.cpp
+++ b/src/mod/endpoints/mod_opal/mod_opal.cpp
@@ -580,7 +580,6 @@ FSConnection::FSConnection(OpalCall & call, FSEndPoint & endpoint, void* userDat
name += outbound_profile->destination_number;
switch_channel_set_name(m_fsChannel, name);
- switch_channel_set_flag(m_fsChannel, CF_OUTBOUND);
switch_channel_set_state(m_fsChannel, CS_INIT);
}
}
@@ -966,7 +965,7 @@ switch_status_t FSConnection::receive_message(switch_core_session_message_t *msg
It would only happen if someone called switch_channel_answer() instead of switch_channel_mark_answered() on an outbound call.
it should not do anything if someone does it by accident somewhere hense this in both cases:
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
return SWITCH_STATUS_FALSE;
}
@@ -1025,7 +1024,7 @@ switch_status_t FSConnection::receive_message(switch_core_session_message_t *msg
{
int fixed = 0;
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
return SWITCH_STATUS_FALSE;
}
diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c
index 2df8937647..5320ca52d1 100644
--- a/src/mod/endpoints/mod_skinny/mod_skinny.c
+++ b/src/mod/endpoints/mod_skinny/mod_skinny.c
@@ -1080,8 +1080,6 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi
switch_channel_set_caller_profile(nchannel, caller_profile);
tech_pvt->caller_profile = caller_profile;
- switch_channel_set_flag(nchannel, CF_OUTBOUND);
-
if ((sql = switch_mprintf(
"INSERT INTO skinny_active_lines "
"(device_name, device_instance, line_instance, channel_uuid, call_id, call_state) "
diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h
index d85a190ba8..ee3c33a497 100644
--- a/src/mod/endpoints/mod_skinny/skinny_protocol.h
+++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h
@@ -547,12 +547,15 @@ struct PACKED service_url_stat_res_message {
#define USER_TO_DEVICE_DATA_VERSION1_MESSAGE 0x013F
/* See struct PACKED extended_data_message */
+/* XMLAlarmMessage */
+#define XML_ALARM_MESSAGE 0x015A
+
/*****************************************************************************/
/* SKINNY MESSAGE */
/*****************************************************************************/
#define SKINNY_MESSAGE_FIELD_SIZE 4 /* 4-bytes field */
#define SKINNY_MESSAGE_HEADERSIZE 12 /* three 4-bytes fields */
-#define SKINNY_MESSAGE_MAXSIZE 1000
+#define SKINNY_MESSAGE_MAXSIZE 2048
union skinny_data {
/* no data for KEEP_ALIVE_MESSAGE */
diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c
index cfafea6f01..9bf9d9fb9b 100644
--- a/src/mod/endpoints/mod_skinny/skinny_server.c
+++ b/src/mod/endpoints/mod_skinny/skinny_server.c
@@ -343,7 +343,7 @@ switch_status_t skinny_session_send_call_info(switch_core_session_t *session, li
zstr((called_party_number = switch_channel_get_variable(channel, "destination_number")))) {
called_party_number = "0000000000";
}
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
call_type = SKINNY_INBOUND_CALL;
} else {
call_type = SKINNY_OUTBOUND_CALL;
@@ -1674,7 +1674,7 @@ switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *liste
);
switch_set_flag_locked(tech_pvt, TFLAG_IO);
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
switch_channel_mark_answered(channel);
}
if (switch_channel_test_flag(channel, CF_HOLD)) {
@@ -1970,7 +1970,7 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re
"Received %s (type=%x,length=%d) from %s:%d.\n", skinny_message_type2str(request->type), request->type, request->length,
listener->device_name, listener->device_instance);
}
- if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE) {
+ if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE && request->type != XML_ALARM_MESSAGE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Device should send a register message first.\n");
return SWITCH_STATUS_FALSE;
diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c
index 0a27ad76c4..053b350b46 100644
--- a/src/mod/endpoints/mod_skinny/skinny_tables.c
+++ b/src/mod/endpoints/mod_skinny/skinny_tables.c
@@ -99,6 +99,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = {
{"DisplayPriNotifyMessage", DISPLAY_PRI_NOTIFY_MESSAGE},
{"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE},
{"UserToDeviceDataVersion1Message", USER_TO_DEVICE_DATA_VERSION1_MESSAGE},
+ {"XMLAlarmMessage", XML_ALARM_MESSAGE},
{NULL, 0}
};
SKINNY_DECLARE_ID2STR(skinny_message_type2str, SKINNY_MESSAGE_TYPES, "UnknownMessage")
diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h
index 14962b8b78..c119e1f141 100644
--- a/src/mod/endpoints/mod_skinny/skinny_tables.h
+++ b/src/mod/endpoints/mod_skinny/skinny_tables.h
@@ -87,7 +87,7 @@ uint32_t func(const char *str)\
}
-extern struct skinny_table SKINNY_MESSAGE_TYPES[65];
+extern struct skinny_table SKINNY_MESSAGE_TYPES[66];
const char *skinny_message_type2str(uint32_t id);
uint32_t skinny_str2message_type(const char *str);
#define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES)
diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c
index 65c1b120fd..56188a4188 100644
--- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c
+++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c
@@ -1364,7 +1364,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
caller_profile = tech_pvt->caller_profile;
caller_profile->destination_number = rdest;
- switch_channel_set_flag(channel, CF_OUTBOUND);
switch_mutex_lock(tech_pvt->flag_mutex);
switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
switch_mutex_unlock(tech_pvt->flag_mutex);
diff --git a/src/mod/endpoints/mod_skypopen/oss/Makefile b/src/mod/endpoints/mod_skypopen/oss/Makefile
index 465db533e4..8df20f68c5 100644
--- a/src/mod/endpoints/mod_skypopen/oss/Makefile
+++ b/src/mod/endpoints/mod_skypopen/oss/Makefile
@@ -4,7 +4,7 @@
# Add your debugging flag (or not) to CFLAGS
ifeq ($(DEBUG),y)
- DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+ DEBFLAGS = -O -g -DSKYPOPEN_DEBUG # "-O" is needed to expand inlines
else
DEBFLAGS = -O2 -Wall
endif
@@ -15,9 +15,9 @@ EXTRA_CFLAGS += -I$(LDDINC)
ifneq ($(KERNELRELEASE),)
# call from kernel build system
-scull-objs := main.o
+skypopen-objs := main.o
-obj-m := scull.o
+obj-m := skypopen.o
else
diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c
index 8da9c549ac..2abc5b342a 100644
--- a/src/mod/endpoints/mod_skypopen/oss/main.c
+++ b/src/mod/endpoints/mod_skypopen/oss/main.c
@@ -1,5 +1,5 @@
/*
- * main.c -- the bare scull char module
+ * main.c -- the bare skypopen char module
*
* Copyright (C) 2010 Giovanni Maruzzelli
* Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
@@ -41,117 +41,198 @@
#include
#include
-#include "scull.h" /* local definitions */
+#include "skypopen.h" /* local definitions */
/*
* Our parameters which can be set at load time.
*/
-int scull_major = SCULL_MAJOR;
-int scull_minor = 3;
-int scull_nr_devs = SCULL_NR_DEVS; /* number of bare scull devices */
+int skypopen_major = SKYPOPEN_MAJOR;
+int skypopen_minor = 3;
+int skypopen_nr_devs = SKYPOPEN_NR_DEVS; /* number of bare skypopen devices */
-module_param(scull_major, int, S_IRUGO);
-module_param(scull_minor, int, S_IRUGO);
-module_param(scull_nr_devs, int, S_IRUGO);
+module_param(skypopen_major, int, S_IRUGO);
+module_param(skypopen_minor, int, S_IRUGO);
+module_param(skypopen_nr_devs, int, S_IRUGO);
-MODULE_AUTHOR("Original: Alessandro Rubini, Jonathan Corbet. Heavy modified by: Giovanni Maruzzelli");
+MODULE_AUTHOR("Original: Alessandro Rubini, Jonathan Corbet. Modified by: Giovanni Maruzzelli for FreeSWITCH skypopen");
MODULE_LICENSE("Dual BSD/GPL");
-static struct scull_dev *scull_devices; /* allocated in scull_init_module */
+static struct skypopen_dev *skypopen_devices; /* allocated in skypopen_init_module */
-#define GIOVA_BLK 1920
-#define GIOVA_SLEEP 20
+static int unload = 0;
+#ifdef CENTOS
+#define HRTIMER_MODE_REL HRTIMER_REL
+#endif// CENTOS
+#ifndef WANT_HRTIMER
void my_timer_callback_inq( unsigned long data )
{
- struct scull_dev *dev = (void *)data;
+ struct skypopen_dev *dev = (void *)data;
- //dev->readable=1;
wake_up_interruptible(&dev->inq);
- mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
+ mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
}
void my_timer_callback_outq( unsigned long data )
{
- struct scull_dev *dev = (void *)data;
+ struct skypopen_dev *dev = (void *)data;
- //dev->writable=1;
wake_up_interruptible(&dev->outq);
- mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) );
+ mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
}
+#else// WANT_HRTIMER
+
+#ifndef CENTOS
+static enum hrtimer_restart my_hrtimer_callback_inq( struct hrtimer *timer_inq )
+{
+ struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq);
+ ktime_t now;
+
+ if(unload)
+ return HRTIMER_NORESTART;
+
+ now = ktime_get();
+ hrtimer_forward(&dev->timer_inq, now, ktime_set(0, SKYPOPEN_SLEEP * 1000000));
+ wake_up_interruptible(&dev->inq);
+
+ return HRTIMER_RESTART;
+}
+static enum hrtimer_restart my_hrtimer_callback_outq( struct hrtimer *timer_outq )
+{
+ struct skypopen_dev *dev = container_of(timer_outq, struct skypopen_dev, timer_outq);
+ ktime_t now;
+
+ if(unload)
+ return HRTIMER_NORESTART;
+
+ now = ktime_get();
+ hrtimer_forward(&dev->timer_outq, now, ktime_set(0, SKYPOPEN_SLEEP * 1000000));
+ wake_up_interruptible(&dev->outq);
+
+ return HRTIMER_RESTART;
+}
+#else// CENTOS
+static int my_hrtimer_callback_inq( struct hrtimer *timer_inq )
+{
+ struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq);
+
+ if(unload)
+ return HRTIMER_NORESTART;
+
+ hrtimer_forward(&dev->timer_inq, timer_inq->expires, ktime_set(0, SKYPOPEN_SLEEP * 1000000));
+ wake_up_interruptible(&dev->inq);
+
+ return HRTIMER_RESTART;
+}
+static int my_hrtimer_callback_outq( struct hrtimer *timer_outq )
+{
+ struct skypopen_dev *dev = container_of(timer_outq, struct skypopen_dev, timer_outq);
+
+ if(unload)
+ return HRTIMER_NORESTART;
+
+ hrtimer_forward(&dev->timer_outq, timer_outq->expires, ktime_set(0, SKYPOPEN_SLEEP * 1000000));
+ wake_up_interruptible(&dev->outq);
+
+ return HRTIMER_RESTART;
+}
+#endif// CENTOS
+#endif// WANT_HRTIMER
/* The clone-specific data structure includes a key field */
-struct scull_listitem {
- struct scull_dev device;
+struct skypopen_listitem {
+ struct skypopen_dev device;
dev_t key;
struct list_head list;
};
/* The list of devices, and a lock to protect it */
-static LIST_HEAD(scull_c_list);
-static spinlock_t scull_c_lock = SPIN_LOCK_UNLOCKED;
+static LIST_HEAD(skypopen_c_list);
+static spinlock_t skypopen_c_lock = SPIN_LOCK_UNLOCKED;
/* Look for a device or create one if missing */
-static struct scull_dev *scull_c_lookfor_device(dev_t key)
+static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key)
{
- struct scull_listitem *lptr;
+ struct skypopen_listitem *lptr;
+#ifdef WANT_HRTIMER
+#if 0
+ ktime_t ktime_inq;
+ ktime_t ktime_outq;
+#endif //0
+#endif// WANT_HRTIMER
- list_for_each_entry(lptr, &scull_c_list, list) {
+ list_for_each_entry(lptr, &skypopen_c_list, list) {
if (lptr->key == key)
return &(lptr->device);
}
/* not found */
- lptr = kmalloc(sizeof(struct scull_listitem), GFP_KERNEL);
+ lptr = kmalloc(sizeof(struct skypopen_listitem), GFP_KERNEL);
if (!lptr)
return NULL;
/* initialize the device */
- memset(lptr, 0, sizeof(struct scull_listitem));
+ memset(lptr, 0, sizeof(struct skypopen_listitem));
lptr->key = key;
init_waitqueue_head(&lptr->device.inq);
init_waitqueue_head(&lptr->device.outq);
- printk(" Timer installing\n");
+#ifndef WANT_HRTIMER
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, 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) );
+ printk( "Starting skypopen OSS driver read timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid );
+ mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
+ printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid );
+ mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
+#else// WANT_HRTIMER
+#if 0
+ ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000);
+ hrtimer_init( &lptr->device.timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
+ lptr->device.timer_inq.function = &my_hrtimer_callback_inq;
+ hrtimer_start( &lptr->device.timer_inq, ktime_inq, HRTIMER_MODE_REL );
+
+ ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000);
+ hrtimer_init( &lptr->device.timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
+ lptr->device.timer_outq.function = &my_hrtimer_callback_outq;
+ hrtimer_start( &lptr->device.timer_outq, ktime_outq, HRTIMER_MODE_REL );
+#endif
+
+#endif// WANT_HRTIMER
+
/* place it in the list */
- list_add(&lptr->list, &scull_c_list);
+ list_add(&lptr->list, &skypopen_c_list);
return &(lptr->device);
}
-static int scull_c_open(struct inode *inode, struct file *filp)
+
+/*
+ * Open and close
+ */
+static int skypopen_c_open(struct inode *inode, struct file *filp)
{
- struct scull_dev *dev;
+ struct skypopen_dev *dev;
dev_t key;
- if (!current->pid) {
- printk("Process \"%s\" has no pid\n", current->comm);
- return -EINVAL;
- }
- key = current->pid;
+ key = current->tgid;
- /* look for a scullc device in the list */
- spin_lock(&scull_c_lock);
- dev = scull_c_lookfor_device(key);
- spin_unlock(&scull_c_lock);
+ /* look for a skypopenc device in the list */
+ spin_lock(&skypopen_c_lock);
+ dev = skypopen_c_lookfor_device(key);
+ spin_unlock(&skypopen_c_lock);
if (!dev)
return -ENOMEM;
- /* then, everything else is copied from the bare scull device */
+ /* then, everything else is copied from the bare skypopen device */
filp->private_data = dev;
return 0; /* success */
}
-static int scull_c_release(struct inode *inode, struct file *filp)
+static int skypopen_c_release(struct inode *inode, struct file *filp)
{
/*
* Nothing to do, because the device is persistent.
@@ -163,39 +244,59 @@ static int scull_c_release(struct inode *inode, struct file *filp)
/*************************************************************/
-/*
- * Open and close
- */
-ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
+static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count,
loff_t *f_pos)
{
- struct scull_dev *dev = filp->private_data;
-
DEFINE_WAIT(wait);
+ struct skypopen_dev *dev = filp->private_data;
+#ifdef WANT_HRTIMER
+#if 1
+ if(dev->timer_inq_started == 0){
+ ktime_t ktime_inq;
+
+ ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000);
+ hrtimer_init( &dev->timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
+ dev->timer_inq.function = &my_hrtimer_callback_inq;
+ hrtimer_start( &dev->timer_inq, ktime_inq, HRTIMER_MODE_REL );
+ dev->timer_inq_started = 1;
+ }
+#endif
+#endif// WANT_HRTIMER
+
+
+ //printk("READ\n");
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;
}
-ssize_t scull_write(struct file *filp, const char __user *buf, size_t count,
+static ssize_t skypopen_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);
+ struct skypopen_dev *dev = filp->private_data;
+#ifdef WANT_HRTIMER
+#if 1
+ if(dev->timer_outq_started == 0){
+ ktime_t ktime_outq;
+
+ ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000);
+ hrtimer_init( &dev->timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
+ dev->timer_outq.function = &my_hrtimer_callback_outq;
+ hrtimer_start( &dev->timer_outq, ktime_outq, HRTIMER_MODE_REL );
+ dev->timer_outq_started = 1;
+ }
+#endif
+#endif// WANT_HRTIMER
+
+
+ //printk("WRITE\n");
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;
}
@@ -203,7 +304,7 @@ ssize_t scull_write(struct file *filp, const char __user *buf, size_t count,
* The ioctl() implementation
*/
-int scull_ioctl(struct inode *inode, struct file *filp,
+static int skypopen_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
@@ -213,7 +314,7 @@ int scull_ioctl(struct inode *inode, struct file *filp,
case OSS_GETVERSION:
return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_GETBLKSIZE:
- return put_user(GIOVA_BLK, p);
+ return put_user(SKYPOPEN_BLK, p);
case SNDCTL_DSP_GETFMTS:
return put_user(28731, p);
@@ -223,14 +324,14 @@ int scull_ioctl(struct inode *inode, struct file *filp,
}
-struct file_operations scull_fops = {
+struct file_operations skypopen_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
- .read = scull_read,
- .write = scull_write,
- .ioctl = scull_ioctl,
- .open = scull_c_open,
- .release = scull_c_release,
+ .read = skypopen_read,
+ .write = skypopen_write,
+ .ioctl = skypopen_ioctl,
+ .open = skypopen_c_open,
+ .release = skypopen_c_release,
};
/*
@@ -243,34 +344,46 @@ struct file_operations scull_fops = {
* have not been initialized
*/
-void scull_cleanup_module(void)
+void skypopen_cleanup_module(void)
{
int i;
int ret;
- struct scull_listitem *lptr, *next;
- dev_t devno = MKDEV(scull_major, scull_minor);
+ struct skypopen_listitem *lptr, *next;
+ dev_t devno = MKDEV(skypopen_major, skypopen_minor);
+
+
+ unload = 1;
+
+ msleep(100);
/* Get rid of our char dev entries */
- if (scull_devices) {
- for (i = 0; i < scull_nr_devs; i++) {
- cdev_del(&scull_devices[i].cdev);
+ if (skypopen_devices) {
+ for (i = 0; i < skypopen_nr_devs; i++) {
+ cdev_del(&skypopen_devices[i].cdev);
}
- kfree(scull_devices);
+ kfree(skypopen_devices);
}
-
/* And all the cloned devices */
- list_for_each_entry_safe(lptr, next, &scull_c_list, list) {
+ list_for_each_entry_safe(lptr, next, &skypopen_c_list, list) {
+#ifndef WANT_HRTIMER
ret= del_timer( &lptr->device.timer_inq );
- if (ret) printk("The inq timer was still in use...\n");
+ printk( "Stopped skypopen OSS driver read timer\n");
ret= del_timer( &lptr->device.timer_outq );
- if (ret) printk("The outq timer was still in use...\n");
+ printk( "Stopped skypopen OSS driver write timer\n");
+#else// WANT_HRTIMER
+ ret = hrtimer_cancel( &lptr->device.timer_inq );
+ printk( "Stopped skypopen OSS driver read HRtimer\n");
+ ret = hrtimer_cancel( &lptr->device.timer_outq );
+ printk( "Stopped skypopen OSS driver write HRtimer\n");
+
+#endif// WANT_HRTIMER
list_del(&lptr->list);
kfree(lptr);
}
- printk("Timer uninstalling\n");
/* cleanup_module is never called if registering failed */
- unregister_chrdev_region(devno, scull_nr_devs);
+ unregister_chrdev_region(devno, skypopen_nr_devs);
+ printk("skypopen OSS driver unloaded\n");
}
@@ -278,40 +391,41 @@ void scull_cleanup_module(void)
/*
* Set up the char_dev structure for this device.
*/
-static void scull_setup_cdev(struct scull_dev *dev, int index)
+static void skypopen_setup_cdev(struct skypopen_dev *dev, int index)
{
- int err, devno = MKDEV(scull_major, scull_minor + index);
+ int err, devno = MKDEV(skypopen_major, skypopen_minor + index);
- cdev_init(&dev->cdev, &scull_fops);
+ cdev_init(&dev->cdev, &skypopen_fops);
dev->cdev.owner = THIS_MODULE;
- dev->cdev.ops = &scull_fops;
+ dev->cdev.ops = &skypopen_fops;
err = cdev_add (&dev->cdev, devno, 1);
/* Fail gracefully if need be */
if (err)
- printk(KERN_NOTICE "Error %d adding scull%d", err, index);
+ printk(KERN_NOTICE "Error %d adding skypopen%d", err, index);
}
-int scull_init_module(void)
+int skypopen_init_module(void)
{
int result, i;
dev_t dev = 0;
+ printk("skypopen OSS driver loading (www.freeswitch.org)\n");
/*
* Get a range of minor numbers to work with, asking for a dynamic
* major unless directed otherwise at load time.
*/
- if (scull_major) {
- dev = MKDEV(scull_major, scull_minor);
- result = register_chrdev_region(dev, scull_nr_devs, "dsp");
+ if (skypopen_major) {
+ dev = MKDEV(skypopen_major, skypopen_minor);
+ result = register_chrdev_region(dev, skypopen_nr_devs, "dsp");
} else {
- result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,
+ result = alloc_chrdev_region(&dev, skypopen_minor, skypopen_nr_devs,
"dsp");
- scull_major = MAJOR(dev);
+ skypopen_major = MAJOR(dev);
}
if (result < 0) {
- printk(KERN_WARNING "scull: can't get major %d\n", scull_major);
+ printk(KERN_WARNING "skypopen OSS driver: can't get major %d\n", skypopen_major);
return result;
}
@@ -319,26 +433,26 @@ int scull_init_module(void)
* allocate the devices -- we can't have them static, as the number
* can be specified at load time
*/
- scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL);
- if (!scull_devices) {
+ skypopen_devices = kmalloc(skypopen_nr_devs * sizeof(struct skypopen_dev), GFP_KERNEL);
+ if (!skypopen_devices) {
result = -ENOMEM;
goto fail; /* Make this more graceful */
}
- memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev));
+ memset(skypopen_devices, 0, skypopen_nr_devs * sizeof(struct skypopen_dev));
/* Initialize each device. */
- for (i = 0; i < scull_nr_devs; i++) {
- scull_setup_cdev(&scull_devices[i], i);
+ for (i = 0; i < skypopen_nr_devs; i++) {
+ skypopen_setup_cdev(&skypopen_devices[i], i);
}
/* At this point call the init function for any friend device */
- dev = MKDEV(scull_major, scull_minor + scull_nr_devs);
+ dev = MKDEV(skypopen_major, skypopen_minor + skypopen_nr_devs);
return 0; /* succeed */
fail:
- scull_cleanup_module();
+ skypopen_cleanup_module();
return result;
}
-module_init(scull_init_module);
-module_exit(scull_cleanup_module);
+module_init(skypopen_init_module);
+module_exit(skypopen_cleanup_module);
diff --git a/src/mod/endpoints/mod_skypopen/oss/scull.h b/src/mod/endpoints/mod_skypopen/oss/scull.h
deleted file mode 100644
index 565b8b38b7..0000000000
--- a/src/mod/endpoints/mod_skypopen/oss/scull.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * scull.h -- definitions for the char module
- *
- * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
- * Copyright (C) 2001 O'Reilly & Associates
- *
- * The source code in this file can be freely used, adapted,
- * and redistributed in source or binary form, so long as an
- * acknowledgment appears in derived source files. The citation
- * should list that the code comes from the book "Linux Device
- * Drivers" by Alessandro Rubini and Jonathan Corbet, published
- * by O'Reilly & Associates. No warranty is attached;
- * we cannot take responsibility for errors or fitness for use.
- *
- * $Id: scull.h,v 1.15 2004/11/04 17:51:18 rubini Exp $
- */
-
-#ifndef _SCULL_H_
-#define _SCULL_H_
-
-#include /* needed for the _IOW etc stuff used later */
-
-#ifndef SCULL_MAJOR
-#define SCULL_MAJOR 14 /* dynamic major by default */
-#endif
-
-#ifndef SCULL_NR_DEVS
-#define SCULL_NR_DEVS 1 /* scull0 through scull3 */
-#endif
-
-struct scull_dev {
- struct cdev cdev; /* Char device structure */
- wait_queue_head_t inq; /* read and write queues */
- 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;
- //unsigned long write_sleeped_acc;
- //double read_delay; /* how much delay last time */
- //double write_delay; /* how much delay last time */
-};
-
-
-/*
- * The different configurable parameters
- */
-extern int scull_major; /* main.c */
-extern int scull_nr_devs;
-
-
-/*
- * Prototypes for shared functions
- */
-
-ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
- loff_t *f_pos);
-ssize_t scull_write(struct file *filp, const char __user *buf, size_t count,
- loff_t *f_pos);
-int scull_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-
-#endif /* _SCULL_H_ */
diff --git a/src/mod/endpoints/mod_skypopen/oss/skypopen.h b/src/mod/endpoints/mod_skypopen/oss/skypopen.h
new file mode 100644
index 0000000000..2324e448cb
--- /dev/null
+++ b/src/mod/endpoints/mod_skypopen/oss/skypopen.h
@@ -0,0 +1,71 @@
+/*
+ * skypopen.h -- definitions for the char module
+ *
+ * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
+ * Copyright (C) 2001 O'Reilly & Associates
+ *
+ * The source code in this file can be freely used, adapted,
+ * and redistributed in source or binary form, so long as an
+ * acknowledgment appears in derived source files. The citation
+ * should list that the code comes from the book "Linux Device
+ * Drivers" by Alessandro Rubini and Jonathan Corbet, published
+ * by O'Reilly & Associates. No warranty is attached;
+ * we cannot take responsibility for errors or fitness for use.
+ *
+ * $Id: skypopen.h,v 1.15 2004/11/04 17:51:18 rubini Exp $
+ */
+
+#ifndef _SKYPOPEN_H_
+#define _SKYPOPEN_H_
+
+#include /* needed for the _IOW etc stuff used later */
+
+#define SKYPOPEN_BLK 960
+#define SKYPOPEN_SLEEP 10
+
+#define CENTOS
+
+#ifndef SKYPOPEN_MAJOR
+#define SKYPOPEN_MAJOR 14 /* dynamic major by default */
+#endif
+
+#ifndef SKYPOPEN_NR_DEVS
+#define SKYPOPEN_NR_DEVS 1 /* skypopen0 through skypopen3 */
+#endif
+
+#define WANT_HRTIMER
+struct skypopen_dev {
+ struct cdev cdev; /* Char device structure */
+ wait_queue_head_t inq; /* read and write queues */
+ wait_queue_head_t outq; /* read and write queues */
+#ifndef WANT_HRTIMER
+ struct timer_list timer_inq;
+ struct timer_list timer_outq;
+#else// WANT_HRTIMER
+ struct hrtimer timer_inq;
+ struct hrtimer timer_outq;
+#endif// WANT_HRTIMER
+ int timer_inq_started;
+ int timer_outq_started;
+};
+
+
+/*
+ * The different configurable parameters
+ */
+extern int skypopen_major; /* main.c */
+extern int skypopen_nr_devs;
+
+
+/*
+ * Prototypes for shared functions
+ */
+
+//ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count,
+ //loff_t *f_pos);
+//ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count,
+ //loff_t *f_pos);
+//int skypopen_ioctl(struct inode *inode, struct file *filp,
+ //unsigned int cmd, unsigned long arg);
+
+#endif /* _SKYPOPEN_H_ */
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index d4f8b1b45a..07e125ad6c 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -508,7 +508,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_END());
}
} else {
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sending CANCEL to %s\n", switch_channel_get_name(channel));
if (!tech_pvt->got_bye) {
switch_channel_set_variable(channel, "sip_hangup_disposition", "send_cancel");
@@ -573,7 +573,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
char *sticky = NULL;
const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
- if (sofia_test_flag(tech_pvt, TFLAG_ANS) || switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (sofia_test_flag(tech_pvt, TFLAG_ANS) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
return SWITCH_STATUS_SUCCESS;
}
@@ -653,7 +653,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
switch_channel_clear_flag(channel, CF_PROXY_MODE);
}
- if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
tech_pvt->num_codecs = 0;
sofia_glue_tech_prepare_codecs(tech_pvt);
@@ -1339,6 +1339,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if (msg->string_arg) {
char *p;
+ const char *s;
+
+ if (!strncasecmp(msg->string_arg, "debug:", 6)) {
+ s = msg->string_arg + 6;
+ if (s && !strcmp(s, "off")) {
+ s = NULL;
+ }
+ switch_rtp_debug_jitter_buffer(tech_pvt->rtp_session, s);
+ goto end;
+ }
+
if ((len = atoi(msg->string_arg))) {
qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000);
@@ -1672,7 +1683,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
sofia_glue_tech_set_local_sdp(tech_pvt, NULL, SWITCH_FALSE);
if (!(switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag(channel, CF_EARLY_MEDIA))) {
- if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
tech_pvt->num_codecs = 0;
@@ -2187,7 +2198,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
} else {
if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || !tech_pvt->iananame) {
sofia_clear_flag_locked(tech_pvt, TFLAG_LATE_NEGOTIATION);
- if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
tech_pvt->num_codecs = 0;
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index f2a555e946..94eab68858 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -357,7 +357,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
goto error;
}
- if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
switch_channel_answer(channel);
switch_channel_set_variable(channel, "auto_answer_destination", switch_channel_get_variable(channel, "destination_number"));
switch_ivr_session_transfer(session, "auto_answer", NULL, NULL);
@@ -4114,7 +4114,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
}
- if (channel && sip && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (channel && sip && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
sip_contact_t *p_contact = sip->sip_contact;
int i = 0;
char var_name[80];
@@ -4645,7 +4645,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
status = 183;
}
- if (channel && (status == 180 || status == 183) && switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
const char *val;
if ((val = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(val)) {
nua_notify(nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR("talk"), TAG_END());
@@ -4692,7 +4692,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (r_sdp) {
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
- if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && !switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
+ if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA");
}
sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
@@ -4715,7 +4715,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
goto done;
} else {
- if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && !switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
+ if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION");
} else {
if (sofia_glue_tech_media(tech_pvt, (char *) r_sdp) != SWITCH_STATUS_SUCCESS) {
@@ -4910,7 +4910,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
sofia_glue_tech_set_local_sdp(tech_pvt, NULL, SWITCH_FALSE);
if (!switch_channel_media_ready(channel)) {
- if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
//const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
tech_pvt->num_codecs = 0;
@@ -6255,7 +6255,8 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
if (!is_nat && profile->nat_acl_count) {
uint32_t x = 0;
- int ok = 1;
+ int contact_private_ip = 1;
+ int network_private_ip = 0;
char *last_acl = NULL;
const char *contact_host = NULL;
@@ -6264,35 +6265,37 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
}
if (!zstr(contact_host)) {
+ /* 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.
+
+ */
+
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");
- }
+ if ((contact_private_ip = switch_check_network_list_ip(contact_host, last_acl))) {
break;
}
}
+ if (contact_private_ip) {
+ for (x = 0; x < profile->nat_acl_count; x++) {
+ if ((network_private_ip = switch_check_network_list_ip(network_ip, profile->nat_acl[x]))) {
+ break;
+ }
+ }
+ }
- if (ok) {
+ if (contact_private_ip && !network_private_ip) {
is_nat = last_acl;
}
}
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index 803059a8da..0f52bbc8fb 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -4687,8 +4687,8 @@ void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp)
switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, sdp);
if (!sofia_test_flag(tech_pvt, TFLAG_CHANGE_MEDIA) && !sofia_test_flag(tech_pvt, TFLAG_RECOVERING) &&
- (switch_channel_test_flag(other_channel, CF_OUTBOUND) &&
- switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND) && switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE))) {
+ (switch_channel_direction(other_channel) == SWITCH_CALL_DIRECTION_OUTBOUND &&
+ switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE))) {
switch_ivr_nomedia(val, SMF_FORCE);
sofia_set_flag_locked(tech_pvt, TFLAG_CHANGE_MEDIA);
}
diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
index ee7cfc9eaf..596a953dcb 100644
--- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
+++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
@@ -31,8 +31,8 @@
*/
#include
#define CMD_BUFLEN 1024 * 1000
-#define MAX_QUEUE_LEN 5000
-#define MAX_MISSED 200
+#define MAX_QUEUE_LEN 25000
+#define MAX_MISSED 2000
SWITCH_MODULE_LOAD_FUNCTION(mod_event_socket_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_event_socket_shutdown);
SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime);
@@ -170,7 +170,7 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l
if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) {
switch_log_node_t *dnode = switch_log_node_dup(node);
- if (switch_queue_trypush(l->log_queue, dnode) == SWITCH_STATUS_SUCCESS) {
+ if (switch_queue_push(l->log_queue, dnode) == SWITCH_STATUS_SUCCESS) {
if (l->lost_logs) {
int ll = l->lost_logs;
switch_event_t *event;
@@ -366,7 +366,7 @@ static void event_handler(switch_event_t *event)
if (send) {
if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
- if (switch_queue_trypush(l->event_queue, clone) == SWITCH_STATUS_SUCCESS) {
+ if (switch_queue_push(l->event_queue, clone) == SWITCH_STATUS_SUCCESS) {
if (l->lost_events) {
int le = l->lost_events;
l->lost_events = 0;
@@ -1233,7 +1233,7 @@ static switch_status_t read_packet(listener_t *listener, switch_event_t **event,
if (switch_channel_get_state(chan) < CS_HANGUP && switch_channel_test_flag(chan, CF_DIVERT_EVENTS)) {
switch_event_t *e = NULL;
while (switch_core_session_dequeue_event(listener->session, &e, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
- if (switch_queue_trypush(listener->event_queue, e) != SWITCH_STATUS_SUCCESS) {
+ if (switch_queue_push(listener->event_queue, e) != SWITCH_STATUS_SUCCESS) {
switch_core_session_queue_event(listener->session, &e);
break;
}
diff --git a/src/switch_channel.c b/src/switch_channel.c
index a9c87c5954..ef21e8c8f1 100644
--- a/src/switch_channel.c
+++ b/src/switch_channel.c
@@ -2386,6 +2386,8 @@ SWITCH_DECLARE(void) switch_channel_set_caller_extension(switch_channel_t *chann
{
switch_assert(channel != NULL);
+ switch_channel_set_flag(channel, CF_DIALPLAN);
+
switch_mutex_lock(channel->profile_mutex);
caller_extension->next = channel->caller_profile->caller_extension;
channel->caller_profile->caller_extension = caller_extension;
@@ -2622,7 +2624,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel
return SWITCH_STATUS_SUCCESS;
}
- if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
msg.message_id = SWITCH_MESSAGE_INDICATE_PROGRESS;
msg.from = channel->name;
status = switch_core_session_perform_receive_message(channel->session, &msg, file, func, line);
@@ -2657,7 +2659,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_ring_ready_value(switch_c
return SWITCH_STATUS_SUCCESS;
}
- if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
msg.message_id = SWITCH_MESSAGE_INDICATE_RINGING;
msg.from = channel->name;
msg.numeric_arg = rv;
@@ -2800,7 +2802,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *
switch_assert(channel != NULL);
- if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
return SWITCH_STATUS_SUCCESS;
}
diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c
index c77f3f1a68..ccd6dacc9c 100644
--- a/src/switch_core_state_machine.c
+++ b/src/switch_core_state_machine.c
@@ -124,7 +124,7 @@ static void switch_core_standard_on_routing(switch_core_session_t *session)
}
if (!count) {
- if (switch_channel_test_flag(session->channel, CF_OUTBOUND)) {
+ if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
if (switch_channel_test_flag(session->channel, CF_ANSWERED)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"No Dialplan on answered channel, changing state to HANGUP\n");
diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp
index 40462db567..1ba850d7e4 100644
--- a/src/switch_cpp.cpp
+++ b/src/switch_cpp.cpp
@@ -1206,7 +1206,7 @@ SWITCH_DECLARE(void) bridge(CoreSession &session_a, CoreSession &session_b)
if (switch_channel_ready(channel_a) && switch_channel_ready(channel_b)) {
session_a.begin_allow_threads();
- if (!switch_channel_test_flag(channel_a, CF_OUTBOUND) && !switch_channel_media_ready(channel_a)) {
+ if (switch_channel_direction(channel_a) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_media_ready(channel_a)) {
switch_channel_pre_answer(channel_a);
}
diff --git a/src/switch_event.c b/src/switch_event.c
index f782c15900..dce42f8e29 100644
--- a/src/switch_event.c
+++ b/src/switch_event.c
@@ -339,7 +339,7 @@ static void *SWITCH_THREAD_FUNC switch_event_thread(switch_thread_t *thread, voi
launch_dispatch_threads(SOFT_MAX_DISPATCH + 1, DISPATCH_QUEUE_LEN, RUNTIME_POOL);
switch_mutex_unlock(EVENT_QUEUE_MUTEX);
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Out of threads!\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Out of event dispatch threads! Slowing things down.\n");
switch_yield(1000000);
}
}
diff --git a/src/switch_ivr.c b/src/switch_ivr.c
index 6e2aeaf637..494871ec8a 100644
--- a/src/switch_ivr.c
+++ b/src/switch_ivr.c
@@ -140,7 +140,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
const char *var;
/*
- if (!switch_channel_test_flag(channel, CF_OUTBOUND) && !switch_channel_test_flag(channel, CF_PROXY_MODE) &&
+ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(channel, CF_PROXY_MODE) &&
!switch_channel_media_ready(channel) && !switch_channel_test_flag(channel, CF_SERVICE)) {
if ((status = switch_channel_pre_answer(channel)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot establish media.\n");
@@ -2300,7 +2300,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3
break;
}
- stfu_n_eat(jb, ts, 0, read_frame->payload, read_frame->data, read_frame->datalen);
+ stfu_n_eat(jb, ts, read_frame->payload, read_frame->data, read_frame->datalen);
ts += interval;
if ((jb_frame = stfu_n_read_a_frame(jb))) {
diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c
index afd33f16a0..aa5ddb9232 100644
--- a/src/switch_ivr_bridge.c
+++ b/src/switch_ivr_bridge.c
@@ -100,7 +100,7 @@ static void send_display(switch_core_session_t *session, switch_core_session_t *
caller_channel = switch_core_session_get_channel(session);
caller_profile = switch_channel_get_caller_profile(caller_channel);
- if (switch_channel_direction(caller_channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
+ if (switch_channel_direction(caller_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(caller_channel, CF_DIALPLAN)) {
name = caller_profile->callee_id_name;
number = caller_profile->callee_id_number;
@@ -435,8 +435,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
switch_channel_t *un = ans_a ? chan_b : chan_a;
switch_channel_t *a = un == chan_b ? chan_a : chan_b;
- if (!switch_channel_test_flag(un, CF_OUTBOUND)) {
- if (switch_channel_test_flag(a, CF_OUTBOUND) || (un == chan_a && !originator)) {
+ if (switch_channel_direction(un) == SWITCH_CALL_DIRECTION_INBOUND) {
+ if (switch_channel_direction(a) == SWITCH_CALL_DIRECTION_OUTBOUND || (un == chan_a && !originator)) {
switch_channel_pass_callee_id(a, un);
}
diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c
index e61534798b..b6ae346a66 100644
--- a/src/switch_ivr_originate.c
+++ b/src/switch_ivr_originate.c
@@ -1751,6 +1751,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
early_state_t early_state = { 0 };
int read_packet = 0;
int check_reject = 1;
+ switch_codec_implementation_t read_impl = { 0 };
if (strstr(bridgeto, SWITCH_ENT_ORIGINATE_DELIM)) {
return switch_ivr_enterprise_originate(session, bleg, cause, bridgeto, timelimit_sec, table, cid_name_override, cid_num_override,
@@ -1777,6 +1778,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
switch_channel_set_flag(caller_channel, CF_ORIGINATOR);
oglobals.session = session;
+ switch_core_session_get_read_impl(session, &read_impl);
if ((to_var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) {
timelimit_sec = atoi(to_var);
@@ -3066,7 +3068,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
if ((ringback.fh || silence || ringback.audio_buffer || oglobals.bridge_early_media > -1) && write_frame.codec && write_frame.datalen) {
if (silence) {
- write_frame.datalen = write_frame.codec->implementation->decoded_bytes_per_packet;
+ write_frame.datalen = read_impl.decoded_bytes_per_packet;
switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2, silence);
}
diff --git a/src/switch_rtp.c b/src/switch_rtp.c
index b4f60fcd55..4e667fb49b 100644
--- a/src/switch_rtp.c
+++ b/src/switch_rtp.c
@@ -229,7 +229,7 @@ struct switch_rtp {
uint32_t sync_packets;
int rtcp_interval;
switch_bool_t rtcp_fresh_frame;
-
+ uint8_t checked_jb;
#ifdef ENABLE_ZRTP
zrtp_session_t *zrtp_session;
zrtp_profile_t *zrtp_profile;
@@ -1652,6 +1652,32 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t
return SWITCH_STATUS_SUCCESS;
}
+static void jb_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
+{
+ int ret;
+ char *data;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = switch_vasprintf(&data, fmt, ap);
+ if (ret != -1) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "%s", data);
+ free(data);
+ }
+
+ //switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN, file, func, line, NULL, level, fmt, ap);
+ va_end(ap);
+}
+
+SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name)
+{
+
+ stfu_n_debug(rtp_session->jb, name);
+ stfu_global_set_logger(jb_logger);
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session,
uint32_t queue_frames,
uint32_t max_queue_frames,
@@ -1674,6 +1700,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *
if (rtp_session->jb) {
switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session");
stfu_n_call_me(rtp_session->jb, jb_callback, session);
+
return SWITCH_STATUS_SUCCESS;
}
@@ -2108,12 +2135,18 @@ static void do_flush(switch_rtp_t *rtp_session)
flushed++;
- if (rtp_session->jb) {
+#ifdef _MSC_VER
+#pragma warning(push) /* remove this stuff when "if (0" is removed */
+#pragma warning(disable:4127)
+#endif
+ if (0 && rtp_session->jb) {
stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts),
- ntohs((uint16_t) rtp_session->recv_msg.header.seq),
rtp_session->recv_msg.header.pt,
rtp_session->recv_msg.body, bytes - rtp_header_len);
}
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
rtp_session->stats.inbound.raw_bytes += bytes;
rtp_session->stats.inbound.flush_packet_count++;
@@ -2177,7 +2210,6 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
}
stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts),
- ntohs((uint16_t) rtp_session->recv_msg.header.seq),
rtp_session->recv_msg.header.pt,
rtp_session->recv_msg.body, *bytes - rtp_header_len);
*bytes = 0;
@@ -2195,9 +2227,9 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
*bytes = jb_frame->dlen + rtp_header_len;
rtp_session->recv_msg.header.ts = htonl(jb_frame->ts);
rtp_session->recv_msg.header.pt = jb_frame->pt;
- rtp_session->recv_msg.header.seq = htons((uint16_t)jb_frame->seq);
status = SWITCH_STATUS_SUCCESS;
}
+ rtp_session->checked_jb++;
}
return status;
@@ -2342,6 +2374,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
READ_INC(rtp_session);
+ rtp_session->checked_jb = 0;
+
while (switch_rtp_ready(rtp_session)) {
int do_cng = 0;
bytes = 0;
@@ -2894,7 +2928,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
if (do_cng) {
uint8_t *data = (uint8_t *) rtp_session->recv_msg.body;
int fdr;
-
+
if ((poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, 0)) == SWITCH_STATUS_SUCCESS) {
goto recvfrom;
}