Merge remote branch 'fsorig/master' into nfas

Conflicts:
	libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c
	libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
This commit is contained in:
David Yat Sin committed 2012-09-03 22:34:13 -04:00
commit 3a57b0bed6
1605 files changed
+170690 -121271

No files matched your search

+13
View File
@@ -13,11 +13,16 @@ libtool
ltmain.sh
missing
ptlib
opal
*_manifest.rc
*.pc
/*.tar.*
/*/*.dSYM/
/apr/apr-1-config
/apr/apr.exp
/apr/build/apr_rules.mk
@@ -225,6 +230,7 @@ missing
/ldns/doc/ldns_manpages
/ldns/include/
/ldns/ldns/config.h
/ldns/ldns/ldns
/ldns/ldns/net.h
/ldns/ldns/util.h
/ldns/lib
@@ -522,6 +528,11 @@ missing
/spandsp/doc/Makefile.in
/spandsp/Makefile
/spandsp/Makefile.in
/spandsp/m4/libtool.m4
/spandsp/m4/ltoptions.m4
/spandsp/m4/ltsugar.m4
/spandsp/m4/ltversion.m4
/spandsp/m4/lt~obsolete.m4
/spandsp/spandsp-sim/Makefile
/spandsp/spandsp-sim/Makefile.in
/spandsp/src/at_interpreter_dictionary.h
@@ -572,6 +583,7 @@ missing
/spandsp/test-data/Makefile.in
/spandsp/tests/Makefile
/spandsp/tests/Makefile.in
/spandsp/src/make_cielab_luts
/speex/config.h
/speex/include/Makefile
/speex/include/Makefile.in
@@ -874,6 +886,7 @@ missing
/yaml/tests/run-parser
/yaml/tests/run-scanner
/zeromq-*/
/jpeg-8d/
# build products we should remove
!/apr-util/xml/expat/conftools/config.guess
+1 -1
View File
@@ -409,7 +409,7 @@ APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b);
* @param pool The pool to tag
* @param tag The tag
*/
APR_DECLARE(char *) apr_pool_tag(apr_pool_t *pool, const char *tag);
APR_DECLARE(const char *) apr_pool_tag(apr_pool_t *pool, const char *tag);
#if APR_HAS_THREADS
/**
+1 -1
View File
@@ -1895,7 +1895,7 @@ APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b)
return 0;
}
APR_DECLARE(char *) apr_pool_tag(apr_pool_t *pool, const char *tag)
APR_DECLARE(const char *) apr_pool_tag(apr_pool_t *pool, const char *tag)
{
if (tag) {
pool->tag = tag;
+6 -6
View File
@@ -557,7 +557,7 @@ void apr__SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
}
/* Clean up state data: */
MEMSET_BZERO(context, sizeof(context));
MEMSET_BZERO(context, sizeof(*context));
usedspace = 0;
}
@@ -578,7 +578,7 @@ char *apr__SHA256_End(SHA256_CTX* context, char buffer[]) {
}
*buffer = (char)0;
} else {
MEMSET_BZERO(context, sizeof(context));
MEMSET_BZERO(context, sizeof(*context));
}
MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
return buffer;
@@ -889,7 +889,7 @@ void apr__SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
}
/* Zero out state data */
MEMSET_BZERO(context, sizeof(context));
MEMSET_BZERO(context, sizeof(*context));
}
char *apr__SHA512_End(SHA512_CTX* context, char buffer[]) {
@@ -909,7 +909,7 @@ char *apr__SHA512_End(SHA512_CTX* context, char buffer[]) {
}
*buffer = (char)0;
} else {
MEMSET_BZERO(context, sizeof(context));
MEMSET_BZERO(context, sizeof(*context));
}
MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
return buffer;
@@ -964,7 +964,7 @@ void apr__SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
}
/* Zero out state data */
MEMSET_BZERO(context, sizeof(context));
MEMSET_BZERO(context, sizeof(*context));
}
char *apr__SHA384_End(SHA384_CTX* context, char buffer[]) {
@@ -984,7 +984,7 @@ char *apr__SHA384_End(SHA384_CTX* context, char buffer[]) {
}
*buffer = (char)0;
} else {
MEMSET_BZERO(context, sizeof(context));
MEMSET_BZERO(context, sizeof(*context));
}
MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
return buffer;
+36 -18
View File
@@ -903,28 +903,46 @@ static const char *basic_gets(int *cnt)
}
static const char *banner =
" _____ ____ ____ _ ___ \n"
" | ___/ ___| / ___| | |_ _| \n"
" | |_ \\___ \\ | | | | | | \n"
" | _| ___) | | |___| |___ | | \n"
" |_| |____/ \\____|_____|___| \n"
"\n"
"*******************************************************\n"
"* Anthony Minessale II, Ken Rice, *\n"
"* Michael Jerris, Travis Cross *\n"
"* FreeSWITCH (http://www.freeswitch.org) *\n"
"* Paypal Donations Appreciated: paypal@freeswitch.org *\n"
"* Brought to you by ClueCon http://www.cluecon.com/ *\n"
"*******************************************************\n"
"\n"
"Type /help <enter> to see a list of commands\n\n\n";
".=======================================================.\n"
"| _____ ____ ____ _ ___ |\n"
"| | ___/ ___| / ___| | |_ _| |\n"
"| | |_ \\___ \\ | | | | | | |\n"
"| | _| ___) | | |___| |___ | | |\n"
"| |_| |____/ \\____|_____|___| |\n"
"| |\n"
".=======================================================.\n"
"| Anthony Minessale II, Ken Rice, |\n"
"| Michael Jerris, Travis Cross |\n"
"| FreeSWITCH (http://www.freeswitch.org) |\n"
"| Paypal Donations Appreciated: paypal@freeswitch.org |\n"
"| Brought to you by ClueCon http://www.cluecon.com/ |\n"
".=======================================================.\n"
"\n";
static const char *inf = "Type /help <enter> to see a list of commands\n\n\n";
static void print_banner(FILE *stream)
{
#ifndef WIN32
fprintf(stream, "%s%s", output_text_color, banner);
#include <cc.h>
#ifdef WIN32
/* Print banner in yellow with blue background */
SetConsoleTextAttribute(hStdout, ESL_SEQ_FYELLOW | BACKGROUND_BLUE);
WriteFile(hStdout, banner, (DWORD) strlen(banner), NULL, NULL);
WriteFile(hStdout, cc, (DWORD) strlen(cc), NULL, NULL);
SetConsoleTextAttribute(hStdout, wOldColorAttrs);
/* Print the rest info in default colors */
fprintf(stream, "\n%s\n", inf);
#else
fprintf(stream, "%s", banner);
fprintf(stream,
"%s%s%s%s%s%s\n%s\n",
ESL_SEQ_DEFAULT_COLOR,
ESL_SEQ_FYELLOW, ESL_SEQ_BBLUE,
banner,
cc, ESL_SEQ_DEFAULT_COLOR, inf);
fprintf(stream, "%s", output_text_color);
#endif
}
+91 -19
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, Anthony Minessale II
* Copyright (c) 2009-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,12 +35,68 @@
#include <stdlib.h>
#include <esl.h>
#include <errno.h>
#include <sys/wait.h>
static void handle_SIGCHLD(int sig)
{
int status = 0;
wait(&status);
return;
}
static void my_forking_callback(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in *addr)
{
esl_handle_t handle = {{0}};
char path_buffer[1024] = { 0 };
const char *path;
char arg[64] = { 0 };
signal(SIGCHLD, handle_SIGCHLD);
if (fork()) {
close(client_sock);
return;
}
if (esl_attach_handle(&handle, client_sock, addr) != ESL_SUCCESS || !handle.info_event) {
esl_log(ESL_LOG_ERROR, "Socket Error\n");
exit(0);
}
if (!(path = esl_event_get_header(handle.info_event, "variable_ivr_path"))) {
esl_disconnect(&handle);
esl_log(ESL_LOG_ERROR, "Missing ivr_path param!\n");
exit(0);
}
snprintf(arg, sizeof(arg), "%d", client_sock);
strncpy(path_buffer, path, sizeof(path_buffer) - 1);
/* hotwire the socket to STDIN/STDOUT */
/* hotwire the socket to STDIN/STDOUT */
if (!(dup2(client_sock, STDIN_FILENO)) && !(dup2(client_sock, STDOUT_FILENO))){
esl_disconnect(&handle);
esl_log(ESL_LOG_ERROR, "Socket Error hotwiring socket to STDIN/STDOUT!\n");
return;
}
/* close the handle but leak the socket on purpose cos the child will need it open */
handle.sock = -1;
esl_disconnect(&handle);
execl(path_buffer, path_buffer, arg, (char *)NULL);
close(client_sock);
exit(0);
}
static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in *addr)
{
esl_handle_t handle = {{0}};
const char *path;
char path_buffer[1024] = { 0 };
if (esl_attach_handle(&handle, client_sock, addr) != ESL_SUCCESS || !handle.info_event) {
close(client_sock);
esl_log(ESL_LOG_ERROR, "Socket Error\n");
@@ -53,16 +109,13 @@ static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struc
return;
}
/* hotwire the socket to STDIN/STDOUT */
if (!(dup2(client_sock, STDIN_FILENO)) && !(dup2(client_sock, STDOUT_FILENO))){
esl_disconnect(&handle);
esl_log(ESL_LOG_ERROR, "Socket Error hotwiring socket to STDIN/STDOUT!\n");
return;
}
snprintf(path_buffer, sizeof(path_buffer), "%s %d", path, client_sock);
if(system(path)) {
if (system(path_buffer)) {
esl_log(ESL_LOG_ERROR, "System Call Failed! [%s]\n", strerror(errno));
}
esl_disconnect(&handle);
}
@@ -71,24 +124,43 @@ int main(int argc, char *argv[])
{
int i;
char *ip = NULL;
int port = 0;
int port = 0, thread = 0;
for (i = 1; i + 1 < argc; ) {
if (!strcasecmp(argv[i], "-h")) {
ip = argv[++i];
} else if (!strcasecmp(argv[i], "-p")) {
port = atoi(argv[++i]);
} else {
i++;
for (i = 1; i < argc; ) {
int cont = 0;
if (i + 1 < argc) {
if (!strcasecmp(argv[i], "-h")) {
ip = argv[++i]; cont++;
} else if (!strcasecmp(argv[i], "-p")) {
port = atoi(argv[++i]); cont++;
}
}
if (cont) {
i++;
continue;
}
if (!strcasecmp(argv[i], "-t")) {
thread++;
}
i++;
}
if (!(ip && port)) {
fprintf(stderr, "Usage %s -h <host> -p <port>\n", argv[0]);
fprintf(stderr, "Usage %s [-t] -h <host> -p <port>\n", argv[0]);
return -1;
}
esl_listen(ip, port, mycallback, 100000);
if (thread) {
printf("Starting threaded listener.\n");
esl_listen_threaded(ip, port, mycallback, 100000);
} else {
printf("Starting forking listener.\n");
esl_listen(ip, port, my_forking_callback);
}
return 0;
}
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/perl
require ESL;
my $command = shift;
my $args = join(" ", @ARGV);
my $con = new ESL::ESLconnection("localhost", "8021", "ClueCon");
$con->events("plain","all");
while ( $con->connected() ) {
my $e = $con->recvEventTimed(0);
print $e->serialize;
}
+16 -5
View File
@@ -1,8 +1,16 @@
PHP=php
PHP_CONFIG=php-config
PHP_LDFLAGS=$(shell $(PHP_CONFIG) --ldflags)
PHP_LIBS=$(shell $(PHP_CONFIG) --libs | sed -r 's/ ?-l(bz2|pcre|xml2|gssapi_krb5|krb5|k5crypto|com_err|history|z|readline|gmp|ssl|crypto)//g')
PHP_EXT_DIR=$(shell $(PHP_CONFIG) --extension-dir)
PHP_INC_DIR=$(shell $(PHP) -r 'echo ini_get("include_path");' | cut -d: -f2)
PHP_INI_DIR=$(shell $(PHP_CONFIG) --configure-options | tr " " "\n" | grep -- --with-config-file-scan-dir | cut -f2 -d=)
LOCAL_CFLAGS=$(shell php-config --includes)
PHP_LDFLAGS=$(shell php-config --ldflags)
PHP_LIBS=$(shell php-config --libs | sed -r 's/ ?-l(bz2|pcre|xml2|gssapi_krb5|krb5|k5crypto|com_err|history|z|readline|gmp|ssl|crypto)//g')
LOCAL_LDFLAGS=$(PHP_LDFLAGS) $(PHP_LIBS)
LOCAL_LDFLAGS+=-lpthread
WRAP_GCC_WARNING_SILENCE=-Wno-unused-label -Wno-unused-function
all: ESL.so
@@ -25,6 +33,9 @@ swigclean:
reswig: swigclean esl_wrap.cpp
install: ESL.so
cp ESL.so $(DESTDIR)/$(shell php-config --extension-dir)
cp ESL.php /$(DESTDIR)/$(shell php -r 'echo ini_get("include_path");' | cut -d: -f2)
echo 'extension=ESL.so' >> $(DESTDIR)/$(shell php-config --configure-options | tr " " "\n" | grep -- --with-config-file-scan-dir | cut -f2 -d=)/esl.ini
test -d "$(DESTDIR)$(PHP_EXT_DIR)" || mkdir -p "$(DESTDIR)$(PHP_EXT_DIR)"
cp ESL.so "$(DESTDIR)$(PHP_EXT_DIR)"
test -d "$(DESTDIR)$(PHP_INC_DIR)" || mkdir -p "$(DESTDIR)$(PHP_INC_DIR)"
cp ESL.php "$(DESTDIR)$(PHP_INC_DIR)"
test -d "$(DESTDIR)$(PHP_INI_DIR)" || mkdir -p "$(DESTDIR)$(PHP_INI_DIR)"
test -f "$(DESTDIR)$(PHP_INI_DIR)/esl.ini" || echo 'extension=ESL.so' > "$(DESTDIR)$(PHP_INI_DIR)/esl.ini"
+61 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -568,11 +568,10 @@ ESL_DECLARE(esl_status_t) esl_sendmsg(esl_handle_t *handle, esl_event_t *event,
assert(cmd_buf);
memset(cmd_buf, 0, len);
if (uuid) {
snprintf(cmd_buf, sizeof(cmd_buf), "sendmsg %s\n%s", uuid, txt);
snprintf(cmd_buf, len, "sendmsg %s\n%s", uuid, txt);
} else {
snprintf(cmd_buf, sizeof(cmd_buf), "sendmsg\n%s", txt);
snprintf(cmd_buf, len, "sendmsg\n%s", txt);
}
esl_log(ESL_LOG_DEBUG, "%s%s\n", cmd_buf, txt);
@@ -649,7 +648,64 @@ static void *client_thread(esl_thread_t *me, void *obj)
}
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback, int max)
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback)
{
esl_socket_t server_sock = ESL_SOCK_INVALID;
struct sockaddr_in addr;
esl_status_t status = ESL_SUCCESS;
if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
return ESL_FAIL;
}
esl_socket_reuseaddr(server_sock);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
if (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
status = ESL_FAIL;
goto end;
}
if (listen(server_sock, 10000) < 0) {
status = ESL_FAIL;
goto end;
}
for (;;) {
int client_sock;
struct sockaddr_in echoClntAddr;
#ifdef WIN32
int clntLen;
#else
unsigned int clntLen;
#endif
clntLen = sizeof(echoClntAddr);
if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == ESL_SOCK_INVALID) {
status = ESL_FAIL;
goto end;
}
callback(server_sock, client_sock, &echoClntAddr);
}
end:
if (server_sock != ESL_SOCK_INVALID) {
closesocket(server_sock);
server_sock = ESL_SOCK_INVALID;
}
return status;
}
ESL_DECLARE(esl_status_t) esl_listen_threaded(const char *host, esl_port_t port, esl_listen_callback_t callback, int max)
{
esl_socket_t server_sock = ESL_SOCK_INVALID;
struct sockaddr_in addr;
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, Anthony Minessale II
* Copyright (c) 2010-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+7 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -127,6 +127,7 @@ static const char *EVENT_NAMES[] = {
"SERVER_DISCONNECTED",
"SEND_INFO",
"RECV_INFO",
"RECV_RTCP_MESSAGE",
"CALL_SECURE",
"NAT",
"RECORD_START",
@@ -137,7 +138,11 @@ static const char *EVENT_NAMES[] = {
"FAILURE",
"SOCKET_DATA",
"MEDIA_BUG_START",
"MEDIA_BUG_START",
"MEDIA_BUG_STOP",
"CONFERENCE_DATA_QUERY",
"CONFERENCE_DATA",
"CALL_SETUP_REQ",
"CALL_SETUP_RESULT",
"ALL"
};
+2
View File
@@ -0,0 +1,2 @@
const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n";
+4 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -391,7 +391,9 @@ ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t s
\param port Port to bind to
\param callback Callback that will be called upon data received
*/
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback, int max);
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback);
ESL_DECLARE(esl_status_t) esl_listen_threaded(const char *host, esl_port_t port, esl_listen_callback_t callback, int max);
/*!
\brief Executes application with sendmsg to a specific UUID. Used for outbound socket.
\param handle Handle that the msg will be sent
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, Anthony Minessale II
* Copyright (c) 2010-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+5 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -128,6 +128,10 @@ typedef enum {
ESL_EVENT_SOCKET_DATA,
ESL_EVENT_MEDIA_BUG_START,
ESL_EVENT_MEDIA_BUG_STOP,
ESL_EVENT_CONFERENCE_DATA_QUERY,
ESL_EVENT_CONFERENCE_DATA,
ESL_EVENT_CALL_SETUP_REQ,
ESL_EVENT_CALL_SETUP_RESULT,
ESL_EVENT_ALL
} esl_event_types_t;
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+1 -1
View File
@@ -48,7 +48,7 @@ static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struc
int main(void)
{
esl_global_set_default_logger(7);
esl_listen("localhost", 8084, mycallback, 100000);
esl_listen_threaded("localhost", 8084, mycallback, 100000);
return 0;
}
+12 -3
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2007, Anthony Minessale II
# Copyright (c) 2007-2012, Anthony Minessale II
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -79,7 +79,8 @@ libfreetdm_la_SOURCES = \
$(SRC)/ftdm_buffer.c \
$(SRC)/ftdm_threadmutex.c \
$(SRC)/ftdm_dso.c \
$(SRC)/ftdm_cpu_monitor.c
$(SRC)/ftdm_cpu_monitor.c \
$(SRC)/ftdm_backtrace.c
library_include_HEADERS = \
$(SRC)/include/freetdm.h \
@@ -150,7 +151,7 @@ ftmod_zt_la_LIBADD = libfreetdm.la
ftmod_skel_la_SOURCES = $(SRC)/ftmod/ftmod_skel/ftmod_skel.c
ftmod_skel_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS)
ftmod_skel_la_LDFLAGS = -module -avoid-version
ftmod_skel_la_LDFLAGS = -shared -module -avoid-version
ftmod_skel_la_LIBADD = libfreetdm.la
ftmod_analog_la_SOURCES = $(SRC)/ftmod/ftmod_analog/ftmod_analog.c
@@ -248,6 +249,14 @@ ftmod_r2_la_LDFLAGS = -shared -module -avoid-version -lopenr2
ftmod_r2_la_LIBADD = libfreetdm.la
endif
if HAVE_WAT
mod_LTLIBRARIES += ftmod_gsm.la
ftmod_gsm_la_SOURCES = $(SRC)/ftmod/ftmod_gsm/ftmod_gsm.c
ftmod_gsm_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS)
ftmod_gsm_la_LDFLAGS = -shared -module -avoid-version -lwat
ftmod_gsm_la_LIBADD = libfreetdm.la
endif
if HAVE_MISDN
mod_LTLIBRARIES += ftmod_misdn.la
ftmod_misdn_la_SOURCES = $(SRC)/ftmod/ftmod_misdn/ftmod_misdn.c
+15 -3
View File
@@ -136,7 +136,7 @@ AC_CHECK_LIB([dl], [dlopen])
AC_CHECK_LIB([pthread], [pthread_create])
AC_CHECK_LIB([m], [cos])
AC_CHECK_HEADERS([netdb.h sys/select.h])
AC_CHECK_HEADERS([netdb.h sys/select.h execinfo.h])
AC_CHECK_FUNC([gethostbyname_r],
[], [AC_CHECK_LIB([nsl], [gethostbyname_r])]
@@ -189,6 +189,14 @@ AC_CHECK_LIB([openr2], [openr2_context_set_io_type], [HAVE_OPENR2="yes"])
AC_MSG_RESULT([checking whether to build ftmod_r2... ${HAVE_OPENR2}])
AM_CONDITIONAL([HAVE_OPENR2], [test "${HAVE_OPENR2}" = "yes"])
##
# WAT GSM stack
#
HAVE_WAT="no"
AC_CHECK_LIB([wat], [wat_version], [HAVE_WAT="yes"])
AC_MSG_RESULT([checking whether to build ftmod_wat... ${HAVE_WAT}])
AM_CONDITIONAL([HAVE_WAT], [test "${HAVE_WAT}" = "yes"])
##
# Digium libpri (TODO: add checks)
#
@@ -305,7 +313,7 @@ AC_MSG_RESULT([checking whether to build ftmod_sangoma_isdn... ${HAVE_SNG_ISDN}]
AM_CONDITIONAL([HAVE_SNG_ISDN], [test "${HAVE_SNG_ISDN}" = "yes"])
if test "${HAVE_SNG_ISDN}" = "yes"; then
if test "${build}" == "${host}"
if test "${build}" = "${host}"
then
case "${host}" in
x86_64-*)
@@ -326,7 +334,7 @@ AC_MSG_RESULT([checking whether to build ftmod_sangoma_ss7... ${HAVE_SNG_SS7}])
AM_CONDITIONAL([HAVE_SNG_SS7], [test "${HAVE_SNG_SS7}" = "yes"])
if test "${HAVE_SNG_SS7}" = "yes"; then
if test "${build}" == "${host}"
if test "${build}" = "${host}"
then
case "${host}" in
x86_64-*)
@@ -451,13 +459,17 @@ AC_MSG_RESULT([
+ Modules
Signalling:
ftmod_analog....................... yes
ftmod_analog_em.................... yes
ftmod_isdn......................... ${HAVE_LIBISDN}
ftmod_libpri....................... ${HAVE_LIBPRI}
ftmod_sangoma_isdn................. ${HAVE_SNG_ISDN}
ftmod_sangoma_ss7.................. ${HAVE_SNG_SS7}
ftmod_r2........................... ${HAVE_OPENR2}
ftmod_gsm.......................... ${HAVE_WAT}
ftmod_pritap....................... ${HAVE_PRITAP}
I/O:
ftmod_zt........................... yes
ftmod_wanpipe...................... ${HAVE_LIBSANGOMA}
ftmod_misdn........................ ${HAVE_MISDN}
+163 -34
View File
@@ -26,7 +26,7 @@
* Anthony Minessale II <anthm@freeswitch.org>
* Moises Silva <moy@sangoma.com>
* David Yat Sin <dyatsin@sangoma.com>
*
* Gideon Sadan <gsadan@sangoma.com>
*
* mod_freetdm.c -- FreeTDM Endpoint Module
*
@@ -35,13 +35,6 @@
#include "freetdm.h"
//#define CUDATEL_DEBUG
#ifdef CUDATEL_DEBUG
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#include <execinfo.h>
#include <syscall.h>
#endif
#ifndef __FUNCTION__
#define __FUNCTION__ __SWITCH_FUNC__
@@ -288,7 +281,7 @@ static void cycle_foreground(ftdm_channel_t *ftdmchan, int flash, const char *bc
const char *buuid;
tech_pvt = switch_core_session_get_private(session);
channel = switch_core_session_get_channel(session);
buuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE);
buuid = switch_channel_get_partner_uuid(channel);
if (tokencnt == 1 && flash) {
@@ -499,6 +492,21 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
#ifdef CUDATEL_DEBUG
struct cudatel_trace_priv {
const char *name;
int span_id;
int chan_id;
};
static void cudatel_trace(const int tid, const void *addr, const char *symbol, void *priv)
{
struct cudatel_trace_priv *data = priv;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d][tid:%d] %s -> %s\n",
data->span_id, data->chan_id, tid, data->name, symbol);
}
#endif
static switch_status_t channel_on_hangup(switch_core_session_t *session)
{
switch_channel_t *channel = NULL;
@@ -558,19 +566,11 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
#ifdef CUDATEL_DEBUG
{
pid_t tid = 0;
size_t size = 0;
char **symbols = NULL;
void *stacktrace[50];
int si = 0;
size = backtrace(stacktrace, ftdm_array_len(stacktrace));
symbols = backtrace_symbols(stacktrace, size);
tid = syscall(SYS_gettid);
for (si = 0; si < size; si++) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d][tid:%d] %s -> %s\n",
span_id, chan_id, tid, name, symbols[si]);
}
free(symbols);
struct cudatel_trace_priv trace_data;
trace_data.name = name;
trace_data.span_id = span_id;
trace_data.chan_id = chan_id;
ftdm_backtrace_walk(&cudatel_trace, &trace_data);
}
#endif
@@ -864,7 +864,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 10);
if (!(wflags & FTDM_WRITE)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write note ready) in channel %s device %d:%d!\n", name, span_id, chan_id);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready) in channel %s device %d:%d!\n", name, span_id, chan_id);
return SWITCH_STATUS_SUCCESS;
}
@@ -1774,6 +1774,10 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Plan", "%d", channel_caller_data->rdnis.plan);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CPC", "%s", ftdm_calling_party_category2str(channel_caller_data->cpc));
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_clg_nadi");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-NADI", "%d", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdnis_screen_ind");
if (!ftdm_strlen_zero(var_value)) {
@@ -1825,8 +1829,19 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM", "%s", var_value);
}
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_cic");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CIC", "%s", var_value);
}
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Screen", "%d", channel_caller_data->screen);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Presentation", "%d", channel_caller_data->pres);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CallReference", "%d", channel_caller_data->call_reference);
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_opc");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OPC", "%s", var_value);
}
}
/* Add any call variable to the dial plan */
@@ -1872,6 +1887,24 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
switch (sigmsg->event_id) {
case FTDM_SIGEVENT_SMS:
{
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
ftdm_sms_data_t *sms = (ftdm_sms_data_t*) caller_data->priv;
ftdm_log(FTDM_LOG_INFO,"FTDM_SIGEVENT_SMS from %s: %s", sms->from, sms->body);
if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "failed to create SMS event\n");
return FTDM_FAIL;
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", sms->from);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "body", sms->body);
alarmbits = 0;
}
//return FTDM_BREAK;
break;
case FTDM_SIGEVENT_ALARM_CLEAR:
case FTDM_SIGEVENT_ALARM_TRAP:
{
@@ -1919,6 +1952,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
return FTDM_SUCCESS;
}
break;
case FTDM_SIGEVENT_RELEASED:
case FTDM_SIGEVENT_INDICATION_COMPLETED:
case FTDM_SIGEVENT_DIALING:
@@ -1947,6 +1981,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
}
if (event) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel));
@@ -2104,19 +2140,19 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
if ((session_a = switch_core_session_locate(ftdm_channel_get_token(sigmsg->channel, 0)))) {
channel_a = switch_core_session_get_channel(session_a);
br_a_uuid = switch_channel_get_variable(channel_a, SWITCH_SIGNAL_BOND_VARIABLE);
br_a_uuid = switch_channel_get_partner_uuid(channel_a);
tech_pvt = switch_core_session_get_private(session_a);
stop_hold(session_a, switch_channel_get_variable(channel_a, SWITCH_SIGNAL_BOND_VARIABLE));
stop_hold(session_a, switch_channel_get_partner_uuid(channel_a));
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
}
if ((session_b = switch_core_session_locate(ftdm_channel_get_token(sigmsg->channel, 1)))) {
channel_b = switch_core_session_get_channel(session_b);
br_b_uuid = switch_channel_get_variable(channel_b, SWITCH_SIGNAL_BOND_VARIABLE);
br_b_uuid = switch_channel_get_partner_uuid(channel_b);
tech_pvt = switch_core_session_get_private(session_b);
stop_hold(session_a, switch_channel_get_variable(channel_b, SWITCH_SIGNAL_BOND_VARIABLE));
stop_hold(session_a, switch_channel_get_partner_uuid(channel_b));
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
}
@@ -2184,7 +2220,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
tech_pvt = switch_core_session_get_private(session);
channel = switch_core_session_get_channel(session);
buuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE);
buuid = switch_channel_get_partner_uuid(channel);
ftdm_channel_call_unhold(sigmsg->channel);
stop_hold(session, buuid);
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
@@ -2804,6 +2840,95 @@ static int add_profile_parameters(switch_xml_t cfg, const char *profname, ftdm_c
return paramindex;
}
static void parse_gsm_spans(switch_xml_t cfg, switch_xml_t spans)
{
switch_xml_t myspan, param;
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
ftdm_status_t zstatus = FTDM_FAIL;
const char *context = "default";
const char *dialplan = "XML";
ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
char *id = (char *) switch_xml_attr(myspan, "id");
char *name = (char *) switch_xml_attr(myspan, "name");
char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
ftdm_span_t *span = NULL;
uint32_t span_id = 0;
unsigned paramindex = 0;
if (!name && !id) {
CONFIG_ERROR("GSM span missing required attribute 'id' or 'name', skipping ...\n");
continue;
}
if (name) {
zstatus = ftdm_span_find_by_name(name, &span);
} else {
if (switch_is_number(id)) {
span_id = atoi(id);
zstatus = ftdm_span_find(span_id, &span);
}
if (zstatus != FTDM_SUCCESS) {
zstatus = ftdm_span_find_by_name(id, &span);
}
}
if (zstatus != FTDM_SUCCESS) {
CONFIG_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
continue;
}
if (!span_id) {
span_id = ftdm_span_get_id(span);
}
memset(spanparameters, 0, sizeof(spanparameters));
paramindex = 0;
if (configname) {
paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters));
if (paramindex) {
ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id);
}
}
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (ftdm_array_len(spanparameters) - 1 == paramindex) {
CONFIG_ERROR("Too many parameters for GSM span, ignoring any parameter after %s\n", var);
break;
}
if (!strcasecmp(var, "context")) {
context = val;
} else if (!strcasecmp(var, "dialplan")) {
dialplan = val;
} else {
spanparameters[paramindex].var = var;
spanparameters[paramindex].val = val;
paramindex++;
}
}
if (ftdm_configure_span_signaling(span,
"gsm",
on_clear_channel_signal,
spanparameters) != FTDM_SUCCESS) {
CONFIG_ERROR("Error configuring Sangoma GSM FreeTDM span %d\n", span_id);
continue;
}
SPAN_CONFIG[span_id].span = span;
switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
switch_copy_string(SPAN_CONFIG[span_id].type, "GSM", sizeof(SPAN_CONFIG[span_id].type));
ftdm_log(FTDM_LOG_DEBUG, "Configured GSM FreeTDM span %d\n", span_id);
ftdm_span_start(span);
}
}
static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans)
{
switch_xml_t myspan, param;
@@ -2812,7 +2937,7 @@ static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans)
ftdm_status_t zstatus = FTDM_FAIL;
const char *context = "default";
const char *dialplan = "XML";
ftdm_conf_parameter_t spanparameters[30];
ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
char *id = (char *) switch_xml_attr(myspan, "id");
char *name = (char *) switch_xml_attr(myspan, "name");
char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
@@ -2981,13 +3106,17 @@ static switch_status_t load_config(void)
parse_bri_pri_spans(cfg, spans);
}
if ((spans = switch_xml_child(cfg, "gsm_spans"))) {
parse_gsm_spans(cfg, spans);
}
switch_core_hash_init(&globals.ss7_configs, module_pool);
if ((spans = switch_xml_child(cfg, "sangoma_ss7_spans"))) {
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
ftdm_status_t zstatus = FTDM_FAIL;
const char *context = "default";
const char *dialplan = "XML";
ftdm_conf_parameter_t spanparameters[30];
ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
char *id = (char *) switch_xml_attr(myspan, "id");
char *name = (char *) switch_xml_attr(myspan, "name");
char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
@@ -3389,7 +3518,7 @@ static switch_status_t load_config(void)
if ((spans = switch_xml_child(cfg, "pri_spans"))) {
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
char *name = (char *) switch_xml_attr(myspan, "name");
ftdm_conf_parameter_t spanparameters[10];
ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
ftdm_status_t zstatus = FTDM_FAIL;
const char *context = "default";
const char *dialplan = "XML";
@@ -3457,7 +3586,7 @@ static switch_status_t load_config(void)
ftdm_status_t zstatus = FTDM_FAIL;
unsigned paramindex = 0;
ftdm_conf_parameter_t spanparameters[10];
ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
const char *context = "default";
const char *dialplan = "XML";
ftdm_span_t *span = NULL;
@@ -3515,7 +3644,7 @@ static switch_status_t load_config(void)
if ((spans = switch_xml_child(cfg, "libpri_spans"))) {
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
char *name = (char *) switch_xml_attr(myspan, "name");
ftdm_conf_parameter_t spanparameters[10];
ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
ftdm_status_t zstatus = FTDM_FAIL;
const char *context = "default";
const char *dialplan = "XML";
@@ -3590,7 +3719,7 @@ static switch_status_t load_config(void)
uint32_t span_id = 0;
ftdm_span_t *span = NULL;
ftdm_conf_parameter_t spanparameters[30];
ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
unsigned paramindex = 0;
if (!name) {
-99
View File
@@ -1,99 +0,0 @@
# renaming main header and build file
copy="cp -r"
$copy src/include/openzap.h src/include/freetdm.h
svn delete src/include/openzap.h
$copy openzap.pc.in freetdm.pc.in
svn delete openzap.pc.in
# create mod_freetdm
mkdir mod_freetdm
cp mod_openzap/* mod_freetdm/
mv mod_freetdm/mod_openzap.c mod_freetdm/mod_freetdm.c
svn delete --force mod_openzap
##### ozmod stuff ####
# rename anything ozmod to ftmod, including directories first
mkdir ./src/ftmod
for file in `find ./src/ozmod -name *ozmod_* -type d`
do
$copy ${file} ${file//ozmod/ftmod}
done
#remove .svn directories in the copied ozmod dirs
find ./src/ftmod -name *.svn -exec rm -rf {} \;
# copy ozmod c files
for file in `find ./src/ftmod -name *ozmod_*.c`
do
mv $file ${file//ozmod/ftmod}
done
# copy ozmod h files
for file in `find ./src/ftmod -name *ozmod_*.h`
do
mv $file ${file//ozmod/ftmod}
done
#### end ozmod stuff ####
# renaming other zap files
for file in `find ./ -name *zap_*.c`
do
mv $file ${file//zap_/ftdm_}
done
for file in `find ./ -name *zap_*.h`
do
mv $file ${file//zap_/ftdm_}
done
svn revert -R src/ozmod
svn delete --force src/ozmod
# replace full openzap occurences first (handles openzap.h, libopenzap etc)
find ./ -name *.c -exec sed -i 's,openzap,freetdm,g' {} \;
find ./ -name *.h -exec sed -i 's,openzap,freetdm,g' {} \;
sed -i 's,openzap,freetdm,g' Makefile.am
sed -i 's,openzap,freetdm,g' configure.ac
sed -i 's,openzap,freetdm,g' mod_freetdm/Makefile.in
# replace inside files
find ./ -name *.c -exec sed -i 's,oz,ft,g' {} \;
find ./ -name *.c -exec sed -i 's,OZ,FT,g' {} \;
find ./ -name *.c -exec sed -i 's,zap,ftdm,g' {} \;
find ./ -name *.c -exec sed -i 's,ZAP,FTDM,g' {} \;
find ./ -name *.c -exec sed -i 's,zchan,ftdmchan,g' {} \;
find ./ -name *.h -exec sed -i 's,oz,ft,g' {} \;
find ./ -name *.h -exec sed -i 's,OZ,FT,g' {} \;
find ./ -name *.h -exec sed -i 's,zap,ftdm,g' {} \;
find ./ -name *.h -exec sed -i 's,ZAP,FTDM,g' {} \;
find ./ -name *.h -exec sed -i 's,zchan,ftdmchan,g' {} \;
sed -i 's,oz,ft,g' Makefile.am
sed -i 's,OZ,FT,g' Makefile.am
sed -i 's,zap,ftdm,g' Makefile.am
sed -i 's,ZAP,FTDM,g' Makefile.am
sed -i 's,zchan,ftdmchan,g' Makefile.am
sed -i 's,oz,ft,g' configure.ac
sed -i 's,OZ,FT,g' configure.ac
sed -i 's,zap,ftdm,g' configure.ac
sed -i 's,ZAP,FTDM,g' configure.ac
sed -i 's,zchan,ftdmchan,g' configure.ac
sed -i 's,oz,ft,g' mod_freetdm/Makefile.in
sed -i 's,OZ,FT,g' mod_freetdm/Makefile.in
sed -i 's,zap,ftdm,g' mod_freetdm/Makefile.in
sed -i 's,ZAP,FTDM,g' mod_freetdm/Makefile.in
sed -i 's,zchan,ftdmchan,g' mod_freetdm/Makefile.in
svn add src/ftmod/
svn add mod_freetdm/
-13
View File
@@ -1,13 +0,0 @@
##### ozmod stuff ####
# replace full openzap occurences first (handles openzap.h, libopenzap etc)
sed -i 's,openzap,freetdm,g' $1
sed -i 's,ozmod,ftmod,g' $1
sed -i 's,zchan,ftdmchan,g' $1
sed -i 's,oz,ft,g' $1
sed -i 's,OZ,FT,g' $1
sed -i 's,zap,ftdm,g' $1
sed -i 's,ZAP,FTDM,g' $1
sed -i 's,zio,fio,g' $1
sed -i 's,ZIO,FIO,g' $1
+75
View File
@@ -0,0 +1,75 @@
/*
*
*
*/
#define _BSD_SOURCE
#include "private/ftdm_core.h"
#ifdef HAVE_EXECINFO_H
#include <stdlib.h>
#include <unistd.h>
#include <execinfo.h>
#include <syscall.h>
#define FTDM_BACKTRACE_MAX 50
FT_DECLARE(ftdm_status_t) ftdm_backtrace_walk(void (* callback)(const int tid, const void *addr, const char *symbol, void *priv), void *priv)
{
void *stacktrace[FTDM_BACKTRACE_MAX];
char **symbols = NULL;
size_t size = 0;
pid_t tid = 0;
int si = 0;
if (!callback) {
return FTDM_EINVAL;
}
tid = syscall(SYS_gettid);
size = backtrace(stacktrace, ftdm_array_len(stacktrace));
symbols = backtrace_symbols(stacktrace, size);
for (si = 0; si < size; si++) {
callback(tid, stacktrace[si], symbols[si], priv);
}
free(symbols);
return FTDM_SUCCESS;
}
#else /* !HAVE_EXECINFO_H */
FT_DECLARE(ftdm_status_t) ftdm_backtrace_walk(void (* callback)(const int tid, const void *addr, const char *symbol, void *priv), void *priv)
{
ftdm_log(FTDM_LOG_DEBUG, "Stack traces are not available on this platform!\n");
return FTDM_NOTIMPL;
}
#endif
static void span_backtrace(const int tid, const void *addr, const char *symbol, void *priv)
{
ftdm_span_t *span = priv;
ftdm_log(FTDM_LOG_DEBUG, "[%d][tid:%d] %p -> %s\n",
ftdm_span_get_id(span), tid, addr, symbol);
}
FT_DECLARE(ftdm_status_t) ftdm_backtrace_span(ftdm_span_t *span)
{
return ftdm_backtrace_walk(&span_backtrace, span);
}
static void chan_backtrace(const int tid, const void *addr, const char *symbol, void *priv)
{
ftdm_channel_t *chan = priv;
ftdm_log(FTDM_LOG_DEBUG, "[%d:%d][tid:%d] %p -> %s\n",
ftdm_channel_get_span_id(chan), ftdm_channel_get_id(chan), tid, addr, symbol);
}
FT_DECLARE(ftdm_status_t) ftdm_backtrace_chan(ftdm_channel_t *chan)
{
return ftdm_backtrace_walk(&chan_backtrace, chan);
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+91 -32
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -262,9 +262,12 @@ FTDM_STR2ENUM(ftdm_str2ftdm_tonemap, ftdm_tonemap2str, ftdm_tonemap_t, TONEMAP_N
FTDM_ENUM_NAMES(OOB_NAMES, OOB_STRINGS)
FTDM_STR2ENUM(ftdm_str2ftdm_oob_event, ftdm_oob_event2str, ftdm_oob_event_t, OOB_NAMES, FTDM_OOB_INVALID)
FTDM_ENUM_NAMES(TRUNK_TYPE_NAMES, TRUNK_STRINGS)
FTDM_ENUM_NAMES(TRUNK_TYPE_NAMES, TRUNK_TYPE_STRINGS)
FTDM_STR2ENUM(ftdm_str2ftdm_trunk_type, ftdm_trunk_type2str, ftdm_trunk_type_t, TRUNK_TYPE_NAMES, FTDM_TRUNK_NONE)
FTDM_ENUM_NAMES(TRUNK_MODE_NAMES, TRUNK_MODE_STRINGS)
FTDM_STR2ENUM(ftdm_str2ftdm_trunk_mode, ftdm_trunk_mode2str, ftdm_trunk_mode_t, TRUNK_MODE_NAMES, FTDM_TRUNK_MODE_INVALID)
FTDM_ENUM_NAMES(START_TYPE_NAMES, START_TYPE_STRINGS)
FTDM_STR2ENUM(ftdm_str2ftdm_analog_start_type, ftdm_analog_start_type2str, ftdm_analog_start_type_t, START_TYPE_NAMES, FTDM_ANALOG_START_NA)
@@ -757,11 +760,16 @@ FT_DECLARE(ftdm_status_t) ftdm_span_stop(ftdm_span_t *span)
goto done;
}
/* Stop SIG */
status = span->stop(span);
if (FTDM_SUCCESS == status) {
if (status == FTDM_SUCCESS) {
ftdm_clear_flag(span, FTDM_SPAN_STARTED);
}
/* Stop I/O */
if (span->fio && span->fio->span_stop) {
status = span->fio->span_stop(span);
}
done:
ftdm_mutex_unlock(span->mutex);
@@ -816,6 +824,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_create(const char *iotype, const char *name,
ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_BUSY], "%(500,500,480,620)", FTDM_TONEMAP_LEN);
ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_ATTN], "%(100,100,1400,2060,2450,2600)", FTDM_TONEMAP_LEN);
new_span->trunk_type = FTDM_TRUNK_NONE;
new_span->trunk_mode = FTDM_TRUNK_MODE_CPE;
new_span->data_type = FTDM_TYPE_SPAN;
ftdm_mutex_lock(globals.span_mutex);
@@ -1994,6 +2003,21 @@ FT_DECLARE(const char *) ftdm_span_get_trunk_type_str(const ftdm_span_t *span)
return ftdm_trunk_type2str(span->trunk_type);
}
FT_DECLARE(void) ftdm_span_set_trunk_mode(ftdm_span_t *span, ftdm_trunk_mode_t mode)
{
span->trunk_mode = mode;
}
FT_DECLARE(ftdm_trunk_mode_t) ftdm_span_get_trunk_mode(const ftdm_span_t *span)
{
return span->trunk_mode;
}
FT_DECLARE(const char *) ftdm_span_get_trunk_mode_str(const ftdm_span_t *span)
{
return ftdm_trunk_mode2str(span->trunk_mode);
}
FT_DECLARE(uint32_t) ftdm_span_get_id(const ftdm_span_t *span)
{
return span->span_id;
@@ -4181,6 +4205,9 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_get_iterator(ftdm_iterator_type_t type, ftdm_
FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter)
{
if (!span->chan_count) {
return NULL;
}
if (!(iter = ftdm_get_iterator(FTDM_ITERATOR_CHANS, iter))) {
return NULL;
}
@@ -4624,7 +4651,7 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, const
static ftdm_status_t load_config(void)
{
char cfg_name[] = "freetdm.conf";
const char cfg_name[] = "freetdm.conf";
ftdm_config_t cfg;
char *var, *val;
int catno = -1;
@@ -4642,7 +4669,9 @@ static ftdm_status_t load_config(void)
if (!ftdm_config_open_file(&cfg, cfg_name)) {
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "Reading FreeTDM configuration file\n");
ftdm_log(FTDM_LOG_DEBUG, "Reading FreeTDM configuration file\n");
while (ftdm_config_next_pair(&cfg, &var, &val)) {
if (*cfg.category == '#') {
if (cfg.catno != catno) {
@@ -4653,14 +4682,14 @@ static ftdm_status_t load_config(void)
if (cfg.catno != catno) {
char *type = cfg.category + 4;
char *name;
if (*type == ' ') {
type++;
}
ftdm_log(FTDM_LOG_DEBUG, "found config for span\n");
catno = cfg.catno;
if (ftdm_strlen_zero(type)) {
ftdm_log(FTDM_LOG_CRIT, "failure creating span, no type specified.\n");
span = NULL;
@@ -4671,7 +4700,7 @@ static ftdm_status_t load_config(void)
*name++ = '\0';
}
/* Verify is trunk_type was specified for previous span */
/* Verify if trunk_type was specified for previous span */
if (span && span->trunk_type == FTDM_TRUNK_NONE) {
ftdm_log(FTDM_LOG_ERROR, "trunk_type not specified for span %d (%s)\n", span->span_id, span->name);
ret = FTDM_FAIL;
@@ -4698,11 +4727,15 @@ static ftdm_status_t load_config(void)
}
ftdm_log(FTDM_LOG_DEBUG, "span %d [%s]=[%s]\n", span->span_id, var, val);
if (!strcasecmp(var, "trunk_type")) {
ftdm_trunk_type_t trtype = ftdm_str2ftdm_trunk_type(val);
ftdm_span_set_trunk_type(span, trtype);
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s'\n", ftdm_trunk_type2str(trtype));
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s'\n", ftdm_trunk_type2str(trtype));
} else if (!strcasecmp(var, "trunk_mode")) {
ftdm_trunk_mode_t trmode = ftdm_str2ftdm_trunk_mode(val);
ftdm_span_set_trunk_mode(span, trmode);
ftdm_log(FTDM_LOG_DEBUG, "setting trunk mode to '%s'\n", ftdm_trunk_mode2str(trmode));
} else if (!strcasecmp(var, "name")) {
if (!strcasecmp(val, "undef")) {
chan_config.name[0] = '\0';
@@ -4719,16 +4752,17 @@ static ftdm_status_t load_config(void)
if (span->trunk_type == FTDM_TRUNK_FXS || span->trunk_type == FTDM_TRUNK_FXO || span->trunk_type == FTDM_TRUNK_EM) {
if ((tmp = ftdm_str2ftdm_analog_start_type(val)) != FTDM_ANALOG_START_NA) {
span->start_type = tmp;
ftdm_log(FTDM_LOG_DEBUG, "changing start type to '%s'\n", ftdm_analog_start_type2str(span->start_type));
ftdm_log(FTDM_LOG_DEBUG, "changing start type to '%s'\n", ftdm_analog_start_type2str(span->start_type));
}
} else {
ftdm_log(FTDM_LOG_ERROR, "This option is only valid on analog trunks!\n");
}
} else if (!strcasecmp(var, "fxo-channel")) {
if (span->trunk_type == FTDM_TRUNK_NONE) {
span->trunk_type = FTDM_TRUNK_FXO;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type));
span->trunk_type = FTDM_TRUNK_FXO;
span->trunk_mode = FTDM_TRUNK_MODE_CPE;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode));
}
if (span->trunk_type == FTDM_TRUNK_FXO) {
unsigned chans_configured = 0;
@@ -4737,13 +4771,14 @@ static ftdm_status_t load_config(void)
configured += chans_configured;
}
} else {
ftdm_log(FTDM_LOG_WARNING, "Cannot add FXO channels to an FXS trunk!\n");
ftdm_log(FTDM_LOG_WARNING, "Cannot add FXO channels to a %s trunk!\n", ftdm_trunk_type2str(span->trunk_type));
}
} else if (!strcasecmp(var, "fxs-channel")) {
if (span->trunk_type == FTDM_TRUNK_NONE) {
span->trunk_type = FTDM_TRUNK_FXS;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type));
span->trunk_mode = FTDM_TRUNK_MODE_NET;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode));
}
if (span->trunk_type == FTDM_TRUNK_FXS) {
unsigned chans_configured = 0;
@@ -4752,13 +4787,14 @@ static ftdm_status_t load_config(void)
configured += chans_configured;
}
} else {
ftdm_log(FTDM_LOG_WARNING, "Cannot add FXS channels to an FXO trunk!\n");
ftdm_log(FTDM_LOG_WARNING, "Cannot add FXS channels to a %s trunk!\n", ftdm_trunk_type2str(span->trunk_type));
}
} else if (!strcasecmp(var, "em-channel")) {
if (span->trunk_type == FTDM_TRUNK_NONE) {
span->trunk_type = FTDM_TRUNK_EM;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type));
span->trunk_mode = FTDM_TRUNK_MODE_CPE;
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type),
ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode));
}
if (span->trunk_type == FTDM_TRUNK_EM) {
unsigned chans_configured = 0;
@@ -4767,19 +4803,33 @@ static ftdm_status_t load_config(void)
configured += chans_configured;
}
} else {
ftdm_log(FTDM_LOG_WARNING, "Cannot add EM channels to a non-EM trunk!\n");
ftdm_log(FTDM_LOG_WARNING, "Cannot add EM channels to a %s trunk!\n", ftdm_trunk_type2str(span->trunk_type));
}
} else if (!strcasecmp(var, "b-channel")) {
unsigned chans_configured = 0;
chan_config.type = FTDM_CHAN_TYPE_B;
if (ftdm_configure_span_channels(span, val, &chan_config, &chans_configured) == FTDM_SUCCESS) {
configured += chans_configured;
if (span->trunk_type == FTDM_TRUNK_NONE) {
ftdm_log(FTDM_LOG_ERROR, "No trunk type specified in configuration file\n");
break;
}
if (FTDM_SPAN_IS_DIGITAL(span)) {
unsigned chans_configured = 0;
chan_config.type = FTDM_CHAN_TYPE_B;
if (ftdm_configure_span_channels(span, val, &chan_config, &chans_configured) == FTDM_SUCCESS) {
configured += chans_configured;
}
} else {
ftdm_log(FTDM_LOG_WARNING, "Cannot add B channels to a %s trunk!\n", ftdm_trunk_type2str(span->trunk_type));
}
} else if (!strcasecmp(var, "d-channel")) {
if (d) {
ftdm_log(FTDM_LOG_WARNING, "ignoring extra d-channel\n");
} else {
if (span->trunk_type == FTDM_TRUNK_NONE) {
ftdm_log(FTDM_LOG_ERROR, "No trunk type specified in configuration file\n");
break;
}
if (FTDM_SPAN_IS_DIGITAL(span)) {
unsigned chans_configured = 0;
if (d) {
ftdm_log(FTDM_LOG_WARNING, "ignoring extra d-channel\n");
continue;
}
if (!strncasecmp(val, "lapd:", 5)) {
chan_config.type = FTDM_CHAN_TYPE_DQ931;
val += 5;
@@ -4790,11 +4840,12 @@ static ftdm_status_t load_config(void)
configured += chans_configured;
}
d++;
} else {
ftdm_log(FTDM_LOG_WARNING, "Cannot add D channels to a %s trunk!\n", ftdm_trunk_type2str(span->trunk_type));
}
} else if (!strcasecmp(var, "cas-channel")) {
unsigned chans_configured = 0;
chan_config.type = FTDM_CHAN_TYPE_CAS;
if (ftdm_configure_span_channels(span, val, &chan_config, &chans_configured) == FTDM_SUCCESS) {
configured += chans_configured;
}
@@ -4916,7 +4967,7 @@ done:
if (!configured) {
ret = FTDM_FAIL;
}
return ret;
}
@@ -5263,6 +5314,14 @@ FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span)
goto done;
}
/* Start I/O */
if (span->fio && span->fio->span_start) {
status = span->fio->span_start(span);
if (status != FTDM_SUCCESS)
goto done;
}
/* Start SIG */
status = ftdm_report_initial_channels_alarms(span);
if (status != FTDM_SUCCESS) {
goto done;
@@ -5661,7 +5720,7 @@ static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
static ftdm_status_t ftdm_cpu_monitor_start(void)
{
if (ftdm_interrupt_create(&globals.cpu_monitor.interrupt, FTDM_INVALID_SOCKET) != FTDM_SUCCESS) {
if (ftdm_interrupt_create(&globals.cpu_monitor.interrupt, FTDM_INVALID_SOCKET, FTDM_NO_FLAGS) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to create CPU monitor interrupt\n");
return FTDM_FAIL;
}
+1 -1
View File
@@ -98,7 +98,7 @@ static ftdm_status_t ftdm_std_queue_create(ftdm_queue_t **outqueue, ftdm_size_t
goto failed;
}
if (ftdm_interrupt_create(&queue->interrupt, FTDM_INVALID_SOCKET) != FTDM_SUCCESS) {
if (ftdm_interrupt_create(&queue->interrupt, FTDM_INVALID_SOCKET, FTDM_NO_FLAGS) != FTDM_SUCCESS) {
goto failed;
}
+13 -6
View File
@@ -92,7 +92,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c
diff = fchan->history[hindex].end_time - fchan->history[hindex].time;
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Completed state change from %s to %s in %llums\n",
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Completed state change from %s to %s in %"FTDM_TIME_FMT" ms\n",
ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(state), diff);
@@ -209,7 +209,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_cancel_state(const char *file, const char
/* NOTE
* we could potentially also take out the channel from the pendingchans queue, but I believe is easier just leave it,
* the only side effect will be a call to ftdm_channel_advance_states() for a channel that has nothing to advance */
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Cancelled state change from %s to %s in %llums\n",
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Cancelled state change from %s to %s in %"FTDM_TIME_FMT" ms\n",
ftdm_channel_state2str(last_state), ftdm_channel_state2str(state), diff);
return FTDM_SUCCESS;
@@ -254,7 +254,7 @@ static ftdm_status_t ftdm_core_set_state(const char *file, const char *func, int
}
if (!ftdmchan->state_completed_interrupt) {
status = ftdm_interrupt_create(&ftdmchan->state_completed_interrupt, FTDM_INVALID_SOCKET);
status = ftdm_interrupt_create(&ftdmchan->state_completed_interrupt, FTDM_INVALID_SOCKET, FTDM_NO_FLAGS);
if (status != FTDM_SUCCESS) {
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_CRIT,
"Failed to create state change interrupt when moving from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
@@ -370,12 +370,19 @@ end:
}
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
ftdm_mutex_lock(ftdmchan->span->mutex);
ftdm_set_flag(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
if (ftdmchan->span->pendingchans) {
ftdm_queue_enqueue(ftdmchan->span->pendingchans, ftdmchan);
} else {
/* there is a potential deadlock here, if a signaling module is processing
* state changes while the ftdm_span_stop() function is called, the signaling
* thread will block until it can acquire the span lock, but the thread calling
* ftdm_span_stop() which holds the span lock is waiting on the signaling thread
* to finish ... The only reason to acquire the span lock is this flag, new
* signaling modules should use the pendingchans queue instead of this flag,
* as of today a few modules need still to be updated before we can get rid of
* this flag (ie, ftmod_libpri, ftmod_isdn, ftmod_analog) */
ftdm_set_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
}
ftdm_mutex_unlock(ftdmchan->span->mutex);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NONBLOCK)) {
/* the channel should not block waiting for state processing */
+47 -10
View File
@@ -73,6 +73,8 @@ struct ftdm_mutex {
struct ftdm_interrupt {
ftdm_socket_t device;
ftdm_wait_flag_t device_input_flags;
ftdm_wait_flag_t device_output_flags;
#ifdef WIN32
/* for generic interruption */
HANDLE event;
@@ -323,7 +325,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_mutex_unlock(const char *file, int line, const c
}
FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt, ftdm_socket_t device)
FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt, ftdm_socket_t device, ftdm_wait_flag_t device_flags)
{
ftdm_status_t status = FTDM_SUCCESS;
ftdm_interrupt_t *interrupt = NULL;
@@ -340,6 +342,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt,
}
interrupt->device = device;
interrupt->device_input_flags = device_flags;
#ifdef WIN32
interrupt->event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!interrupt->event) {
@@ -389,15 +392,16 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_wait(ftdm_interrupt_t *interrupt, int m
char pipebuf[255];
#endif
ftdm_assert_return(interrupt != NULL, FTDM_FAIL, "Condition is null!\n");
ftdm_assert_return(interrupt != NULL, FTDM_FAIL, "Interrupt is null!\n");
interrupt->device_output_flags = FTDM_NO_FLAGS;
/* start implementation */
#ifdef WIN32
ints[0] = interrupt->event;
if (interrupt->device != FTDM_INVALID_SOCKET) {
num++;
ints[1] = interrupt->device;
ftdm_log(FTDM_LOG_CRIT, "implement me! (Windows support for device_output_flags member!)\n");
}
res = WaitForMultipleObjects(num, ints, FALSE, ms >= 0 ? ms : INFINITE);
switch (res) {
@@ -422,7 +426,7 @@ pollagain:
if (interrupt->device != FTDM_INVALID_SOCKET) {
num++;
ints[1].fd = interrupt->device;
ints[1].events = POLLIN;
ints[1].events = interrupt->device_input_flags;
ints[1].revents = 0;
}
@@ -446,7 +450,17 @@ pollagain:
ftdm_log(FTDM_LOG_CRIT, "reading interrupt descriptor failed (%s)\n", strerror(errno));
}
}
if (interrupt->device != FTDM_INVALID_SOCKET) {
if (ints[1].revents & POLLIN) {
interrupt->device_output_flags |= FTDM_READ;
}
if (ints[1].revents & POLLOUT) {
interrupt->device_output_flags |= FTDM_WRITE;
}
if (ints[1].revents & POLLPRI) {
interrupt->device_output_flags |= FTDM_EVENTS;
}
}
return FTDM_SUCCESS;
#endif
}
@@ -515,10 +529,12 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru
for (i = 0; i < size; i++) {
ints[i] = interrupts[i]->event;
interrupts[i]->device_output_flags = FTDM_NO_FLAGS;
if (interrupts[i]->device != FTDM_INVALID_SOCKET) {
/* WARNING: if the device is ready for data we must implement for Windows the device_output_flags member */
ints[size+numdevices] = interrupts[i]->device;
numdevices++;
ftdm_log(FTDM_LOG_CRIT, "implement me! (Windows support for device_data_ready member!)\n", size);
}
}
@@ -548,17 +564,16 @@ pollagain:
ints[i].events = POLLIN;
ints[i].revents = 0;
ints[i].fd = interrupts[i]->readfd;
interrupts[i]->device_output_flags = FTDM_NO_FLAGS;
if (interrupts[i]->device != FTDM_INVALID_SOCKET) {
ints[size+numdevices].events = POLLIN;
ints[size+numdevices].events = interrupts[i]->device_input_flags;
ints[size+numdevices].revents = 0;
ints[size+numdevices].fd = interrupts[i]->device;
numdevices++;
}
}
res = poll(ints, size + numdevices, ms);
if (res == -1) {
if (errno == EINTR) {
goto pollagain;
@@ -571,7 +586,8 @@ pollagain:
return FTDM_TIMEOUT;
}
/* check for events in the pipes, NOT in the devices */
/* check for events in the pipes and in the devices, but service only the pipes */
numdevices = 0;
for (i = 0; i < size; i++) {
if (ints[i].revents & POLLIN) {
res = read(ints[i].fd, pipebuf, sizeof(pipebuf));
@@ -579,6 +595,18 @@ pollagain:
ftdm_log(FTDM_LOG_CRIT, "reading interrupt descriptor failed (%s)\n", strerror(errno));
}
}
if (interrupts[i]->device != FTDM_INVALID_SOCKET) {
if (ints[size+numdevices].revents & POLLIN) {
interrupts[i]->device_output_flags |= FTDM_READ;
}
if (ints[size+numdevices].revents & POLLOUT) {
interrupts[i]->device_output_flags |= FTDM_WRITE;
}
if (ints[size+numdevices].revents & POLLPRI) {
interrupts[i]->device_output_flags |= FTDM_EVENTS;
}
numdevices++;
}
}
#else
/* for MacOS compilation, unused vars */
@@ -587,6 +615,15 @@ pollagain:
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_wait_flag_t) ftdm_interrupt_device_ready(ftdm_interrupt_t *interrupt)
{
#if defined(__WINDOWS__)
/* device output flags are not currently filled for Windows upon returning from a wait function */
ftdm_log(FTDM_LOG_CRIT, "IMPLEMENT ME!\n");
#endif
return interrupt->device_output_flags;
}
/* For Emacs:
* Local Variables:
* mode:c
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -473,7 +473,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
sig.span_id = ftdmchan->span_id;
sig.channel = ftdmchan;
ftdm_assert(interval != 0, NULL);
ftdm_assert(interval != 0, "Invalid interval");
if (!dial_timeout) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Not waiting for dial tone to dial number %s\n", ftdmchan->caller_data.dnis.digits);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, Anthony Minessale II
* Copyright (c) 2008-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, Anthony Minessale II
* Copyright (c) 2008-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
File diff suppressed because it is too large. Load diff
+168 -128
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -469,10 +469,15 @@ static FIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request)
}
if (new_chan && new_chan->state == FTDM_CHANNEL_STATE_DOWN) {
isdn_data->channels_local_crv[gen->CRV] = new_chan;
struct Q931_Call *call = NULL;
memset(&new_chan->caller_data, 0, sizeof(new_chan->caller_data));
ftdm_set_flag(new_chan, FTDM_CHANNEL_OUTBOUND);
ftdm_set_state_locked(new_chan, FTDM_CHANNEL_STATE_DIALING);
call = Q931GetCallByCRV(&isdn_data->q931, gen->CRV);
Q931CallSetPrivate(call, new_chan);
switch(gen->MesType) {
case Q931mes_ALERTING:
new_chan->init_state = FTDM_CHANNEL_STATE_PROGRESS_MEDIA;
@@ -539,21 +544,17 @@ static void ftdm_isdn_call_event(struct Q931_Call *call, struct Q931_CallEvent *
{
Q931_TrunkInfo_t *trunk = NULL;
ftdm_isdn_data_t *isdn_data = NULL;
ftdm_span_t *zspan = NULL;
ftdm_span_t *span = priv;
assert(span);
assert(call);
assert(event);
trunk = Q931CallGetTrunk(call);
assert(trunk);
zspan = Q931CallGetPrivate(call);
if (!zspan) {
zspan = priv;
Q931CallSetPrivate(call, zspan);
}
assert(zspan);
isdn_data = zspan->signal_data;
isdn_data = span->signal_data;
assert(isdn_data);
if (Q931CallIsGlobal(call)) {
/*
@@ -575,7 +576,7 @@ static void ftdm_isdn_call_event(struct Q931_Call *call, struct Q931_CallEvent *
* Try to get associated zap channel
* and init sigmsg struct if there is one
*/
ftdmchan = Q931CallIsOutgoing(call) ? isdn_data->channels_local_crv[call_crv] : isdn_data->channels_remote_crv[call_crv];
ftdmchan = Q931CallGetPrivate(call);
if (ftdmchan) {
memset(&sig, 0, sizeof(ftdm_sigmsg_t));
sig.chan_id = ftdmchan->chan_id;
@@ -598,7 +599,9 @@ static void ftdm_isdn_call_event(struct Q931_Call *call, struct Q931_CallEvent *
return;
}
if (ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_DOWN) {
if (ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_DOWN &&
ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_HANGUP_COMPLETE)
{
ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d not in DOWN state, cleaning up\n",
ftdm_channel_get_span_id(ftdmchan),
ftdm_channel_get_id(ftdmchan));
@@ -763,29 +766,23 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
assert(span != NULL);
assert(isdn_data != NULL);
/*
* Support code for the new event handling system
* Remove this as soon as we have the new api to set up calls
*/
#ifdef __OLD__
if (gen->CRV) {
struct Q931_Call *call;
call = Q931GetCallByCRV(&isdn_data->q931, gen->CRV);
if (call && !Q931CallGetPrivate(call)) {
ftdm_log(FTDM_LOG_DEBUG, "Storing reference to current span in call %d [0x%x]\n", gen->CRV, gen->CRV);
Q931CallSetPrivate(call, span);
/* ftdm channel is stored in call private */
if (call) {
ftdmchan = Q931CallGetPrivate(call);
if (!ftdmchan) {
ftdm_log(FTDM_LOG_DEBUG, "[s%d] No channel associated to call [%#x] private\n",
ftdm_span_get_id(span), Q931CallGetCRV(call));
}
}
#else
if (call && !Q931CallGetPrivate(call)) {
ftdm_log(FTDM_LOG_DEBUG, "Storing reference to current span in call %d [0x%x]\n", gen->CRV, gen->CRV);
Q931CallSetPrivate(call, span);
}
#endif
ftdm_log(FTDM_LOG_DEBUG, "Yay I got an event! Type:[%02x] Size:[%d] CRV: %d (%#hx, CTX: %s)\n", gen->MesType, gen->Size, gen->CRV, gen->CRV, gen->CRVFlag ? "Terminator" : "Originator");
#ifdef __TODO_OR_REMOVE__
ftdm_log(FTDM_LOG_DEBUG, "Yay I got an event! Type:[%02x] Size:[%d] CRV: %d (%#hx, CTX: %s)\n",
gen->MesType, gen->Size, gen->CRV, gen->CRV, gen->CRVFlag ? "Terminator" : "Originator");
#ifdef __TODO__
/*
* This code block is needed for isdn_channel_request()
* isdn_data->outbound_crv has been removed so another way to pass data around is required
*/
if (gen->CRVFlag && (caller_data = isdn_data->outbound_crv[gen->CRV])) {
if (chan_id) {
caller_data->chan_id = chan_id;
@@ -808,18 +805,10 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
return 0;
}
#endif
if (gen->CRVFlag) {
ftdmchan = isdn_data->channels_local_crv[gen->CRV];
} else {
ftdmchan = isdn_data->channels_remote_crv[gen->CRV];
}
ftdm_log(FTDM_LOG_DEBUG, "ftdmchan %x (%d:%d) source isdn_data->channels_%s_crv[%#hx]\n",
ftdm_log(FTDM_LOG_DEBUG, "ftdmchan %p (%d:%d) via CRV[%#hx]\n",
ftdmchan,
((ftdmchan) ? ftdm_channel_get_span_id(ftdmchan) : -1),
((ftdmchan) ? ftdm_channel_get_id(ftdmchan) : -1),
((gen->CRVFlag) ? "local" : "remote"),
gen->CRV);
if (gen->ProtDisc == 3) {
@@ -874,12 +863,14 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
uint32_t i;
for (i = 1; i < ftdm_span_get_chan_count(span); i++) {
ftdmchan = ftdm_span_get_channel(span, chan_id);
/* Skip channels that are down and D-Channels (#OpenZAP-39) */
if (ftdm_channel_get_state(span->channels[i]) == FTDM_CHANNEL_STATE_DOWN ||
ftdm_channel_get_type(span->channels[i]) == FTDM_CHAN_TYPE_DQ921)
if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DOWN ||
ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_DQ921)
continue;
ftdm_set_state_locked(span->channels[i], FTDM_CHANNEL_STATE_RESTART);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
}
}
@@ -898,6 +889,10 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
}
}
else if (gen->MesType == Q931mes_RELEASE_COMPLETE && ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DIALTONE) {
/* Go DOWN */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
}
else if ((gen->MesType == Q931mes_RELEASE && ftdm_channel_get_state(ftdmchan) <= FTDM_CHANNEL_STATE_UP) ||
(gen->MesType == Q931mes_RELEASE_COMPLETE && ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DIALING)) {
@@ -906,7 +901,6 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
*/
Q931ie_Cause *cause = Q931GetIEPtr(gen->Cause, gen->buf);
ftdm_sigmsg_t sig;
ftdm_status_t status;
memset(&sig, 0, sizeof(sig));
sig.span_id = ftdm_channel_get_span_id(ftdmchan);
@@ -915,14 +909,15 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
sig.channel->caller_data.hangup_cause = (cause) ? cause->Value : FTDM_CAUSE_NORMAL_UNSPECIFIED;
sig.event_id = FTDM_SIGEVENT_STOP;
status = ftdm_span_send_signal(span, &sig);
ftdm_span_send_signal(span, &sig);
ftdm_log(FTDM_LOG_DEBUG, "Received %s in state %s, requested hangup for channel %d:%d\n", what,
ftdm_channel_get_state_str(ftdmchan),
ftdm_channel_get_span_id(ftdmchan),
ftdm_channel_get_id(ftdmchan));
} else {
ftdm_log(FTDM_LOG_DEBUG, "Ignoring %s on channel %d\n", what, ftdm_channel_get_id(ftdmchan));
ftdm_log(FTDM_LOG_DEBUG, "Ignoring %s on channel %d in state %s\n", what,
ftdm_channel_get_id(ftdmchan), ftdm_channel_get_state_str(ftdmchan));
}
} else {
ftdm_log(FTDM_LOG_CRIT, "Received %s with no matching channel %d\n", what, chan_id);
@@ -983,7 +978,7 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
int fail_cause = 0;
int fail = 1;
if (ftdmchan && ftdmchan == isdn_data->channels_remote_crv[gen->CRV]) {
if (ftdmchan && ftdmchan == Q931CallGetPrivate(call)) {
ftdm_log(FTDM_LOG_INFO, "Duplicate SETUP message(?) for Channel %d:%d ~ %d:%d in state %s [ignoring]\n",
ftdm_channel_get_span_id(ftdmchan),
ftdm_channel_get_id(ftdmchan),
@@ -1039,7 +1034,7 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
}
}
if (!callednum || !strlen((char *)callednum->Digit)) {
if (!callednum || ftdm_strlen_zero((char *)callednum->Digit)) {
if (FTDM_SPAN_IS_NT(span)) {
ftdm_log(FTDM_LOG_NOTICE, "No destination number found, assuming overlap dial\n");
overlap_dial++;
@@ -1080,7 +1075,6 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
if (ftdmchan && ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DOWN) {
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan);
isdn_data->channels_remote_crv[gen->CRV] = ftdmchan;
memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
if (ftdmchan->call_data) {
@@ -1095,19 +1089,12 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
if (!overlap_dial) {
isdn_get_number(callednum, caller_data->dnis.digits);
}
#ifdef __TODO_OR_REMOVE__
ftdmchan->caller_data.CRV = gen->CRV;
#endif
#if 0 /* FIXME */
if (cplen > sizeof(caller_data->raw_data)) {
cplen = sizeof(caller_data->raw_data);
}
#endif
ftdmchan->caller_data.call_reference = gen->CRV;
Q931CallSetPrivate(call, ftdmchan);
gen->CRVFlag = !(gen->CRVFlag);
#if 0 /* FIXME */
memcpy(caller_data->raw_data, msg, cplen);
caller_data->raw_data_len = cplen;
#endif
fail = 0;
}
}
@@ -1134,7 +1121,7 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
}
if (ftdmchan) {
ftdm_log(FTDM_LOG_CRIT, "Channel is busy\n");
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Channel is busy\n");
} else {
ftdm_log(FTDM_LOG_CRIT, "Failed to open channel for new setup message\n");
}
@@ -1191,7 +1178,7 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
case Q931mes_CALL_PROCEEDING:
{
if (ftdmchan) {
ftdm_log(FTDM_LOG_CRIT, "Received CALL PROCEEDING message for channel %d\n", ftdm_channel_get_id(ftdmchan));
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Received CALL PROCEEDING message for channel\n");
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
} else {
ftdm_log(FTDM_LOG_CRIT, "Received CALL PROCEEDING with no matching channel %d\n", chan_id);
@@ -1201,7 +1188,7 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
case Q931mes_CONNECT_ACKNOWLEDGE:
{
if (ftdmchan) {
ftdm_log(FTDM_LOG_DEBUG, "Received CONNECT_ACK message for channel %d\n", ftdm_channel_get_id(ftdmchan));
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Received CONNECT_ACK message for channel\n");
} else {
ftdm_log(FTDM_LOG_DEBUG, "Received CONNECT_ACK with no matching channel %d\n", chan_id);
}
@@ -1211,7 +1198,7 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
case Q931mes_INFORMATION:
{
if (ftdmchan) {
ftdm_log(FTDM_LOG_CRIT, "Received INFORMATION message for channel %d\n", ftdm_channel_get_id(ftdmchan));
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Received INFORMATION message for channel\n");
if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DIALTONE) {
char digit = '\0';
@@ -1305,19 +1292,25 @@ static int ftdm_isdn_921_21(void *pvt, L2UCHAR *msg, L2INT mlen)
static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
{
ftdm_isdn_data_t *isdn_data = ftdmchan->span->signal_data;
ftdm_span_t *span = ftdm_channel_get_span(ftdmchan);
ftdm_isdn_data_t *isdn_data = NULL;
ftdm_sigmsg_t sig;
ftdm_status_t status;
#if 1 /* FIXME caller_data.raw_data does not exist anymore, see docs/variables.txt for more info */
Q931mes_Generic empty_gen;
Q931mes_Generic *gen = &empty_gen;
memset(&empty_gen, 0, sizeof(empty_gen)) ;
#else
Q931mes_Generic *gen = (Q931mes_Generic *) ftdmchan->caller_data.raw_data;
#endif
struct Q931_Call *call = NULL;
Q931InitMesGeneric(gen);
isdn_data = span->signal_data;
assert(isdn_data);
call = Q931GetCallByCRV(&isdn_data->q931, ftdmchan->caller_data.call_reference);
if (call) {
gen->CRV = Q931CallGetCRV(call);
gen->CRVFlag = Q931CallGetDirection(call) == Q931_DIRECTION_INBOUND ? 1 : 0;
}
ftdm_log(FTDM_LOG_DEBUG, "%d:%d STATE [%s]\n",
ftdm_channel_get_span_id(ftdmchan),
@@ -1329,17 +1322,17 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
sig.chan_id = ftdm_channel_get_id(ftdmchan);
sig.channel = ftdmchan;
/* Acknowledge channel state change */
ftdm_channel_complete_state(ftdmchan);
switch (ftdm_channel_get_state(ftdmchan)) {
case FTDM_CHANNEL_STATE_DOWN:
{
if (gen->CRV) {
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
isdn_data->channels_local_crv[gen->CRV] = NULL;
} else {
isdn_data->channels_remote_crv[gen->CRV] = NULL;
}
Q931CallSetPrivate(call, NULL);
Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
}
ftdmchan->caller_data.call_reference = 0;
ftdm_channel_close(&ftdmchan);
}
break;
@@ -1348,15 +1341,10 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
sig.event_id = FTDM_SIGEVENT_PROGRESS;
if ((status = ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig) != FTDM_SUCCESS)) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
}
} else {
int crv = gen->CRV;
Q931InitMesGeneric(gen);
gen->MesType = Q931mes_CALL_PROCEEDING;
gen->CRV = crv;
gen->CRVFlag = 1; /* inbound */
if (FTDM_SPAN_IS_NT(ftdm_channel_get_span(ftdmchan))) {
Q931ie_ChanID ChanID;
@@ -1396,7 +1384,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
sig.event_id = FTDM_SIGEVENT_START;
if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
}
}
}
@@ -1406,7 +1394,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_UNSPECIFIED;
sig.event_id = FTDM_SIGEVENT_RESTART;
status = ftdm_span_send_signal(span, &sig);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
}
break;
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
@@ -1414,17 +1402,16 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
}
} else {
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
return;
}
}
gen->MesType = Q931mes_ALERTING;
gen->CRVFlag = 1; /* inbound call */
Q931Rx43(&isdn_data->q931, gen, gen->Size);
}
}
@@ -1434,21 +1421,19 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
sig.event_id = FTDM_SIGEVENT_UP;
if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
}
} else {
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
return;
}
}
gen->MesType = Q931mes_CONNECT;
gen->BearerCap = 0;
gen->CRVFlag = 1; /* inbound call */
#if 0 /* FIXME */
Q931Rx43(&isdn_data->q931, gen, ftdmchan->caller_data.raw_data_len);
#endif
Q931Rx43(&isdn_data->q931, gen, gen->Size);
}
}
break;
@@ -1560,19 +1545,18 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
gen->HLComp = Q931AppendIE(gen, (L3UCHAR *) &HLComp);
Q931Rx43(&isdn_data->q931, gen, gen->Size);
isdn_data->channels_local_crv[gen->CRV] = ftdmchan;
/*
* Support code for the new event handling system
* Remove this as soon as we have the new api to set up calls
*/
if (gen->CRV) {
struct Q931_Call *call;
call = Q931GetCallByCRV(&isdn_data->q931, gen->CRV);
if (call) {
ftdm_log(FTDM_LOG_DEBUG, "Storing reference to current span in call %d [0x%x]\n", gen->CRV, gen->CRV);
Q931CallSetPrivate(call, ftdm_channel_get_span(ftdmchan));
Q931CallSetPrivate(call, ftdmchan);
ftdmchan->caller_data.call_reference = gen->CRV;
}
}
}
@@ -1585,7 +1569,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
Q931Rx43(&isdn_data->q931, gen, gen->Size);
}
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
}
break;
case FTDM_CHANNEL_STATE_HANGUP:
@@ -1593,9 +1577,8 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan);
Q931ie_Cause cause;
ftdm_log(FTDM_LOG_DEBUG, "Hangup: Direction %s\n", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
gen->CRVFlag = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? 0 : 1;
ftdm_log(FTDM_LOG_DEBUG, "Hangup: Call direction %s\n",
ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
cause.IEId = Q931ie_CAUSE;
cause.Size = sizeof(Q931ie_Cause);
@@ -1612,7 +1595,13 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
* inbound call [was: number unknown (= not found in routing state)]
* (in Q.931 spec terms: Reject request)
*/
gen->MesType = Q931mes_RELEASE_COMPLETE;
if (!FTDM_SPAN_IS_NT(span)) {
gen->MesType = Q931mes_RELEASE_COMPLETE; /* TE mode: Reject call */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
} else {
gen->MesType = Q931mes_DISCONNECT; /* NT mode: Disconnect and wait */
//ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
}
//cause.Value = (unsigned char) FTDM_CAUSE_UNALLOCATED;
cause.Value = (unsigned char) caller_data->hangup_cause;
@@ -1621,8 +1610,8 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
Q931Rx43(&isdn_data->q931, gen, gen->Size);
/* we're done, release channel */
//ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
////ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
//ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
}
else if (ftdm_channel_get_last_state(ftdmchan) <= FTDM_CHANNEL_STATE_PROGRESS) {
/*
@@ -1636,7 +1625,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
Q931Rx43(&isdn_data->q931, gen, gen->Size);
/* this will be triggered by the RELEASE_COMPLETE reply */
/* ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); */
/* ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); */
}
else {
/*
@@ -1653,13 +1642,13 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
break;
case FTDM_CHANNEL_STATE_TERMINATING:
{
ftdm_log(FTDM_LOG_DEBUG, "Terminating: Direction %s\n", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
ftdm_log(FTDM_LOG_DEBUG, "Terminating: Call direction %s\n",
ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
sig.event_id = FTDM_SIGEVENT_STOP;
status = ftdm_span_send_signal(span, &sig);
gen->MesType = Q931mes_RELEASE;
gen->CRVFlag = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? 0 : 1;
Q931Rx43(&isdn_data->q931, gen, gen->Size);
}
default:
@@ -1679,11 +1668,8 @@ static __inline__ void check_state(ftdm_span_t *span)
if (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_channel_lock(chan);
ftdm_clear_flag(chan, FTDM_CHANNEL_STATE_CHANGE);
state_advance(chan);
ftdm_channel_complete_state(chan);
ftdm_channel_unlock(chan);
}
}
@@ -1820,7 +1806,6 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
teletone_generation_session_t ts = {{{{0}}}};;
unsigned char frame[1024];
int x, interval;
int offset = 0;
ftdm_log(FTDM_LOG_DEBUG, "ISDN tones thread starting.\n");
ftdm_set_flag(isdn_data, FTDM_ISDN_TONES_RUNNING);
@@ -1865,6 +1850,7 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
for (x = 1; x <= ftdm_span_get_chan_count(span); x++) {
ftdm_channel_t *chan = ftdm_span_get_channel(span, x);
ftdm_size_t len = sizeof(frame), rlen;
ftdm_isdn_bchan_data_t *data = chan->call_data;
if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_DQ921) {
continue;
@@ -1878,7 +1864,6 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
switch (ftdm_channel_get_state(chan)) {
case FTDM_CHANNEL_STATE_DIALTONE:
{
ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)chan->call_data;
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
/* check overlap dial timeout first before generating tone */
@@ -1951,13 +1936,24 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
continue;
}
/*
* Teletone operates on SLIN data (2 bytes per sample).
* Convert the length of non-SLIN codecs, so we read
* the right amount of samples from the buffer.
*/
if (chan->effective_codec != FTDM_CODEC_SLIN) {
len *= 2;
}
/* seek to current offset */
ftdm_buffer_seek(dt_buffer, offset);
ftdm_buffer_seek(dt_buffer, data->offset);
/*
* ftdm_channel_read() can read up to sizeof(frame) bytes
* (in certain situations). Avoid overflowing the stack (and smashing dt_buffer)
* if the codec is not slin and we had to double the length.
*/
len = ftdm_min(len, sizeof(frame));
rlen = ftdm_buffer_read_loop(dt_buffer, frame, len);
if (chan->effective_codec != FTDM_CODEC_SLIN) {
@@ -1969,6 +1965,12 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
codec_func = fio_slin2alaw;
}
/*
* Convert SLIN to native format (a-law/u-law),
* input size is 2 bytes per sample, output size
* (after conversion) is one byte per sample
* (= max. half the input size).
*/
if (codec_func) {
status = codec_func(frame, sizeof(frame), &rlen);
} else {
@@ -1976,7 +1978,21 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
goto done;
}
}
ftdm_channel_write(chan, frame, sizeof(frame), &rlen);
if (ftdm_channel_write(chan, frame, sizeof(frame), &rlen) == FTDM_SUCCESS) {
/*
* Advance offset in teletone buffer by amount
* of data actually written to channel.
*/
if (chan->effective_codec != FTDM_CODEC_SLIN) {
data->offset += rlen << 1; /* Teletone buffer is in SLIN (= rlen * 2) */
} else {
data->offset += rlen;
}
/* Limit offset to [0..Rate(Samples/s)-1] in SLIN (2 bytes per sample) units. */
data->offset %= (ts.rate << 1);
}
}
/*
@@ -1985,11 +2001,6 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
if (!gated) {
ftdm_sleep(interval);
}
offset += (ts.rate / (1000 / interval)) << 1;
if (offset >= ts.rate) {
offset = 0;
}
}
done:
@@ -2055,10 +2066,13 @@ static void *ftdm_isdn_run(ftdm_thread_t *me, void *obj)
break;
default:
{
errs = 0;
if (flags & FTDM_READ) {
len = sizeof(frame);
if (ftdm_channel_read(isdn_data->dchan, frame, &len) == FTDM_SUCCESS) {
if (ftdm_channel_read(isdn_data->dchan, frame, &len) != FTDM_SUCCESS) {
ftdm_log_chan_msg(isdn_data->dchan, FTDM_LOG_ERROR, "Failed to read from D-Channel\n");
continue;
}
if (len > 0) {
#ifdef HAVE_PCAP
if (isdn_pcap_capture_both(isdn_data)) {
isdn_pcap_write(isdn_data, frame, len, ISDN_PCAP_INCOMING);
@@ -2066,6 +2080,9 @@ static void *ftdm_isdn_run(ftdm_thread_t *me, void *obj)
#endif
Q921QueueHDLCFrame(&isdn_data->q921, frame, (int)len);
Q921Rx12(&isdn_data->q921);
/* Successful read, reset error counter */
errs = 0;
}
} else {
ftdm_log(FTDM_LOG_DEBUG, "No Read FLAG!\n");
@@ -2209,7 +2226,7 @@ static ftdm_state_map_t isdn_state_map = {
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_DIALTONE, FTDM_END},
{FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
{FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
},
{
ZSD_INBOUND,
@@ -2676,11 +2693,24 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(isdn_configure_span)
isdn_data = malloc(sizeof(*isdn_data));
assert(isdn_data != NULL);
memset(isdn_data, 0, sizeof(*isdn_data));
isdn_data->mode = Q931_TE;
memset(isdn_data, 0, sizeof(*isdn_data));
dialect = Q931_Dialect_Q931;
/* Use trunk_mode span parameter to set default */
switch (ftdm_span_get_trunk_mode(span)) {
case FTDM_TRUNK_MODE_NET:
ftdm_log(FTDM_LOG_INFO, "Span '%s' [s%d] defaulting to NET mode\n",
ftdm_span_get_name(span), ftdm_span_get_id(span));
isdn_data->mode = Q931_NT;
break;
default:
ftdm_log(FTDM_LOG_INFO, "Span '%s' [s%d] defaulting to USER mode\n",
ftdm_span_get_name(span), ftdm_span_get_id(span));
isdn_data->mode = Q931_TE;
break;
}
for (i = 0; ftdm_parameters[i].var; i++) {
const char *var = ftdm_parameters[i].var;
const char *val = ftdm_parameters[i].val;
@@ -2744,6 +2774,16 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(isdn_configure_span)
digit_timeout = DEFAULT_DIGIT_TIMEOUT;
}
/* Check if modes match and log a message if they do not. Just to be on the safe side. */
if (isdn_data->mode == Q931_TE && ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET) {
ftdm_log(FTDM_LOG_WARNING, "Span '%s' signalling set up for TE/CPE/USER mode, while port is running in NT/NET mode. You may want to check your 'trunk_mode' settings.\n",
ftdm_span_get_name(span));
}
else if (isdn_data->mode == Q931_NT && ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_CPE) {
ftdm_log(FTDM_LOG_WARNING, "Span '%s' signalling set up for NT/NET mode, while port is running in TE/CPE/USER mode. You may want to check your 'trunk_mode' settings.\n",
ftdm_span_get_name(span));
}
/* allocate per b-chan data */
if (isdn_data->mode == Q931_NT) {
ftdm_isdn_bchan_data_t *data;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -67,9 +67,6 @@ struct ftdm_isdn_data {
int32_t mode;
int32_t digit_timeout;
ftdm_isdn_opts_t opts;
ftdm_caller_data_t *outbound_crv[32768];
ftdm_channel_t *channels_local_crv[32768];
ftdm_channel_t *channels_remote_crv[32768];
#ifdef HAVE_PCAP
struct pcap_context *pcap;
#endif
@@ -81,7 +78,8 @@ typedef struct ftdm_isdn_data ftdm_isdn_data_t;
/* b-channel private data */
struct ftdm_isdn_bchan_data
{
int32_t digit_timeout;
ftdm_time_t digit_timeout;
int offset; /* offset in teletone buffer */
};
typedef struct ftdm_isdn_bchan_data ftdm_isdn_bchan_data_t;
File diff suppressed because it is too large. Load diff
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, Anthony Minessale II
* Copyright (c) 2009-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,18 +30,21 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
typedef enum {
SERVICE_CHANGE_STATUS_INSERVICE = 0,
SERVICE_CHANGE_STATUS_MAINTENANCE = 1,
SERVICE_CHANGE_STATUS_OUTOFSERVICE = 2
} service_change_status_t;
#ifndef FTMOD_LIBPRI_H
#define FTMOD_LIBPRI_H
#include "freetdm.h"
#include "lpwrap_pri.h"
#define OVERLAP_TIMEOUT_MS_DEFAULT 5000 /* 5 sec */
#define OVERLAP_TIMEOUT_MS_MIN 3000 /* 3 sec */
#define OVERLAP_TIMEOUT_MS_MAX 30000 /* 30 sec */
typedef enum {
SERVICE_CHANGE_STATUS_INSERVICE = 0,
SERVICE_CHANGE_STATUS_MAINTENANCE,
SERVICE_CHANGE_STATUS_OUTOFSERVICE
} service_change_status_t;
typedef enum {
FTMOD_LIBPRI_OPT_NONE = 0,
FTMOD_LIBPRI_OPT_SUGGEST_CHANNEL = (1 << 0),
@@ -72,15 +75,41 @@ struct ftdm_libpri_data {
int mode;
int dialect;
int overlap; /*!< Overlap dial flags */
int overlap_timeout_ms; /*!< Overlap dial timeout */
unsigned int layer1;
unsigned int ton;
unsigned int service_message_support;
lpwrap_pri_t spri;
/* MSN filter */
ftdm_hash_t *msn_hash;
ftdm_mutex_t *msn_mutex;
};
typedef struct ftdm_libpri_data ftdm_libpri_data_t;
/*
* b-channel flags
*/
enum {
FTDM_LIBPRI_B_NONE = 0,
FTDM_LIBPRI_B_REMOTE_RESTART = (1 << 0), /*!< Remote triggered channel restart */
};
/**
* Per-b-channel private data
*/
struct ftdm_libpri_b_chan {
struct lpwrap_timer t302; /*!< T302 overlap receive timer */
ftdm_channel_t *channel; /*!< back-pointer to b-channel */
q931_call *call; /*!< libpri opaque call handle */
uint32_t flags; /*!< channel flags */
};
typedef struct ftdm_libpri_b_chan ftdm_libpri_b_chan_t;
#endif
/* For Emacs:
+246 -129
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, Anthony Minessale II
* Copyright (c) 2009-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,51 +36,7 @@
#include "private/ftdm_core.h"
#include "lpwrap_pri.h"
#ifndef HAVE_GETTIMEOFDAY
#ifdef WIN32
#include <mmsystem.h>
static __inline int gettimeofday(struct timeval *tp, void *nothing)
{
#ifdef WITHOUT_MM_LIB
SYSTEMTIME st;
time_t tt;
struct tm tmtm;
/* mktime converts local to UTC */
GetLocalTime (&st);
tmtm.tm_sec = st.wSecond;
tmtm.tm_min = st.wMinute;
tmtm.tm_hour = st.wHour;
tmtm.tm_mday = st.wDay;
tmtm.tm_mon = st.wMonth - 1;
tmtm.tm_year = st.wYear - 1900; tmtm.tm_isdst = -1;
tt = mktime (&tmtm);
tp->tv_sec = tt;
tp->tv_usec = st.wMilliseconds * 1000;
#else
/**
** The earlier time calculations using GetLocalTime
** had a time resolution of 10ms.The timeGetTime, part
** of multimedia apis offer a better time resolution
** of 1ms.Need to link against winmm.lib for this
**/
unsigned long Ticks = 0;
unsigned long Sec =0;
unsigned long Usec = 0;
Ticks = timeGetTime();
Sec = Ticks/1000;
Usec = (Ticks - (Sec*1000))*1000;
tp->tv_sec = Sec;
tp->tv_usec = Usec;
#endif /* WITHOUT_MM_LIB */
(void)nothing;
return 0;
}
#endif /* WIN32 */
#endif /* HAVE_GETTIMEOFDAY */
static struct lpwrap_pri_event_list LPWRAP_PRI_EVENT_LIST[] = {
static struct lpwrap_pri_event_list LPWRAP_PRI_EVENT_LIST[LPWRAP_PRI_EVENT_MAX] = {
{0, LPWRAP_PRI_EVENT_ANY, "ANY"},
{1, LPWRAP_PRI_EVENT_DCHAN_UP, "DCHAN_UP"},
{2, LPWRAP_PRI_EVENT_DCHAN_DOWN, "DCHAN_DOWN"},
@@ -103,8 +59,6 @@ static struct lpwrap_pri_event_list LPWRAP_PRI_EVENT_LIST[] = {
{19, LPWRAP_PRI_EVENT_IO_FAIL, "IO_FAIL"},
};
#define LINE "--------------------------------------------------------------------------------"
const char *lpwrap_pri_event_str(lpwrap_pri_event_t event_id)
{
if (event_id < 0 || event_id >= LPWRAP_PRI_EVENT_MAX)
@@ -170,6 +124,10 @@ static int __pri_lpwrap_write(struct pri *pri, void *buf, int buflen)
return (int)buflen;
}
/*
* Unified init function for BRI + PRI libpri spans
*/
int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *dchan, int swtype, int node, int debug)
{
int ret = -1;
@@ -179,115 +137,255 @@ int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *
spri->span = span;
if (!spri->dchan) {
ftdm_log(FTDM_LOG_ERROR, "No D-Channel available, unable to create PRI\n");
ftdm_log(FTDM_LOG_ERROR, "No D-Channel available, unable to create BRI/PRI\n");
return ret;
}
if ((spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))) {
unsigned char buf[4] = { 0 };
size_t buflen = sizeof(buf), len = 0;
pri_set_debug(spri->pri, debug);
#ifdef HAVE_LIBPRI_AOC
pri_aoc_events_enable(spri->pri, 1);
#endif
ftdm_channel_write(spri->dchan, buf, buflen, &len);
ret = 0;
} else {
ftdm_log(FTDM_LOG_ERROR, "Unable to create PRI\n");
if (ftdm_mutex_create(&spri->timer_mutex) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Failed to create timer list mutex\n");
return ret;
}
return ret;
}
int lpwrap_init_bri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *dchan, int swtype, int node, int ptp, int debug)
{
int ret = -1;
switch (ftdm_span_get_trunk_type(span)) {
case FTDM_TRUNK_E1:
case FTDM_TRUNK_J1:
case FTDM_TRUNK_T1:
spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri);
break;
#ifdef HAVE_LIBPRI_BRI
memset(spri, 0, sizeof(struct lpwrap_pri));
spri->dchan = dchan;
spri->span = span;
if (!spri->dchan) {
ftdm_log(FTDM_LOG_ERROR, "No D-Channel available, unable to create BRI\n");
case FTDM_TRUNK_BRI:
spri->pri = pri_new_bri_cb(spri->dchan->sockfd, 1, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri);
break;
case FTDM_TRUNK_BRI_PTMP:
spri->pri = pri_new_bri_cb(spri->dchan->sockfd, 0, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri);
break;
#endif
default:
ftdm_log(FTDM_LOG_CRIT, "Invalid/unsupported trunk type '%s'\n",
ftdm_span_get_trunk_type_str(span));
ftdm_mutex_destroy(&spri->timer_mutex);
return ret;
}
if ((spri->pri = pri_new_bri_cb(spri->dchan->sockfd, ptp, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))) {
unsigned char buf[4] = { 0 };
size_t buflen = sizeof(buf), len = 0;
if (spri->pri) {
pri_set_debug(spri->pri, debug);
#ifdef HAVE_LIBPRI_AOC
pri_aoc_events_enable(spri->pri, 1);
#endif
ftdm_channel_write(spri->dchan, buf, buflen, &len);
ret = 0;
} else {
ftdm_log(FTDM_LOG_ERROR, "Unable to create BRI\n");
ftdm_log(FTDM_LOG_CRIT, "Unable to create BRI/PRI\n");
ftdm_mutex_destroy(&spri->timer_mutex);
}
#else
ftdm_log(FTDM_LOG_ERROR, "Installed libpri version (%s) has no BRI support\n",
pri_get_version());
#endif
return ret;
}
int lpwrap_one_loop(struct lpwrap_pri *spri)
#define timeval_to_ms(x) \
(((ftdm_time_t)(x)->tv_sec * 1000) + (ftdm_time_t)((x)->tv_usec / 1000))
int lpwrap_start_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer, const uint32_t timeout_ms, timeout_handler callback)
{
fd_set rfds, efds;
struct timeval now = {0,0}, *next = NULL;
struct lpwrap_timer **prev, *cur;
if (!spri || !timer || timer->timeout)
return -1;
ftdm_log_chan(spri->dchan, FTDM_LOG_DEBUG, "-- Starting timer %p with timeout %u ms\n",
timer, timeout_ms);
timer->timeout = ftdm_current_time_in_ms() + timeout_ms;
timer->callback = callback;
timer->next = NULL;
ftdm_mutex_lock(spri->timer_mutex);
for (prev = &spri->timer_list, cur = spri->timer_list; cur; prev = &(*prev)->next, cur = cur->next) {
if (cur->timeout < timer->timeout) {
*prev = timer;
timer->next = cur;
break;
}
}
if (!cur) {
*prev = timer;
}
ftdm_mutex_unlock(spri->timer_mutex);
return 0;
}
int lpwrap_stop_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer)
{
struct lpwrap_timer **prev, *cur;
if (!spri || !timer)
return -1;
if (!timer->timeout)
return 0;
ftdm_log_chan(spri->dchan, FTDM_LOG_DEBUG, "-- Stopping timer %p\n", timer);
ftdm_mutex_lock(spri->timer_mutex);
for (prev = &spri->timer_list, cur = spri->timer_list; cur; prev = &(*prev)->next, cur = cur->next) {
if (cur == timer) {
*prev = cur->next;
break;
}
}
ftdm_mutex_unlock(spri->timer_mutex);
timer->next = NULL;
timer->timeout = 0;
timer->callback = NULL;
return 0;
}
static struct lpwrap_timer *lpwrap_timer_next(struct lpwrap_pri *spri)
{
return spri ? spri->timer_list : NULL;
}
static int lpwrap_run_expired(struct lpwrap_pri *spri, ftdm_time_t now_ms)
{
struct lpwrap_timer *expired_list = NULL;
struct lpwrap_timer **prev, *cur;
if (!spri || !spri->timer_list)
return 0;
ftdm_mutex_lock(spri->timer_mutex);
/* Move all timers to expired list */
expired_list = spri->timer_list;
for (prev = &expired_list, cur = expired_list; cur; prev = &(*prev)->next, cur = cur->next) {
if (cur->timeout > now_ms) {
*prev = NULL;
break;
}
}
/* Move non-expired timer to front of timer_list (or clear list if there are none) */
spri->timer_list = cur;
ftdm_mutex_unlock(spri->timer_mutex);
/* fire callbacks */
while ((cur = expired_list)) {
expired_list = cur->next;
if (cur->callback)
cur->callback(spri, cur);
/* stop timer */
cur->next = NULL;
cur->timeout = 0;
cur->callback = NULL;
}
return 0;
}
#define LPWRAP_MAX_TIMEOUT_MS 100
#define LPWRAP_MAX_ERRORS 2
int lpwrap_run_pri_once(struct lpwrap_pri *spri)
{
struct timeval *next = NULL;
struct lpwrap_timer *timer = NULL;
pri_event *event = NULL;
event_handler handler;
int sel;
ftdm_wait_flag_t flags;
ftdm_time_t now_ms, next_ms, timeout_ms, tmp_ms;
int ret;
if (spri->on_loop) {
if ((sel = spri->on_loop(spri)) < 0) {
return sel;
if ((ret = spri->on_loop(spri)) < 0)
return FTDM_FAIL;
}
/* Default timeout when no scheduled events are pending */
timeout_ms = LPWRAP_MAX_TIMEOUT_MS;
next_ms = 0;
now_ms = ftdm_current_time_in_ms();
/*
* Get the next scheduled timer from libpri to set the maximum timeout,
* but limit it to MAX_TIMEOUT_MS (100ms).
*/
if ((next = pri_schedule_next(spri->pri))) {
next_ms = timeval_to_ms(next);
if (now_ms >= next_ms) {
/* Already late, handle timeout */
timeout_ms = 0;
} else {
/* Calculate new timeout and limit it to MAX_TIMEOUT_MS miliseconds */
tmp_ms = ftdm_min(next_ms - now_ms, LPWRAP_MAX_TIMEOUT_MS);
timeout_ms = ftdm_min(timeout_ms, tmp_ms);
}
}
if (spri->errs >= 2) {
spri->errs = 0;
return -1;
/*
* Next lpwrap_timer timeout
*/
if ((timer = lpwrap_timer_next(spri))) {
if (now_ms >= timer->timeout) {
/* Already late, handle timeout */
timeout_ms = 0;
} else {
/* Calculate new timeout and limit it to MAX_TIMEOUT_MS miliseconds */
tmp_ms = ftdm_min(timer->timeout - now_ms, LPWRAP_MAX_TIMEOUT_MS);
timeout_ms = ftdm_min(timeout_ms, tmp_ms);
}
}
FD_ZERO(&rfds);
FD_ZERO(&efds);
/* */
if (timeout_ms > 0) {
flags = FTDM_READ | FTDM_EVENTS;
ret = ftdm_channel_wait(spri->dchan, &flags, timeout_ms);
#ifdef _MSC_VER
//Windows macro for FD_SET includes a warning C4127: conditional expression is constant
#pragma warning(push)
#pragma warning(disable:4127)
#endif
if (spri->flags & LPWRAP_PRI_ABORT)
return FTDM_SUCCESS;
FD_SET(pri_fd(spri->pri), &rfds);
FD_SET(pri_fd(spri->pri), &efds);
if (ret == FTDM_TIMEOUT) {
now_ms = ftdm_current_time_in_ms();
#ifdef _MSC_VER
#pragma warning(pop)
#endif
now.tv_sec = 0;
now.tv_usec = 100000;
sel = select(pri_fd(spri->pri) + 1, &rfds, NULL, &efds, &now);
if (!sel) {
if ((next = pri_schedule_next(spri->pri))) {
gettimeofday(&now, NULL);
if (now.tv_sec >= next->tv_sec && (now.tv_usec >= next->tv_usec || next->tv_usec <= 100000)) {
//ftdm_log(FTDM_LOG_DEBUG, "Check event\n");
if (next) {
if (next_ms < now_ms) {
ftdm_log_chan(spri->dchan, FTDM_LOG_DEBUG, "pri timer %d ms late\n",
(int)(now_ms - next_ms));
}
event = pri_schedule_run(spri->pri);
}
if (timer) {
if (timer->timeout < now_ms) {
ftdm_log_chan(spri->dchan, FTDM_LOG_DEBUG, "lpwrap timer %d ms late\n",
(int)(now_ms - timer->timeout));
}
lpwrap_run_expired(spri, now_ms);
}
} else if (flags & (FTDM_READ | FTDM_EVENTS)) {
event = pri_check_event(spri->pri);
}
} else {
/*
* Scheduled event has already expired, handle it immediately
*/
if (next) {
event = pri_schedule_run(spri->pri);
}
if (timer) {
lpwrap_run_expired(spri, now_ms);
}
} else if (sel > 0) {
event = pri_check_event(spri->pri);
}
if (spri->flags & LPWRAP_PRI_ABORT)
return FTDM_SUCCESS;
if (event) {
event_handler handler;
/* 0 is catchall event handler */
if (event->e < 0 || event->e >= LPWRAP_PRI_EVENT_MAX) {
handler = spri->eventmap[0];
@@ -303,28 +401,47 @@ int lpwrap_one_loop(struct lpwrap_pri *spri)
ftdm_log(FTDM_LOG_CRIT, "No event handler found for event %d.\n", event->e);
}
}
return sel;
return FTDM_SUCCESS;
}
int lpwrap_run_pri(struct lpwrap_pri *spri)
{
int ret = 0;
for (;;) {
if ((ret = lpwrap_one_loop(spri)) < 0) {
#ifndef WIN32 //This needs to be adressed fror WIN32 still
if (errno == EINTR){
/* Igonore an interrupted system call */
continue;
}
#endif
ftdm_log(FTDM_LOG_CRIT, "Error = %i [%s]\n", ret, strerror(errno));
while (!(spri->flags & LPWRAP_PRI_ABORT)) {
ret = lpwrap_run_pri_once(spri);
if (ret) {
ftdm_log(FTDM_LOG_ERROR, "Error = %d, [%s]\n",
ret, strerror(errno));
spri->errs++;
} else {
spri->errs = 0;
}
if (!ftdm_running())
break;
if (spri->errs >= LPWRAP_MAX_ERRORS) {
ftdm_log(FTDM_LOG_CRIT, "Too many errors on span, restarting\n");
spri->errs = 0;
break;
}
}
return ret;
}
int lpwrap_stop_pri(struct lpwrap_pri *spri)
{
spri->flags |= LPWRAP_PRI_ABORT;
return FTDM_SUCCESS;
}
int lpwrap_destroy_pri(struct lpwrap_pri *spri)
{
if (spri->timer_mutex)
ftdm_mutex_destroy(&spri->timer_mutex);
return FTDM_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, Anthony Minessale II
* Copyright (c) 2009-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -92,10 +92,14 @@ typedef enum {
} lpwrap_pri_switch_t;
typedef enum {
LPWRAP_PRI_READY = (1 << 0)
LPWRAP_PRI_READY = (1 << 0),
LPWRAP_PRI_ABORT = (1 << 1)
} lpwrap_pri_flag_t;
struct lpwrap_pri;
struct lpwrap_timer;
typedef int (*timeout_handler)(struct lpwrap_pri *, struct lpwrap_timer *);
typedef int (*event_handler)(struct lpwrap_pri *, lpwrap_pri_event_t, pri_event *);
typedef int (*loop_handler)(struct lpwrap_pri *);
@@ -108,6 +112,8 @@ struct lpwrap_pri {
event_handler eventmap[LPWRAP_PRI_EVENT_MAX];
loop_handler on_loop;
int errs;
struct lpwrap_timer *timer_list;
ftdm_mutex_t *timer_mutex;
};
typedef struct lpwrap_pri lpwrap_pri_t;
@@ -118,15 +124,21 @@ struct lpwrap_pri_event_list {
const char *name;
};
struct lpwrap_timer {
struct lpwrap_timer *next;
ftdm_time_t timeout;
timeout_handler callback;
};
int lpwrap_start_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer, const uint32_t timeout_ms, timeout_handler callback);
int lpwrap_stop_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer);
#define LPWRAP_MAP_PRI_EVENT(spri, event, func) spri.eventmap[event] = func;
const char *lpwrap_pri_event_str(lpwrap_pri_event_t event_id);
int lpwrap_one_loop(struct lpwrap_pri *spri);
int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *dchan, int swtype, int node, int debug);
int lpwrap_init_bri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *dchan, int swtype, int node, int ptp, int debug);
int lpwrap_run_pri(struct lpwrap_pri *spri);
#define lpwrap_run_bri(x) lpwrap_run_pri(x)
int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *dchan, int swtype, int node, int debug);
int lpwrap_destroy_pri(struct lpwrap_pri *spri);
int lpwrap_run_pri_once(struct lpwrap_pri *spri);
int lpwrap_run_pri(struct lpwrap_pri *spri);
int lpwrap_stop_pri(struct lpwrap_pri *spri);
#endif
File diff suppressed because it is too large. Load diff
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -782,7 +782,7 @@ static ftdm_status_t ftdm_pritap_sig_read(ftdm_channel_t *ftdmchan, void *data,
return FTDM_FAIL;
}
if (sizeread != size) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "read from peer channel only %d bytes!\n", sizeread);
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "read from peer channel only %"FTDM_SIZE_FMT" bytes!\n", sizeread);
return FTDM_FAIL;
}
@@ -854,7 +854,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span)
}
if (!dchan) {
ftdm_log(FTDM_LOG_ERROR, "No d-channel specified in freetdm.conf!\n", ftdm_trunk_type2str(span->trunk_type));
ftdm_log(FTDM_LOG_ERROR, "No d-channel specified in freetdm.conf!\n");
return FTDM_FAIL;
}
+3 -3
View File
@@ -1557,10 +1557,10 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
intval = atoi(val);
if (intval < 0) {
r2conf.mf_dump_size = FTDM_IO_DUMP_DEFAULT_BUFF_SIZE;
ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with default mf_dump_size = %d bytes\n", span->name, r2conf.mf_dump_size);
ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with default mf_dump_size = %"FTDM_SIZE_FMT" bytes\n", span->name, r2conf.mf_dump_size);
} else {
r2conf.mf_dump_size = intval;
ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with mf_dump_size = %d bytes\n", span->name, r2conf.mf_dump_size);
ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with mf_dump_size = %"FTDM_SIZE_FMT" bytes\n", span->name, r2conf.mf_dump_size);
}
} else if (!strcasecmp(var, "allow_collect_calls")) {
r2conf.allow_collect_calls = ftdm_true(val);
@@ -1970,7 +1970,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
r2data->monitor_thread_id = syscall(SYS_gettid);
#endif
ftdm_log(FTDM_LOG_DEBUG, "OpenR2 monitor thread %lu started.\n", r2data->monitor_thread_id);
ftdm_log(FTDM_LOG_DEBUG, "OpenR2 monitor thread %u started.\n", r2data->monitor_thread_id);
r2chan = NULL;
chaniter = ftdm_span_get_chan_iterator(span, NULL);
if (!chaniter) {
@@ -451,17 +451,17 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
/* get an interrupt queue for this span */
if (ftdm_queue_get_interrupt(span->pendingchans, &ftdm_sangoma_isdn_int[0]) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to get a ftdm_interrupt for span = %s!\n", span->name);
ftdm_log(FTDM_LOG_CRIT, "Failed to get a ftdm_interrupt for span = %s!\n", span->name);
goto ftdm_sangoma_isdn_run_exit;
}
if (ftdm_queue_get_interrupt(span->pendingsignals, &ftdm_sangoma_isdn_int[1]) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to get a signal interrupt for span = %s!\n", span->name);
ftdm_log(FTDM_LOG_CRIT, "Failed to get a signal interrupt for span = %s!\n", span->name);
goto ftdm_sangoma_isdn_run_exit;
}
if (ftdm_queue_get_interrupt(signal_data->event_queue, &ftdm_sangoma_isdn_int[2]) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to get a event interrupt for span = %s!\n", span->name);
ftdm_log(FTDM_LOG_CRIT, "Failed to get a event interrupt for span = %s!\n", span->name);
goto ftdm_sangoma_isdn_run_exit;
}
@@ -528,6 +528,7 @@ ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb);
ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb);
ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt);
ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
ftdm_status_t set_called_subaddr(ftdm_channel_t *ftdmchan, CdPtySad *cdPtySad);
ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind);
ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap);
ftdm_status_t set_network_specific_fac(ftdm_channel_t *ftdmchan, NetFac *netFac);
@@ -131,7 +131,7 @@ static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span
/* can be > 1 for some BRI variants */
break;
default:
ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type));
ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunktype:%s\n", span->name, ftdm_trunk_type2str(span->trunk_type));
return FTDM_FAIL;
}
@@ -523,7 +523,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
parse_yesno(var, val, &signal_data->restart_opt);
} else if (!strcasecmp(var, "channel-restart-timeout")) {
signal_data->restart_timeout = atoi(val);
} else if (!strcasecmp(var, "local-number")) {
} else if (!strcasecmp(var, "local-number")) {
if (add_local_number(val, span) != FTDM_SUCCESS) {
return FTDM_FAIL;
}
@@ -719,7 +719,11 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
cfg.t.cfg.s.inDLSAP.clrGlr = FALSE; /* in case of glare, do not clear local call */
cfg.t.cfg.s.inDLSAP.statEnqOpt = TRUE;
cfg.t.cfg.s.inDLSAP.rstOpt = TRUE;
if (signal_data->ftdm_span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
cfg.t.cfg.s.inDLSAP.rstOpt = FALSE;
} else {
cfg.t.cfg.s.inDLSAP.rstOpt = TRUE;
}
} else {
cfg.t.cfg.s.inDLSAP.ackOpt = FALSE;
cfg.t.cfg.s.inDLSAP.intType = USER;
@@ -841,19 +845,17 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
cfg.t.cfg.s.inDLSAP.tmr.t308.enb = TRUE;
cfg.t.cfg.s.inDLSAP.tmr.t308.val = 4;
cfg.t.cfg.s.inDLSAP.tmr.t310.enb = TRUE;
cfg.t.cfg.s.inDLSAP.tmr.t310.val = 120;
if (signal_data->timer_t308 > 0) {
cfg.t.cfg.s.inDLSAP.tmr.t308.val = signal_data->timer_t308;
}
if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
cfg.t.cfg.s.inDLSAP.tmr.t310.enb = TRUE;
cfg.t.cfg.s.inDLSAP.tmr.t310.val = 10;
cfg.t.cfg.s.inDLSAP.tmr.t312.enb = TRUE;
cfg.t.cfg.s.inDLSAP.tmr.t312.val = cfg.t.cfg.s.inDLSAP.tmr.t303.val+2;
} else {
cfg.t.cfg.s.inDLSAP.tmr.t310.enb = TRUE;
cfg.t.cfg.s.inDLSAP.tmr.t310.val = 120;
cfg.t.cfg.s.inDLSAP.tmr.t312.enb = FALSE;
}
@@ -967,7 +969,7 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
cfg.t.cfg.s.inDLSAP.dChannelNum = 0; /* Unused for BRI */
cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_BRI_CHANNELS_PER_SPAN;
cfg.t.cfg.s.inDLSAP.firstBChanNum = 1;
cfg.t.cfg.s.inDLSAP.callRefLen = 1;
cfg.t.cfg.s.inDLSAP.callRefLen = 1;
cfg.t.cfg.s.inDLSAP.teiAlloc = IN_STATIC;
cfg.t.cfg.s.inDLSAP.intCfg = IN_INTCFG_PTPT;
break;
@@ -1023,7 +1025,13 @@ ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span)
cfg.t.cfg.s.inLCe.sapId = signal_data->link_id;
cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE;
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
/* Stack will send Restart CFM's each time link is established (TEI negotiated),
and we do not want thi s event */
cfg.t.cfg.s.inLCe.lnkUpDwnInd = FALSE;
} else {
cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE;
}
if (FTDM_SPAN_IS_BRI(span)) {
/* tCon Timer causes unwanted hangup on BRI links
@@ -1225,7 +1233,7 @@ uint8_t sng_isdn_stack_switchtype(sngisdn_switchtype_t switchtype)
case SNGISDN_SWITCH_INSNET:
return SW_INSNET;
case SNGISDN_SWITCH_INVALID:
ftdm_log(FTDM_LOG_ERROR, "%s:Invalid switchtype:%d\n", switchtype);
ftdm_log(FTDM_LOG_ERROR, "Invalid switchtype: %d\n", switchtype);
break;
}
return 0;
@@ -493,7 +493,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
if (cnStEvnt->sndCmplt.eh.pres || num_digits >= min_digits) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
} else {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "received %d of %d digits\n", num_digits, min_digits);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "received %"FTDM_SIZE_FMT" of %"FTDM_SIZE_FMT" digits\n", num_digits, min_digits);
}
}
break;
@@ -509,7 +509,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "\n", suId, suInstId, spInstId);
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled INFO (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
break;
}
}
@@ -966,6 +966,12 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
break;
case 2: /* overlap sending */
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_COLLECT:
/* T302 Timeout reached */
/* Send the call to user, and see if they accept it */
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T302 Timer expired, proceeding with call\n");
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
break;
case FTDM_CHANNEL_STATE_PROCEED:
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_RINGING:
@@ -1196,7 +1202,16 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
return;
}
if (rstEvnt->rstInd.eh.pres == PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres == PRSNT_NODEF) {
ftdm_log(FTDM_LOG_DEBUG, "%s: Processing RESTART CFM (suId:%u dChan:%d ces:%d %s(%d))\n",
signal_data->ftdm_span->name,
suId, dChan, ces,
(evntType == IN_LNK_DWN)?"LNK_DOWN":
(evntType == IN_LNK_UP)?"LNK_UP":
(evntType == IN_INDCHAN)?"b-channel":
(evntType == IN_LNK_DWN_DM_RLS)?"NFAS service procedures":
(evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown", evntType);
if (rstEvnt->rstInd.eh.pres == PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres == PRSNT_NODEF) {
switch(rstEvnt->rstInd.rstClass.val) {
case IN_CL_INDCHAN: /* Indicated b-channel */
if (rstEvnt->chanId.eh.pres) {
@@ -1342,28 +1357,29 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
}
if (chan_no) { /* For a single channel */
if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) {
ftdm_log(FTDM_LOG_CRIT, "Received RESTART IND on invalid channel:%d\n", chan_no);
} else {
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
if (ftdmchan->physical_chan_id == chan_no) {
sngisdn_bring_down(ftdmchan);
}
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
if (sngisdn_info->ces == ces && ftdmchan->physical_chan_id == chan_no) {
sngisdn_bring_down(ftdmchan);
}
ftdm_iterator_free(chaniter);
}
ftdm_iterator_free(chaniter);
} else { /* for all channels */
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
sngisdn_bring_down((ftdm_channel_t*)ftdm_iterator_current(curr));
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
if (sngisdn_info->ces == ces) {
sngisdn_bring_down(ftdmchan);
}
}
ftdm_iterator_free(chaniter);
}
@@ -67,6 +67,7 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
set_calling_num(ftdmchan, &conEvnt.cgPtyNmb);
set_calling_num2(ftdmchan, &conEvnt.cgPtyNmb2);
set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad);
set_called_subaddr(ftdmchan, &conEvnt.cdPtySad);
set_redir_num(ftdmchan, &conEvnt.redirNmb);
set_calling_name(ftdmchan, &conEvnt);
set_network_specific_fac(ftdmchan, &conEvnt.netFac[0]);
@@ -1084,7 +1084,7 @@ void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...)
switch (level) {
case SNG_LOGLEVEL_DEBUG:
ftdm_log(FTDM_LOG_DEBUG, "sng_isdn->%s", data);
ftdm_log(FTDM_LOG_DEBUG, "sng_isdn->%s\n", data);
break;
case SNG_LOGLEVEL_WARN:
if ( strncmp(data, "Invalid Q.921/Q.931 frame", 25) ) {
@@ -1092,21 +1092,21 @@ void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...)
}
break;
case SNG_LOGLEVEL_INFO:
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s\n", data);
break;
case SNG_LOGLEVEL_STATS:
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s\n", data);
break;
case SNG_LOGLEVEL_ERROR:
ftdm_log(FTDM_LOG_ERROR, "sng_isdn->%s", data);
ftdm_log(FTDM_LOG_ERROR, "sng_isdn->%s\n", data);
/*ftdm_assert(0, "Got an error from stack");*/
break;
case SNG_LOGLEVEL_CRIT:
ftdm_log(FTDM_LOG_CRIT, "sng_isdn->%s", data);
ftdm_log(FTDM_LOG_CRIT, "sng_isdn->%s\n", data);
/* ftdm_assert(0, "Got an error from stack"); */
break;
default:
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s\n", data);
break;
}
ftdm_safe_free(data);
@@ -453,7 +453,7 @@ ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
}
memset(subaddress, 0, sizeof(subaddress));
if(cgPtySad->sadInfo.len >= sizeof(subaddress)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Calling Party Subaddress exceeds local size limit (len:%d max:%d)\n", cgPtySad->sadInfo.len, sizeof(subaddress));
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Calling Party Subaddress exceeds local size limit (len:%d max:%"FTDM_SIZE_FMT")\n", cgPtySad->sadInfo.len, sizeof(subaddress));
cgPtySad->sadInfo.len = sizeof(subaddress)-1;
}
@@ -847,6 +847,26 @@ ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
return FTDM_SUCCESS;
}
ftdm_status_t set_called_subaddr(ftdm_channel_t *ftdmchan, CdPtySad *cdPtySad)
{
const char* cld_subaddr = NULL;
cld_subaddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.called_subaddr");
if (!ftdm_strlen_zero(cld_subaddr)) {
unsigned len = strlen (cld_subaddr);
cdPtySad->eh.pres = PRSNT_NODEF;
cdPtySad->typeSad.pres = 1;
cdPtySad->typeSad.val = 0; /* NSAP */
cdPtySad->oddEvenInd.pres = 1;
cdPtySad->oddEvenInd.val = 0;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Called Party Subaddress:%s\n", cld_subaddr);
cdPtySad->sadInfo.pres = 1;
cdPtySad->sadInfo.len = len;
memcpy(cdPtySad->sadInfo.val, cld_subaddr, len);
}
return FTDM_SUCCESS;
}
ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
{
ftdm_status_t status;
@@ -1198,7 +1218,7 @@ void sngisdn_restart_timeout(void *p_signal_data)
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
ftdm_log(FTDM_LOG_DEBUG, "s%d:Did not receive a RESTART from remote switch in %d ms - restarting\n", span->name, signal_data->restart_timeout);
ftdm_log(FTDM_LOG_DEBUG, "s%s:Did not receive a RESTART from remote switch in %d ms - restarting\n", span->name, signal_data->restart_timeout);
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
@@ -152,7 +152,7 @@ static ftdm_status_t att_courtesy_vru(ftdm_channel_t *ftdmchan, sngisdn_transfer
goto done;
}
if (strlen(val) > COURTESY_TRANSFER_MAX_DATA_SIZE) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Data exceeds max size (len:%d max:%d), cannot perform transfer\n", strlen(val), COURTESY_TRANSFER_MAX_DATA_SIZE);
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Data exceeds max size (len:%"FTDM_SIZE_FMT" max:%d), cannot perform transfer\n", strlen(val), COURTESY_TRANSFER_MAX_DATA_SIZE);
goto done;
}
memcpy(sngisdn_info->transfer_data.tdata.att_courtesy_vru.data, val, strlen(val));
@@ -99,17 +99,18 @@ int ft_to_sngss7_cfg_all(void)
return 1;
} else {
SS7_INFO("Started Stack Manager!\n");
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SM);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SM_STARTED);
}
/* check if the configuration had a Relay Channel */
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY_PRESENT)) {
/* start up the relay task */
if (sng_isup_init_relay()) {
SS7_CRITICAL("Failed to start Relay\n");
return 1;
} else {
SS7_INFO("Started Relay!\n");
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY_STARTED);
}
/* run general configuration on the relay task */
@@ -122,12 +123,13 @@ int ft_to_sngss7_cfg_all(void)
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY)) */
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC_PRESENT)) {
if (sng_isup_init_cc()) {
SS7_CRITICAL("Failed to start Call-Control\n");
return 1;
} else {
SS7_INFO("Started Call-Control!\n");
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC_STARTED);
}
if (ftmod_ss7_cc_gen_config()) {
SS7_CRITICAL("CC General configuration FAILED!\n");
@@ -143,12 +145,13 @@ int ft_to_sngss7_cfg_all(void)
}
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC)) */
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_PRESENT)) {
if (sng_isup_init_isup()) {
SS7_CRITICAL("Failed to start ISUP\n");
return 1;
} else {
SS7_INFO("Started ISUP!\n");
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED);
}
if (ftmod_ss7_isup_gen_config()) {
SS7_CRITICAL("ISUP General configuration FAILED!\n");
@@ -158,12 +161,13 @@ int ft_to_sngss7_cfg_all(void)
}
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3_PRESENT)) {
if (sng_isup_init_mtp3()) {
SS7_CRITICAL("Failed to start MTP3\n");
return 1;
} else {
SS7_INFO("Started MTP3!\n");
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3_STARTED);
}
if (ftmod_ss7_mtp3_gen_config()) {
@@ -174,18 +178,20 @@ int ft_to_sngss7_cfg_all(void)
}
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3)) */
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_PRESENT)) {
if (sng_isup_init_mtp2()) {
SS7_CRITICAL("Failed to start MTP2\n");
return 1;
} else {
SS7_INFO("Started MTP2!\n");
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_STARTED);
}
if (sng_isup_init_mtp1()) {
SS7_CRITICAL("Failed to start MTP2\n");
SS7_CRITICAL("Failed to start MTP1\n");
return 1;
} else {
SS7_INFO("Started MTP1!\n");
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP1_STARTED);
}
if (ftmod_ss7_mtp1_gen_config()) {
SS7_CRITICAL("MTP1 General configuration FAILED!\n");
@@ -376,7 +382,7 @@ int ft_to_sngss7_cfg_all(void)
x++;
} /* while (x < (MAX_ISAPS)) */
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED)) {
x = 1;
while (x < (MAX_ISUP_INFS)) {
/* check if this link has been configured already */
@@ -913,13 +919,14 @@ int ftmod_ss7_mtp3_dlsap_config(int id)
#endif /* SDT2 */
cfg.t.cfg.s.snDLSAP.lnkId = 0; /* signalling link allocation procedure identity */
cfg.t.cfg.s.snDLSAP.lnkTstSLC = k->slc; /* link selection code for link test */
cfg.t.cfg.s.snDLSAP.tstLen = 6; /* link test pattern length */
cfg.t.cfg.s.snDLSAP.tst[0] = 'K'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.tst[1] = 'O'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.tstLen = 7; /* link test pattern length */
cfg.t.cfg.s.snDLSAP.tst[0] = 'S'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.tst[1] = 'A'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.tst[2] = 'N'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.tst[3] = 'R'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.tst[4] = 'A'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.tst[5] = 'D'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.tst[3] = 'G'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.tst[4] = 'O'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.tst[5] = 'M'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.tst[6] = 'A'; /* link test pattern */
cfg.t.cfg.s.snDLSAP.ssf = k->ssf; /* sub service field */
cfg.t.cfg.s.snDLSAP.dstProcId = k->mtp2ProcId; /* destination processor id */
cfg.t.cfg.s.snDLSAP.dstEnt = ENTSD; /* entity */
File diff suppressed because it is too large. Load diff
@@ -89,12 +89,13 @@ ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt)
{
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
char nadi[2];
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
memset(nadi, '\0', sizeof(nadi));
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
char var[FTDM_DIGITS_LIMIT];
memset(var, '\0', sizeof(var));
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@@ -209,12 +210,52 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
}
/* add any special variables for the dialplan */
sprintf(nadi, "%d", siConEvnt->cgPtyNum.natAddrInd.val);
sngss7_add_var(sngss7_info, "ss7_clg_nadi", nadi);
sprintf(var, "%d", siConEvnt->cgPtyNum.natAddrInd.val);
sngss7_add_var(sngss7_info, "ss7_clg_nadi", var);
sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
sngss7_add_var(sngss7_info, "ss7_cld_nadi", nadi);
sprintf(var, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
sngss7_add_var(sngss7_info, "ss7_cld_nadi", var);
/* Retrieve the Location Number if present (see ITU Q.763, 3.30) */
if (siConEvnt->cgPtyNum1.eh.pres) {
if (siConEvnt->cgPtyNum1.addrSig.pres) {
/* fill in the ss7 location address number */
copy_tknStr_from_sngss7(siConEvnt->cgPtyNum1.addrSig, var, siConEvnt->cgPtyNum1.oddEven);
sngss7_add_var(sngss7_info, "ss7_loc_digits", var);
}
if (siConEvnt->cgPtyNum1.scrnInd.pres) {
/* fill in the screening indication value */
sprintf(var, "%d", siConEvnt->cgPtyNum1.scrnInd.val);
sngss7_add_var(sngss7_info, "ss7_loc_screen_ind", var);
}
if (siConEvnt->cgPtyNum1.presRest.pres) {
/* fill in the presentation value */
sprintf(var, "%d", siConEvnt->cgPtyNum1.presRest.val);
sngss7_add_var(sngss7_info, "ss7_loc_pres_ind", var);
}
if (siConEvnt->cgPtyNum1.natAddrInd.pres) {
sprintf(var, "%d", siConEvnt->cgPtyNum1.natAddrInd.val);
sngss7_add_var(sngss7_info, "ss7_loc_nadi", var);
}
} else {
SS7_DEBUG_CHAN(ftdmchan, "No Location Number information in IAM%s\n", " ");
}
sprintf(var, "%d", sngss7_info->circuit->cic);
sngss7_add_var(sngss7_info, "ss7_cic", var);
sprintf(var, "%d", g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].spc );
sngss7_add_var(sngss7_info, "ss7_opc", var);
if (siConEvnt->callRef.callId.pres) {
ftdmchan->caller_data.call_reference = (unsigned int)siConEvnt->callRef.callId.val;
} else {
ftdmchan->caller_data.call_reference = 0;
}
if (sngss7_info->circuit->transparent_iam) {
sngss7_save_iam(ftdmchan, siConEvnt);
}
@@ -252,9 +293,9 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
case (FTDM_CHANNEL_STATE_HANGUP_COMPLETE):
handle_glare:
/* the core already has plans for this channel...glare */
SS7_INFO_CHAN(ftdmchan, "Got IAM on channel that is already inuse (state=%s|inuse=%d)...glare!\n",
SS7_INFO_CHAN(ftdmchan, "Got IAM on channel that is already inuse (state=%s|inuse=%c)...glare!\n",
ftdm_channel_state2str (ftdmchan->state),
ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE));
ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) ? 'Y' : 'N');
/* save the info so that we can use it later on */
sngss7_info->glare.spInstId = spInstId;
@@ -401,6 +442,8 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
append_tknStr_from_sngss7(siCnStEvnt->subNum.addrSig,
ftdmchan->caller_data.dnis.digits,
siCnStEvnt->subNum.oddEven);
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Rx SAM (digits = %s)\n", sngss7_info->circuit->cic,
ftdmchan->caller_data.dnis.digits);
} else {
SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in SAM!%s\n", " ");
}
@@ -696,7 +739,7 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
* ITU Q.784 Test Number 3.8
* Collision of REL messages
*/
SS7_DEBUG_CHAN(ftdmchan, "Collision of REL messages. Rx REL while waiting for RLC.\n", " ");
SS7_DEBUG_CHAN(ftdmchan, "Collision of REL messages. Rx REL while waiting for RLC.%s\n", " ");
if (sngss7_test_ckt_flag(sngss7_info, FLAG_LOCAL_REL) &&
!sngss7_test_ckt_flag (sngss7_info, FLAG_REMOTE_REL)) {
/* locally requested hangup completed, wait for remote RLC */
@@ -1639,8 +1682,8 @@ ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_mutex_lock(ftdmchan->mutex);
/* check if the channel is blocked */
if (!(sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) {
SS7_WARN("Received UBL on circuit that is not blocked!\n");
if (!(sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) && !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) {
SS7_WARN("Received UBL on circuit that is not blocked! span= %d, chan= %d , flag = %x \n", g_ftdm_sngss7_data.cfg.isupCkt[circuit].span, g_ftdm_sngss7_data.cfg.isupCkt[circuit].chan,sngss7_info->blk_flags );
}
/* throw the unblock flag */
@@ -1648,6 +1691,8 @@ ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* clear the block flag */
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX_DN);
/* set the channel to suspended state */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
@@ -1688,14 +1733,6 @@ ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
DECODE_LCC_EVENT(evntType));
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* KONRAD FIX ME */
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}
@@ -1860,7 +1897,7 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* go to DOWN */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
} else {
SS7_ERROR("Received RSC-RLC but we're not waiting on a RSC-RLC on CIC #, dropping\n", sngss7_info->circuit->cic);
SS7_ERROR("Received RSC-RLC but we're not waiting on a RSC-RLC on CIC #%d, dropping\n", sngss7_info->circuit->cic);
}
break;
@@ -2449,6 +2486,8 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**********************************************************************/
case 0: /* maintenance oriented */
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN);
break;
/**********************************************************************/
case 1: /* hardware failure oriented */
@@ -486,47 +486,47 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint
g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic);
}
x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1;
x = (g_ftdm_sngss7_data.cfg.procId * MAX_CIC_MAP_LENGTH) + 1;
while ((g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) &&
(g_ftdm_sngss7_data.cfg.isupCkt[x].id < ((g_ftdm_sngss7_data.cfg.procId +1) * 1000))) {
/**********************************************************************/
(g_ftdm_sngss7_data.cfg.isupCkt[x].id < ((g_ftdm_sngss7_data.cfg.procId + 1) * MAX_CIC_MAP_LENGTH))) {
/**********************************************************************/
/* confirm this is a voice channel and not a gap/sig (no ftdmchan there) */
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != SNG_CKT_VOICE) goto move_along;
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) {
/* compare the intfIds */
if (g_ftdm_sngss7_data.cfg.isupCkt[x].infId == intfId) {
/* we have a match, setup the pointers to the correct values */
circuit = x;
/* compare the intfIds */
if (g_ftdm_sngss7_data.cfg.isupCkt[x].infId == intfId) {
/* we have a match, setup the pointers to the correct values */
circuit = x;
/* confirm that the circuit is active on our side otherwise move to the next circuit */
if (!sngss7_test_flag(&g_ftdm_sngss7_data.cfg.isupCkt[circuit], SNGSS7_ACTIVE)) {
SS7_DEBUG("[CIC:%d]Rx %s but circuit is not active yet, skipping!\n",
g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
DECODE_LCC_EVENT(evntType));
x++;
continue;
}
/* confirm that the circuit is active on our side otherwise move to the next circuit */
if (!sngss7_test_flag(&g_ftdm_sngss7_data.cfg.isupCkt[circuit], SNGSS7_ACTIVE)) {
SS7_DEBUG("[CIC:%d]Rx %s but circuit is not active yet, skipping!\n",
g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
DECODE_LCC_EVENT(evntType));
continue;
}
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return;
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
/* bounce out of the loop */
break;
}
}
/* bounce out of the loop */
break;
} /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].intfId == intfId) */
move_along:
/* move along ... nothing to see here */
x++;
/**********************************************************************/
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */
/**********************************************************************/
}
/* check if we found any circuits that are on the intfId, drop the message
* if none are found
*/
if (ftdmchan == NULL) goto sta_ind_end;
* if none are found */
if (!ftdmchan) {
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
break;
/**************************************************************************/
@@ -544,7 +544,6 @@ move_along:
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
break;
/**************************************************************************/
} /* switch (evntType) */
@@ -571,9 +570,6 @@ move_along:
/* enqueue this event */
ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event);
sta_ind_end:
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
}
/******************************************************************************/
@@ -31,6 +31,7 @@
* SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* INCLUDE ********************************************************************/
#include "ftmod_sangoma_ss7_main.h"
/******************************************************************************/
@@ -279,7 +280,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
}
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %d\n",
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
DECODE_DISC_REASON(sta->t.usta.evntParm[1]));
@@ -353,6 +354,8 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
char buf[50];
int x = 1;
SS7_RELAY_DBG_FUN(handle_sng_mtp3_alarm);
memset(buf, '\0', sizeof(buf));
switch (sta->hdr.elmId.elmnt) {
@@ -492,6 +495,8 @@ void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta)
char tmp[25];
char *p = NULL;
int x = 0;
SS7_RELAY_DBG_FUN(handle_sng_isup_alarm);
/* initalize the msg variable to NULLs */
memset(&msg[0], '\0', sizeof(&msg));
@@ -502,7 +507,6 @@ void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta)
return;
}
/* point p to the first spot in msg */
p = &msg[0];
@@ -742,6 +746,7 @@ void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta)
void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta)
{
SS7_RELAY_DBG_FUN(handle_sng_cc_alarm);
return;
} /* handle_cc_alarm */
@@ -749,6 +754,7 @@ void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta)
void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
{
SS7_RELAY_DBG_FUN(handle_sng_relay_alarm);
switch (sta->hdr.elmId.elmnt) {
/**************************************************************************/
@@ -60,6 +60,7 @@ static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span);
static ftdm_status_t ftdm_sangoma_ss7_start (ftdm_span_t * span);
/******************************************************************************/
/* STATE MAP ******************************************************************/
ftdm_state_map_t sangoma_ss7_state_map = {
{
@@ -281,7 +282,37 @@ ftdm_state_map_t sangoma_ss7_state_map = {
}
};
/******************************************************************************/
static void handle_hw_alarm(ftdm_event_t *e)
{
sngss7_chan_data_t *ss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
int x = 0;
ftdm_assert(e != NULL, "Null event!\n");
for (x = (g_ftdm_sngss7_data.cfg.procId * MAX_CIC_MAP_LENGTH) + 1; g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0; x++) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) {
ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
ftdmchan = ss7_info->ftdmchan;
if (e->channel->span_id == ftdmchan->physical_span_id &&
e->channel->chan_id == ftdmchan->physical_chan_id) {
if (e->enum_id == FTDM_OOB_ALARM_TRAP) {
sngss7_set_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX);
if (ftdmchan->state != FTDM_CHANNEL_STATE_SUSPENDED) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
}
} else {
sngss7_set_ckt_blk_flag(ss7_info, FLAG_GRP_HW_UNBLK_TX);
sngss7_clear_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX);
if (ftdmchan->state != FTDM_CHANNEL_STATE_SUSPENDED) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
}
}
}
}
}
}
/* MONITIOR THREADS ***********************************************************/
static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
@@ -293,6 +324,9 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
sngss7_event_data_t *sngss7_event = NULL;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
int b_alarm_test = 1;
sngss7_chan_data_t *ss7_info=NULL;
ftdm_log (FTDM_LOG_INFO, "ftmod_sangoma_ss7 monitor thread for span=%u started.\n", ftdmspan->span_id);
/* set IN_THREAD flag so that we know this thread is running */
@@ -311,6 +345,30 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
}
while (ftdm_running () && !(ftdm_test_flag (ftdmspan, FTDM_SPAN_STOP_THREAD))) {
int x = 0;
if (b_alarm_test) {
b_alarm_test = 0;
for (x = (g_ftdm_sngss7_data.cfg.procId * MAX_CIC_MAP_LENGTH) + 1;
g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0; x++) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) {
ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
ftdmchan = ss7_info->ftdmchan;
if (!ftdmchan) {
continue;
}
if (ftdmchan->alarm_flags != 0) { /* we'll send out block */
sngss7_set_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX );
} else { /* we'll send out reset */
sngss7_clear_ckt_blk_flag( ss7_info, FLAG_GRP_HW_BLOCK_TX );
sngss7_clear_ckt_blk_flag( ss7_info, FLAG_GRP_HW_BLOCK_TX_DN );
sngss7_set_ckt_blk_flag (ss7_info, FLAG_GRP_HW_UNBLK_TX);
}
}
usleep(50);
}
ftdmchan = NULL;
}
/* check the channel state queue for an event*/
switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, 2, 100))) {
@@ -388,7 +446,11 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
switch (ftdm_span_poll_event(ftdmspan, 0, NULL)) {
/**********************************************************************/
case FTDM_SUCCESS:
while (ftdm_span_next_event(ftdmspan, &event) == FTDM_SUCCESS);
while (ftdm_span_next_event(ftdmspan, &event) == FTDM_SUCCESS) {
if (event->e_type == FTDM_EVENT_OOB) {
handle_hw_alarm(event);
}
}
break;
/**********************************************************************/
case FTDM_TIMEOUT:
@@ -530,6 +592,11 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
i++;
}
/* kill t10 if active */
if (sngss7_info->t10.hb_timer_id) {
ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
}
/* check if the end of pulsing (ST) character has arrived or the right number of digits */
if (ftdmchan->caller_data.dnis.digits[i-1] == 'F') {
SS7_DEBUG_CHAN(ftdmchan, "Received the end of pulsing character %s\n", "");
@@ -551,7 +618,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
} else {
/* if we are coming from idle state then we have already been here once before */
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) {
SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
SS7_INFO_CHAN(ftdmchan, "Received %d out of %d so far: %s...starting T35\n",
i,
sngss7_info->circuit->min_digits,
ftdmchan->caller_data.dnis.digits);
@@ -566,7 +633,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
ftdmchan->caller_data.hangup_cause = 41;
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE;
/* set the flag to indicate this hangup is started from the local side */
sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL);
@@ -574,9 +641,29 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* end the call */
state_flag = 0;
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
} /* if (ftdm_sched_timer(sngss7_info->t35.sched, */
} /* if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) */
} /* checking ST/#digits */
}
}
/* start ISUP t10 */
if (ftdm_sched_timer (sngss7_info->t10.sched,
"t10",
sngss7_info->t10.beat,
sngss7_info->t10.callback,
&sngss7_info->t10,
&sngss7_info->t10.hb_timer_id)) {
SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE;
/* set the flag to indicate this hangup is started from the local side */
sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL);
/* end the call */
state_flag = 0;
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
}
}
break;
@@ -656,10 +743,14 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
/* inform the user there is media avai */
sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_PROGRESS_MEDIA);
} else {
if (!sngss7_test_ckt_flag(sngss7_info, FLAG_SENT_ACM)) {
sngss7_set_ckt_flag(sngss7_info, FLAG_SENT_ACM);
ft_to_sngss7_acm(ftdmchan);
}
ft_to_sngss7_cpg(ftdmchan);
}
/* nothing to do at this time */
break;
/**************************************************************************/
case FTDM_CHANNEL_STATE_UP: /*call is accpeted...both incoming and outgoing */
@@ -751,9 +842,18 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
if (sngss7_test_ckt_flag (sngss7_info, FLAG_REMOTE_REL)) {
/* check if this hangup is from a tx RSC */
if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX)) {
/* go to RESTART State until RSCa is received */
state_flag = 0;
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
if (!sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_SENT)) {
ft_to_sngss7_rsc (ftdmchan);
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_SENT);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
} else if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP)) {
state_flag = 0;
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
} else {
/* go to RESTART State until RSCa is received */
state_flag = 0;
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
} else {
/* if the hangup is from a rx RSC, rx GRS, or glare don't sent RLC */
if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_RX)) &&
@@ -844,7 +944,9 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* check if we came from reset (aka we just processed a reset) */
if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) ||
(ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED)) {
(ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) ||
(ftdmchan->last_state == FTDM_CHANNEL_STATE_HANGUP_COMPLETE)) {
/* check if reset flags are up indicating there is more processing to do yet */
if (!(sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX)) &&
@@ -949,9 +1051,12 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
if ((sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX)) &&
!(sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_SENT))) {
/* send a reset request */
ft_to_sngss7_rsc (ftdmchan);
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_SENT);
/* don't send out reset before finished hanging up if I'm in-use. */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
/* send a reset request */
ft_to_sngss7_rsc (ftdmchan);
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_SENT);
}
} /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX)) */
@@ -1102,16 +1207,97 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* clear the unblock flag */
sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX);
/* bring the sig status up */
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP);
/* not bring the cic up if there is a hardware block */
if( !sngss7_test_ckt_blk_flag(sngss7_info, (FLAG_GRP_HW_BLOCK_TX | FLAG_GRP_HW_BLOCK_TX_DN) ) ) {
/* bring the sig status up */
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP);
/* send a uba */
ft_to_sngss7_uba (ftdmchan);
/* send a uba */
ft_to_sngss7_uba (ftdmchan);
}
/* check the last state and return to it to allow the call to finish */
goto suspend_goto_last;
}
/**********************************************************************/
/* hardware block/unblock tx */
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_GRP_HW_BLOCK_TX ) &&
!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX_DN )) {
SS7_DEBUG_CHAN(ftdmchan, "Processing FLAG_GRP_HW_BLOCK_TX flag %s\n", "");
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN);
/* dont send block again if the channel is already blocked by maintenance */
if( !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX) &&
!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX_DN)
) {
ft_to_sngss7_blo(ftdmchan);
}
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX_DN);
goto suspend_goto_last;
}
if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_UNBLK_TX)) {
SS7_DEBUG_CHAN(ftdmchan, "Processing FLAG_GRP_HW_UNBLK_TX flag %s\n", "");
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX_DN);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_UNBLK_TX);
/* do not set the channel up if it's blocked by blo/cgb command OR blocked by receiving blo/cgb */
if (!sngss7_test_ckt_blk_flag(sngss7_info, ( FLAG_CKT_MN_BLOCK_TX
| FLAG_CKT_MN_BLOCK_TX
| FLAG_GRP_MN_BLOCK_TX
| FLAG_GRP_MN_BLOCK_TX_DN
| FLAG_CKT_MN_BLOCK_RX
| FLAG_CKT_MN_BLOCK_RX_DN
| FLAG_GRP_MN_BLOCK_RX
| FLAG_GRP_MN_BLOCK_RX_DN
)
)
) {
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP);
ft_to_sngss7_ubl(ftdmchan);
}
goto suspend_goto_last;
}
#if 0
//jz: there is no such thing of "remote hw block". for receiver, there are only block and unblock
/**********************************************************************/
// jz: hardware block/unblock rx
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_GRP_HW_BLOCK_RX ) &&
!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX_DN )) {
SS7_DEBUG_CHAN(ftdmchan, "Processing FLAG_GRP_HW_BLOCK_RX flag %s\n", "");
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN);
ft_to_sngss7_bla(ftdmchan);
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX_DN);
goto suspend_goto_last;
}
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_GRP_HW_UNBLK_RX )){
SS7_DEBUG_CHAN(ftdmchan, "Processing FLAG_GRP_HW_UNBLK_RX flag %s\n", "");
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX_DN);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_UNBLK_RX);
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP);
ft_to_sngss7_uba(ftdmchan);
goto suspend_goto_last;
}
#endif
/**********************************************************************/
if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX) &&
!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX_DN)) {
@@ -1142,11 +1328,14 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* clear the unblock flag */
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_TX);
/* bring the sig status up */
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP);
/* not bring the cic up if there is a hardware block */
if (!sngss7_test_ckt_blk_flag(sngss7_info, (FLAG_GRP_HW_BLOCK_TX | FLAG_GRP_HW_BLOCK_TX_DN))) {
/* bring the sig status up */
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP);
/* send a ubl */
ft_to_sngss7_ubl (ftdmchan);
/* send a ubl */
ft_to_sngss7_ubl(ftdmchan);
}
/* check the last state and return to it to allow the call to finish */
goto suspend_goto_last;
@@ -1624,32 +1813,37 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_ss7_unload)
ftdm_log (FTDM_LOG_INFO, "Starting ftmod_sangoma_ss7 unload...\n");
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC_STARTED)) {
sng_isup_free_cc();
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC);
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC_STARTED);
}
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED)) {
ftmod_ss7_shutdown_isup();
sng_isup_free_isup();
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP);
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED);
}
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3_STARTED)) {
ftmod_ss7_shutdown_mtp3();
sng_isup_free_mtp3();
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3);
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3_STARTED);
}
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_STARTED)) {
ftmod_ss7_shutdown_mtp2();
sng_isup_free_mtp2();
sng_isup_free_mtp1();
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2);
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_STARTED);
}
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY)) {
/* go through all the relays channels and configure it */
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP1_STARTED)) {
sng_isup_free_mtp1();
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP1_STARTED);
}
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY_STARTED)) {
/* go through all the relays channels and disable them */
x = 1;
while (x < (MAX_RELAY_CHANNELS)) {
/* check if this relay channel has been configured already */
@@ -1658,24 +1852,28 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_ss7_unload)
/* send the specific configuration */
if (ftmod_ss7_disable_relay_channel(x)) {
SS7_CRITICAL("Relay Channel %d disable failed!\n", x);
return 1;
/* jz: dont leave like this
* return 1;
* */
} else {
SS7_INFO("Relay Channel %d disable DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.relay[x].flags &= !SNGSS7_CONFIGURED;
g_ftdm_sngss7_data.cfg.relay[x].flags &= ~(SNGSS7_CONFIGURED);
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_RELAY_CHANNELS)) */
ftmod_ss7_shutdown_relay();
sng_isup_free_relay();
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY);
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY_STARTED);
}
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SM)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SM_STARTED)) {
sng_isup_free_sm();
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SM_STARTED);
}
sng_isup_free_gen();
@@ -51,7 +51,7 @@
/* DEFINES ********************************************************************/
#define MAX_NAME_LEN 25
#define MAX_PATH 255
#define MAX_PATH 4096
#define MAX_CIC_LENGTH 5
#define MAX_CIC_MAP_LENGTH 1000
@@ -64,12 +64,10 @@
(switchtype == LSI_SW_ANS92) || \
(switchtype == LSI_SW_ANS95)
typedef struct ftdm2trillium
{
typedef struct ftdm2trillium {
uint8_t ftdm_val;
uint8_t trillium_val;
}ftdm2trillium_t;
} ftdm2trillium_t;
typedef enum {
SNGSS7_CON_IND_EVENT = 0,
@@ -290,7 +288,6 @@ typedef struct sng_isup_intf {
uint32_t ssf;
uint32_t isap;
uint16_t t4;
uint32_t t10;
uint32_t t11;
uint32_t t18;
uint32_t t19;
@@ -346,6 +343,7 @@ typedef struct sng_isup_ckt {
uint8_t transparent_iam;
void *obj;
uint16_t t3;
uint32_t t10;
uint16_t t12;
uint16_t t13;
uint16_t t14;
@@ -473,6 +471,7 @@ typedef struct sngss7_chan_data {
void *raw_data; /* send on next sigevent */
sngss7_glare_data_t glare;
sngss7_timer_data_t t35;
sngss7_timer_data_t t10;
sngss7_group_data_t rx_grs;
sngss7_group_data_t rx_gra;
sngss7_group_data_t tx_grs;
@@ -609,22 +608,20 @@ typedef enum {
"TX CKT BLK DN", \
"TX CKT UNBLK", \
"TX CKT UNBLK DN", \
"RX GRP MN BLK", \
"RX GRP MN BLK DN", \
"RX GRP MN UNBLK", \
"RX GRP MN UNBLK DN", \
"TX GRP MN BLK", \
"TX GRP MN BLK DN", \
"TX GRP MN UNBLK", \
"TX GRP MN UNBLK DN", \
"RX GRP HW BLK", \
"RX GRP HW BLK DN", \
"RX GRP HW UNBLK", \
"RX GRP HW UNBLK DN", \
"TX GRP HW BLK", \
"TX GRP HW BLK DN", \
"RX GRP MN BLK", \
"RX GRP MN BLK DN", \
"TX GRP MN BLK", \
"TX GRP MN BLK DN", \
"TX GRP HW UNBLK", \
"TX GRP HW UNBLK DN"
"TX GRP HW UNBLK DN", \
"TX GRP MN UNBLK", \
"TX GRP MN UNBLK DN", \
"RX GRP HW UNBLK", \
"RX GRP HW UNBLK DN"
FTDM_STR2ENUM_P(ftmod_ss7_blk_state2flag, ftmod_ss7_blk_flag2str, sng_ckt_block_flag_t)
/* valid for every cfg array except circuits */
@@ -636,13 +633,25 @@ typedef enum {
} sng_cfg_flag_t;
typedef enum {
SNGSS7_SM = (1 << 0),
SNGSS7_RY = (1 << 1),
SNGSS7_MTP1 = (1 << 2),
SNGSS7_MTP2 = (1 << 3),
SNGSS7_MTP3 = (1 << 4),
SNGSS7_ISUP = (1 << 5),
SNGSS7_CC = (1 << 6)
SNGSS7_SM_STARTED = (1 << 0),
SNGSS7_RY_PRESENT = (1 << 2),
SNGSS7_RY_STARTED = (1 << 3),
SNGSS7_MTP1_PRESENT = (1 << 4),
SNGSS7_MTP1_STARTED = (1 << 5),
SNGSS7_MTP2_PRESENT = (1 << 6),
SNGSS7_MTP2_STARTED = (1 << 7),
SNGSS7_MTP3_PRESENT = (1 << 8),
SNGSS7_MTP3_STARTED = (1 << 9),
SNGSS7_ISUP_PRESENT = (1 << 10),
SNGSS7_ISUP_STARTED = (1 << 11),
SNGSS7_CC_PRESENT = (1 << 12),
SNGSS7_CC_STARTED = (1 << 13),
} sng_task_flag_t;
/******************************************************************************/
@@ -739,6 +748,7 @@ int ftmod_ss7_isup_ckt_sta(uint32_t id, unsigned char *state);
/* in ftmod_sangoma_ss7_out.c */
void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_acm(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_cpg (ftdm_channel_t *ftdmchan);
void ft_to_sngss7_anm(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_rel(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_rlc(ftdm_channel_t *ftdmchan);
@@ -878,6 +888,7 @@ ftdm_status_t sngss7_add_raw_data(sngss7_chan_data_t *sngss7_info, uint8_t* data
/* in ftmod_sangoma_ss7_timers.c */
void handle_isup_t35(void *userdata);
void handle_isup_t10(void *userdata);
/******************************************************************************/
@@ -1029,13 +1040,12 @@ if (ftdmchan->state == new_state) { \
#define sngss7_set_options(obj, option) ((obj)->options |= (option))
#ifdef SS7_PRODUCTION
# define SS7_ASSERT \
SS7_INFO_CHAN(ftdmchan,"Production Mode, continuing%s\n", "");
#ifdef SMG_RELAY_DBG
#define SS7_RELAY_DBG(a,...) printf(a"\n", ##__VA_ARGS__)
#define SS7_RELAY_DBG_FUN(a) printf(#a"\n")
#else
# define SS7_ASSERT \
SS7_ERROR_CHAN(ftdmchan, "Debugging Mode, ending%s\n", ""); \
*(int*)0=0;
#define SS7_RELAY_DBG(a, ...)
#define SS7_RELAY_DBG_FUN(a)
#endif
/******************************************************************************/
@@ -36,6 +36,8 @@
/******************************************************************************/
/* DEFINES ********************************************************************/
#define SNGSS7_EVNTINFO_IND_INBAND_AVAIL 0x03
/******************************************************************************/
/* GLOBALS ********************************************************************/
@@ -171,6 +173,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
acm.optBckCalInd.simpleSegmInd.pres = PRSNT_DEF;
acm.optBckCalInd.mlppUserInd.pres = PRSNT_DEF;
acm.optBckCalInd.usrNetIneractInd.pres = PRSNT_DEF;
acm.optBckCalInd.netExcDelInd.pres = PRSNT_DEF;
} /* if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) */
/* send the ACM request to LibSngSS7 */
@@ -187,6 +190,31 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
return;
}
void ft_to_sngss7_cpg (ftdm_channel_t *ftdmchan)
{
SiCnStEvnt cpg;
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
memset (&cpg, 0, sizeof (cpg));
cpg.evntInfo.eh.pres = PRSNT_NODEF;
cpg.evntInfo.evntInd.pres = PRSNT_NODEF;
cpg.evntInfo.evntInd.val = SNGSS7_EVNTINFO_IND_INBAND_AVAIL; /* Event Indicator = In-band info is now available */
cpg.evntInfo.evntPresResInd.pres = PRSNT_NODEF;
cpg.evntInfo.evntPresResInd.val = 0; /* Event presentation restricted indicator = no indication */
/* send the CPG request to LibSngSS7 */
sng_cc_con_status (1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &cpg, PROGRESS);
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "[CIC:%d]Tx CPG\n", sngss7_info->circuit->cic);
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
}
void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
@@ -49,7 +49,7 @@ ftdm_status_t handle_relay_disconnect(RyMngmt *sta);
static ftdm_status_t reconfig_all_ckts_for_relay(void);
static ftdm_status_t disable_all_ckts_for_relay(void);
static ftdm_status_t block_all_ckts_for_relay(uint32_t procId);
static ftdm_status_t unblock_all_ckts_for_relay(uint32_t procId);
/* static ftdm_status_t unblock_all_ckts_for_relay(uint32_t procId); */
static ftdm_status_t disable_all_sigs_for_relay(uint32_t procId);
static ftdm_status_t disble_all_mtp2_sigs_for_relay(void);
/******************************************************************************/
@@ -59,43 +59,26 @@ ftdm_status_t handle_relay_connect(RyMngmt *sta)
{
sng_relay_t *sng_relay = &g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id];
/* test if this is the first time the channel comes up */
if (!sngss7_test_flag(sng_relay, SNGSS7_RELAY_INIT)) {
SS7_INFO("Relay Channel %d initial connection UP\n", sng_relay->id);
/* mark the channel as being up */
/* SS7_INFO("Relay Channel %d initial connection UP\n", sng_relay->id); */
sngss7_set_flag(sng_relay, SNGSS7_RELAY_INIT);
} else {
SS7_INFO("Relay Channel %d connection UP\n", sng_relay->id);
/* react based on type of channel */
switch (sng_relay->type) {
/******************************************************************/
case (LRY_CT_TCP_CLIENT):
/* reconfigure all ISUP ckts, since the main system would have lost all configs */
}
SS7_INFO("Relay Channel %d connection UP\n", sng_relay->id);
if (sng_relay->type == LRY_CT_TCP_CLIENT) {
if (!sngss7_test_flag(sng_relay, SNGSS7_RELAY_INIT)) {
if (reconfig_all_ckts_for_relay()) {
SS7_ERROR("Failed to reconfigure ISUP Ckts!\n");
/* we're done....this is very bad! */
}
break;
/******************************************************************/
case (LRY_CT_TCP_SERVER):
/* bring the sig links on the client system back up */
ftmod_ss7_enable_grp_mtp3Link(sta->t.usta.s.ryUpUsta.id);
/* unbloock the ckts on the client system */
unblock_all_ckts_for_relay(sta->t.usta.s.ryUpUsta.id);
break;
/******************************************************************/
default:
break;
/******************************************************************/
} /* switch (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id].type) */
} /* intial up? */
return FTDM_SUCCESS;
}
return FTDM_SUCCESS;
} else if (sng_relay->type == LRY_CT_TCP_SERVER) {
ftmod_ss7_enable_grp_mtp3Link(sta->t.usta.s.ryUpUsta.id);
/* unbloock the ckts on the client system */
return FTDM_SUCCESS;
}
return FTDM_FAIL;
}
/******************************************************************************/
@@ -300,7 +283,7 @@ ftdm_status_t disable_all_sigs_for_relay(uint32_t procId)
ftdm_status_t disble_all_mtp2_sigs_for_relay(void)
{
/* check if there is a local mtp2 link*/
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_STARTED)) {
SS7_INFO("Disalbing all mtp2 sig links on local system\n");
ftmod_ss7_disable_grp_mtp2Link(1);
@@ -310,6 +293,7 @@ ftdm_status_t disble_all_mtp2_sigs_for_relay(void)
}
#if 0
/******************************************************************************/
static ftdm_status_t unblock_all_ckts_for_relay(uint32_t procId)
{
@@ -345,6 +329,7 @@ static ftdm_status_t unblock_all_ckts_for_relay(uint32_t procId)
return FTDM_SUCCESS;
}
#endif
/******************************************************************************/
/* For Emacs:
@@ -319,7 +319,7 @@ ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb
if (genNmb->nmbQual.pres == PRSNT_NODEF) {
snprintf(val, sizeof(val), "%d", genNmb->nmbQual.val);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"number qualifier\" \n", val);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"number qualifier\" \"%s\"\n", val);
sngss7_add_var(sngss7_info, "ss7_gn_numqual", val);
}
@@ -2454,7 +2454,7 @@ ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt)
goto done;
}
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%d\n", len);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%lu\n", len);
/* Worst case: size will triple after url encode */
url_encoded_iam = ftdm_malloc(3*sizeof(*siConEvnt));
@@ -2468,10 +2468,10 @@ ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt)
/* URL encode buffer to that its safe to store it in a string */
ftdm_url_encode((const char*)compressed_iam, url_encoded_iam, len);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%d\n", strlen(url_encoded_iam));
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%"FTDM_SIZE_FMT"\n", strlen(url_encoded_iam));
if (strlen(url_encoded_iam) > g_ftdm_sngss7_data.cfg.transparent_iam_max_size) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "IAM variable length exceeds max size (len:%d max:%d) \n", strlen(url_encoded_iam), g_ftdm_sngss7_data.cfg.transparent_iam_max_size);
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "IAM variable length exceeds max size (len:%"FTDM_SIZE_FMT" max:%d) \n", strlen(url_encoded_iam), g_ftdm_sngss7_data.cfg.transparent_iam_max_size);
ret_val = FTDM_FAIL;
goto done;
}
@@ -2505,10 +2505,10 @@ ftdm_status_t sngss7_retrieve_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt
url_encoded_iam = ftdm_strdup(val);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%d\n", strlen(val));
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%"FTDM_SIZE_FMT"\n", strlen(val));
ftdm_url_decode(url_encoded_iam, &url_encoded_iam_len);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%d\n", url_encoded_iam_len);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%"FTDM_SIZE_FMT"\n", url_encoded_iam_len);
uncompressed_buffer = ftdm_malloc(sizeof(*siConEvnt));
ftdm_assert_return(uncompressed_buffer, FTDM_FAIL, "Failed to allocate buffer for uncompressed buffer\n");
@@ -2520,7 +2520,7 @@ ftdm_status_t sngss7_retrieve_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt
}
if (len != sizeof(*siConEvnt)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Incompatible IAM structure size (expected:%d size:%d)\n", sizeof(*siConEvnt), strlen(uncompressed_buffer));
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Incompatible IAM structure size (expected:%"FTDM_SIZE_FMT" size:%"FTDM_SIZE_FMT")\n", sizeof(*siConEvnt), strlen(uncompressed_buffer));
goto done;
}
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2009, Konrad Hammel <konrad@sangoma.com>
* Copyright (c) 2009, Sangoma Technologies
* Konrad Hammel <konrad@sangoma.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,6 +30,11 @@
* 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.
*
* Contributors:
*
* Moises Silva <moy@sangoma.com>
*
*/
/* INCLUDE ********************************************************************/
@@ -56,25 +62,53 @@ void handle_isup_t35(void *userdata)
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
/* now that we have the right channel...put a lock on it so no-one else can use it */
ftdm_mutex_lock(ftdmchan->mutex);
ftdm_channel_lock(ftdmchan);
/* Q.764 2.2.5 Address incomplete (T35 expiry action is hangup with cause 28 according to Table A.1/Q.764) */
SS7_ERROR("[Call-Control] Timer 35 expired on CIC = %d\n", sngss7_info->circuit->cic);
/* set the flag to indicate this hangup is started from the local side */
sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL);
/* hang up on timer expiry */
ftdmchan->caller_data.hangup_cause = 28;
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_INVALID_NUMBER_FORMAT;
/* end the call */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
/* kill t10 if active */
if (sngss7_info->t10.hb_timer_id) {
ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
}
/*unlock*/
ftdm_mutex_unlock(ftdmchan->mutex);
ftdm_channel_unlock(ftdmchan);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
void handle_isup_t10(void *userdata)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_timer_data_t *timer = userdata;
sngss7_chan_data_t *sngss7_info = timer->sngss7_info;
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
ftdm_channel_lock(ftdmchan);
SS7_DEBUG("[Call-Control] Timer 10 expired on CIC = %d\n", sngss7_info->circuit->cic);
/* send the call to the user */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
ftdm_channel_unlock(ftdmchan);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
}
/******************************************************************************/
/* For Emacs:
* Local Variables:
@@ -62,6 +62,7 @@ sng_switch_type_t sng_switch_type_map[] =
{ 1, "india" , LSI_SW_INDIA , LSI_SW_INDIA },
{ 1, "uk" , LSI_SW_UK , LSI_SW_UK },
{ 1, "russia" , LSI_SW_RUSSIA , LSI_SW_RUSSIA },
{ 1, "china" , LSI_SW_CHINA , LSI_SW_CHINA },
{ 0, "", 0, 0 },
};
@@ -127,6 +128,7 @@ typedef struct sng_ccSpan
uint8_t itx_auto_reply;
uint8_t transparent_iam;
uint32_t t3;
uint32_t t10;
uint32_t t12;
uint32_t t13;
uint32_t t14;
@@ -1570,11 +1572,6 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
sng_isap.t9 = atoi(parm->val);
SS7_DEBUG("Found isup t9 = %d\n",sng_isap.t9);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t10")) {
/**********************************************************************/
sng_isup.t10 = atoi(parm->val);
SS7_DEBUG("Found isup t10 = %d\n",sng_isup.t10);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t11")) {
/**********************************************************************/
sng_isup.t11 = atoi(parm->val);
@@ -1965,6 +1962,10 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
/**********************************************************************/
sng_ccSpan.t3 = atoi(parm->val);
SS7_DEBUG("Found isup t3 = %d\n", sng_ccSpan.t3);
} else if (!strcasecmp(parm->var, "isup.t10")) {
/**********************************************************************/
sng_ccSpan.t10 = atoi(parm->val);
SS7_DEBUG("Found isup t10 = %d\n", sng_ccSpan.t10);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t12")) {
/**********************************************************************/
@@ -2082,7 +2083,7 @@ static int ftmod_ss7_fill_in_relay_channel(sng_relay_t *relay_channel)
relay_channel->port,
relay_channel->procId,
relay_channel->id);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY_PRESENT);
} else {
relay_channel->id = i;
SS7_DEBUG("found existing relay channel on type:%d, hostname:%s, port:%d, procId:%d, id = %d\n",
@@ -2116,7 +2117,7 @@ static int ftmod_ss7_fill_in_mtp1_link(sng_mtp1_link_t *mtp1Link)
/* check if this id value has been used already */
if (g_ftdm_sngss7_data.cfg.mtp1Link[i].id == 0) {
SS7_DEBUG("Found new MTP1 Link: id=%d, name=%s\n", mtp1Link->id, mtp1Link->name);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP1);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP1_PRESENT);
} else {
SS7_DEBUG("Found an existing MTP1 Link: id=%d, name=%s (old name=%s)\n",
mtp1Link->id,
@@ -2142,7 +2143,7 @@ static int ftmod_ss7_fill_in_mtp2_link(sng_mtp2_link_t *mtp2Link)
/* check if this id value has been used already */
if (g_ftdm_sngss7_data.cfg.mtp2Link[i].id == 0) {
SS7_DEBUG("Found new MTP2 Link: id=%d, name=%s\n", mtp2Link->id, mtp2Link->name);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_PRESENT);
} else {
SS7_DEBUG("Found an existing MTP2 Link: id=%d, name=%s (old name=%s)\n",
mtp2Link->id,
@@ -2219,7 +2220,7 @@ static int ftmod_ss7_fill_in_mtp3_link(sng_mtp3_link_t *mtp3Link)
/* check if this id value has been used already */
if (g_ftdm_sngss7_data.cfg.mtp3Link[i].id == 0) {
SS7_DEBUG("Found new MTP3 Link: id=%d, name=%s\n", mtp3Link->id, mtp3Link->name);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3_PRESENT);
} else {
SS7_DEBUG("Found an existing MTP3 Link: id=%d, name=%s (old name=%s)\n",
mtp3Link->id,
@@ -2560,7 +2561,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
/* check if this id value has been used already */
if (g_ftdm_sngss7_data.cfg.isupIntf[i].id == 0) {
SS7_DEBUG("Found new ISUP Interface: id=%d, name=%s\n", sng_isup->id, sng_isup->name);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_PRESENT);
} else {
SS7_DEBUG("Found an existing ISUP Interface: id=%d, name=%s (old name=%s)\n",
sng_isup->id,
@@ -2584,11 +2585,6 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
} else {
g_ftdm_sngss7_data.cfg.isupIntf[i].t4 = 3000;
}
if (sng_isup->t10 != 0) {
g_ftdm_sngss7_data.cfg.isupIntf[i].t10 = sng_isup->t10;
} else {
g_ftdm_sngss7_data.cfg.isupIntf[i].t10 = 50;
}
if (sng_isup->t11 != 0) {
g_ftdm_sngss7_data.cfg.isupIntf[i].t11 = sng_isup->t11;
} else {
@@ -2908,7 +2904,7 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
g_ftdm_sngss7_data.cfg.isupCkt[x].type = SNG_CKT_VOICE;
/* throw the flag to indicate that we need to start call control */
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC);
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC_PRESENT);
}
if (timeslot.channel) {
@@ -2935,6 +2931,11 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = ccSpan->t3;
}
if (ccSpan->t10 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t10 = 50;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t10 = ccSpan->t10;
}
if (ccSpan->t12 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300;
} else {
@@ -2966,9 +2967,10 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = ccSpan->t17;
}
if (ccSpan->t35 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 170;
/* Q.764 2.2.5 Address incomplete (T35 is 15-20 seconds according to Table A.1/Q.764) */
g_ftdm_sngss7_data.cfg.isupCkt[x].t35 = 170;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = ccSpan->t35;
g_ftdm_sngss7_data.cfg.isupCkt[x].t35 = ccSpan->t35;
}
if (ccSpan->tval == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10;
@@ -3062,12 +3064,18 @@ static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan)
ftdmchan->call_data = ss7_info;
/* prepare the timer structures */
ss7_info->t35.sched = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched;
ss7_info->t35.sched = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched;
ss7_info->t35.counter = 1;
ss7_info->t35.beat = (isupCkt->t35) * 100; /* beat is in ms, t35 is in 100ms */
ss7_info->t35.beat = (isupCkt->t35) * 100; /* beat is in ms, t35 is in 100ms */
ss7_info->t35.callback = handle_isup_t35;
ss7_info->t35.sngss7_info = ss7_info;
ss7_info->t10.sched = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched;
ss7_info->t10.counter = 1;
ss7_info->t10.beat = (isupCkt->t10) * 100; /* beat is in ms, t10 is in 100ms */
ss7_info->t10.callback = handle_isup_t10;
ss7_info->t10.sngss7_info = ss7_info;
/**************************************************************************/
} /* for (i == 1; i < ftdmspan->chan_count; i++) */
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+45 -19
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,9 +36,9 @@
* David Yat Sin <davidy@sangoma.com>
* Nenad Corbic <ncorbic@sangoma.com>
* Arnaldo Pereira <arnaldo@sangoma.com>
* Gideon Sadan <gsadan@sangoma.com>
*
*/
*/
#ifdef WP_DEBUG_IO
#define _BSD_SOURCE
#include <syscall.h>
@@ -121,6 +121,16 @@ FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event);
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event);
FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event);
static void wp_swap16(char *data, int datalen)
{
int i = 0;
uint16_t *samples = (uint16_t *)data;
for (i = 0; i < datalen/2; i++) {
uint16_t sample = ((samples[i] & 0x00FF) << 8) | ((samples[i] & 0xFF00) >> 8);
samples[i] = sample;
}
}
/**
* \brief Poll for event on a wanpipe socket
* \param fd Wanpipe socket descriptor
@@ -305,11 +315,20 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
err = sangoma_tdm_get_hw_coding(chan->sockfd, &tdm_api);
if (tdm_api.wp_tdm_cmd.hw_tdm_coding) {
chan->native_codec = chan->effective_codec = FTDM_CODEC_ALAW;
} else {
chan->native_codec = chan->effective_codec = FTDM_CODEC_ULAW;
}
if ((span->trunk_type == FTDM_TRUNK_GSM) && (chan->type == FTDM_CHAN_TYPE_B)) {
chan->native_codec = FTDM_CODEC_SLIN;
chan->native_interval = 20;
chan->packet_len = 320;
}
err = sangoma_tdm_get_hw_dtmf(chan->sockfd, &tdm_api);
if (err > 0) {
@@ -580,8 +599,9 @@ static FIO_OPEN_FUNCTION(wanpipe_open)
ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_INTERVAL);
ftdmchan->effective_interval = ftdmchan->native_interval = wp_globals.codec_ms;
ftdmchan->packet_len = ftdmchan->native_interval * 8;
/* The packet len will depend on the codec and interval */
ftdmchan->packet_len = ftdmchan->native_interval * ((ftdmchan->native_codec==FTDM_CODEC_SLIN) ? 16 : 8);
if (wp_globals.txqueue_size > 0) {
ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &wp_globals.txqueue_size);
}
@@ -772,6 +792,7 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
case FTDM_COMMAND_SET_INTERVAL:
{
err=sangoma_tdm_set_usr_period(ftdmchan->sockfd, &tdm_api, FTDM_COMMAND_OBJ_INT);
ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8);
}
break;
@@ -793,7 +814,7 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
FTDM_COMMAND_OBJ_INT = wanpipe_swap_bits(rbsbits);
}
#else
// does sangoma_tdm_read_rbs is available here?
/* is sangoma_tdm_read_rbs available here? */
FTDM_COMMAND_OBJ_INT = ftdmchan->rx_cas_bits;
#endif
}
@@ -885,17 +906,11 @@ static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *t
}
if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_tx_idle_packets) {
/* HDLC channels do not always transmit, so its ok for drivers to fill with idle
* also do not report idle warning when we just started transmitting */
if (ftdmchan->iostats.tx.packets && FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Tx idle changed from %d to %d\n",
ftdmchan->iostats.tx.idle_packets, tx_stats->wp_api_tx_hdr_tx_idle_packets);
}
ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets;
}
if (!ftdmchan->iostats.tx.packets) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "First packet write stats: Tx queue len: %d, Tx queue size: %d, Tx idle: %d\n",
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "First packet write stats: Tx queue len: %d, Tx queue size: %d, Tx idle: %"FTDM_UINT64_FMT"\n",
ftdmchan->iostats.tx.queue_len,
ftdmchan->iostats.tx.queue_size,
ftdmchan->iostats.tx.idle_packets);
@@ -941,11 +956,11 @@ static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx
}
if (ftdmchan->iostats.rx.queue_len >= (0.8 * ftdmchan->iostats.rx.queue_size)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue length exceeded 80% threshold (%d/%d)\n",
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue length exceeded 80%% threshold (%d/%d)\n",
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
} else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)){
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue length reduced 80% threshold (%d/%d)\n",
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue length reduced 80%% threshold (%d/%d)\n",
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
}
@@ -975,12 +990,15 @@ static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx
* \param datalen Size of data buffer
* \return Success, failure or timeout
*/
static FIO_READ_FUNCTION(wanpipe_read)
{
int rx_len = 0;
int rq_len = (int)*datalen;
wp_tdm_api_rx_hdr_t hdrframe;
#ifdef WP_DEBUG_IO
wp_channel_t *wchan = ftdmchan->io_data;
ftdm_time_t time_diff = 0;
@@ -1040,6 +1058,10 @@ static FIO_READ_FUNCTION(wanpipe_read)
wanpipe_read_stats(ftdmchan, &hdrframe);
}
if ((ftdmchan->type == FTDM_CHAN_TYPE_B) && (ftdmchan->span->trunk_type == FTDM_TRUNK_GSM)) {
wp_swap16(data, *datalen);
}
return FTDM_SUCCESS;
}
@@ -1056,6 +1078,10 @@ static FIO_WRITE_FUNCTION(wanpipe_write)
int err = 0;
wp_tdm_api_tx_hdr_t hdrframe;
if ((ftdmchan->type == FTDM_CHAN_TYPE_B) && (ftdmchan->span->trunk_type == FTDM_TRUNK_GSM)) {
wp_swap16(data, *datalen);
}
/* Do we even need the headerframe here? on windows, we don't even pass it to the driver */
memset(&hdrframe, 0, sizeof(hdrframe));
if (*datalen == 0) {
@@ -1490,10 +1516,10 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc
if (fchan->dtmfdetect.duration_ms) {
ftdm_time_t diff = ftdm_current_time_in_ms() - fchan->dtmfdetect.start_time;
if (diff > fchan->dtmfdetect.duration_ms) {
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c (duration:%d min:%d)\n", tmp_dtmf[0], diff, fchan->dtmfdetect.duration_ms);
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c (duration:%"FTDM_TIME_FMT" min:%d)\n", tmp_dtmf[0], diff, fchan->dtmfdetect.duration_ms);
ftdm_channel_queue_dtmf(fchan, tmp_dtmf);
} else {
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe DTMF: %c (duration:%d min:%d)\n", tmp_dtmf[0], diff, fchan->dtmfdetect.duration_ms);
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe DTMF: %c (duration:%"FTDM_TIME_FMT" min:%d)\n", tmp_dtmf[0], diff, fchan->dtmfdetect.duration_ms);
}
} else if (!fchan->dtmfdetect.trigger_on_start) {
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c\n", tmp_dtmf[0]);
@@ -1591,7 +1617,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_FLASH);
ftdm_set_flag_locked(span->channels[i], FTDM_CHANNEL_OFFHOOK);
event_id = FTDM_OOB_OFFHOOK;
ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "Diff since last event = %llums, delivering %s now\n", diff, ftdm_oob_event2str(event_id));
ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "Diff since last event = %"FTDM_TIME_FMT" ms, delivering %s now\n", diff, ftdm_oob_event2str(event_id));
goto event;
}
}
@@ -1610,7 +1636,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
sangoma_tdm_txsig_onhook(ftdmchan->sockfd,&tdm_api);
}
ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "Diff since last event = %llums, delivering %s now\n", diff, ftdm_oob_event2str(event_id));
ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "Diff since last event = %"FTDM_TIME_FMT" ms, delivering %s now\n", diff, ftdm_oob_event2str(event_id));
goto event;
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+100 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -62,6 +62,9 @@
/*! \brief Max number of groups */
#define FTDM_MAX_GROUPS_INTERFACE FTDM_MAX_SPANS_INTERFACE
/*! \brief Max number of key=value pairs to be sent as signaling stack parameters */
#define FTDM_MAX_SIG_PARAMETERS 30
#define FTDM_INVALID_INT_PARM 0xFF
/*! \brief Thread/Mutex OS abstraction API. */
@@ -201,10 +204,19 @@ FTDM_STR2ENUM_P(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t)
(fchan)->span->trunk_type == FTDM_TRUNK_BRI || \
(fchan)->span->trunk_type == FTDM_TRUNK_BRI_PTMP)
/*! \brief Test if a span is digital */
#define FTDM_SPAN_IS_DIGITAL(span) \
((span)->trunk_type == FTDM_TRUNK_E1 || \
(span)->trunk_type == FTDM_TRUNK_T1 || \
(span)->trunk_type == FTDM_TRUNK_J1 || \
(span)->trunk_type == FTDM_TRUNK_BRI || \
(span)->trunk_type == FTDM_TRUNK_BRI_PTMP)
/*! \brief Logging function prototype to be used for all FreeTDM logs
* you should use ftdm_global_set_logger to set your own logger
*/
typedef void (*ftdm_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...);
typedef void (*ftdm_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...) __ftdm_check_printf(5, 6);
/*! \brief Data queue operation functions
* you can use ftdm_global_set_queue_handler if you want to override the default implementation (not recommended)
@@ -343,6 +355,11 @@ typedef struct {
uint8_t plan;
} ftdm_number_t;
typedef struct {
char from[FTDM_MAX_NUMBER_STR_SZ];
char body[FTDM_MAX_NAME_STR_SZ];
} ftdm_sms_data_t;
/*! \brief Caller information */
typedef struct ftdm_caller_data {
char cid_date[8]; /*!< Caller ID date */
@@ -362,6 +379,7 @@ typedef struct ftdm_caller_data {
/* user information layer 1 protocol */
ftdm_user_layer1_prot_t bearer_layer1;
ftdm_calling_party_category_t cpc; /*!< Calling party category */
uint32_t call_reference;
ftdm_channel_t *fchan; /*!< FreeTDM channel associated (can be NULL) */
@@ -452,12 +470,13 @@ typedef enum {
FTDM_SIGEVENT_INDICATION_COMPLETED, /*!< Last requested indication was completed */
FTDM_SIGEVENT_DIALING, /*!< Outgoing call just started */
FTDM_SIGEVENT_TRANSFER_COMPLETED, /*!< Transfer request is completed */
FTDM_SIGEVENT_SMS,
FTDM_SIGEVENT_INVALID, /*!<Invalid */
} ftdm_signal_event_t;
#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "RINGING", "PROGRESS", \
"PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "FACILITY", \
"TRACE", "TRACE_RAW", "INDICATION_COMPLETED", "DIALING", "TRANSFER_COMPLETED", "INVALID"
"TRACE", "TRACE_RAW", "INDICATION_COMPLETED", "DIALING", "TRANSFER_COMPLETED", "SMS", "INVALID"
/*! \brief Move from string to ftdm_signal_event_t and viceversa */
FTDM_STR2ENUM_P(ftdm_str2ftdm_signal_event, ftdm_signal_event2str, ftdm_signal_event_t)
@@ -471,13 +490,26 @@ typedef enum {
FTDM_TRUNK_FXO,
FTDM_TRUNK_FXS,
FTDM_TRUNK_EM,
FTDM_TRUNK_GSM,
FTDM_TRUNK_NONE
} ftdm_trunk_type_t;
#define TRUNK_STRINGS "E1", "T1", "J1", "BRI", "BRI_PTMP", "FXO", "FXS", "EM", "NONE"
#define TRUNK_TYPE_STRINGS "E1", "T1", "J1", "BRI", "BRI_PTMP", "FXO", "FXS", "EM", "GSM", "NONE"
/*! \brief Move from string to ftdm_trunk_type_t and viceversa */
FTDM_STR2ENUM_P(ftdm_str2ftdm_trunk_type, ftdm_trunk_type2str, ftdm_trunk_type_t)
/*! \brief Span trunk modes */
typedef enum {
FTDM_TRUNK_MODE_CPE,
FTDM_TRUNK_MODE_NET,
FTDM_TRUNK_MODE_INVALID
} ftdm_trunk_mode_t;
#define TRUNK_MODE_STRINGS "CPE", "NET", "INVALID"
/*! \brief Move from string to ftdm_trunk_mode_t and viceversa */
FTDM_STR2ENUM_P(ftdm_str2ftdm_trunk_mode, ftdm_trunk_mode2str, ftdm_trunk_mode_t)
/*! \brief Basic channel configuration provided to ftdm_configure_span_channels */
typedef struct ftdm_channel_config {
char name[FTDM_MAX_NAME_STR_SZ];
@@ -621,14 +653,6 @@ typedef enum {
FTDM_CRASH_ON_ASSERT
} ftdm_crash_policy_t;
/*! \brief I/O waiting flags */
typedef enum {
FTDM_NO_FLAGS = 0,
FTDM_READ = (1 << 0),
FTDM_WRITE = (1 << 1),
FTDM_EVENTS = (1 << 2)
} ftdm_wait_flag_t;
/*! \brief Signaling configuration parameter for the stacks (variable=value pair) */
typedef struct ftdm_conf_parameter {
const char *var;
@@ -783,6 +807,8 @@ struct ftdm_memory_handler {
#define FIO_CONFIGURE_SPAN_SIGNALING_ARGS (ftdm_span_t *span, fio_signal_cb_t sig_cb, ftdm_conf_parameter_t *ftdm_parameters)
#define FIO_SIG_UNLOAD_ARGS (void)
#define FIO_API_ARGS (ftdm_stream_handle_t *stream, const char *data)
#define FIO_SPAN_START_ARGS (ftdm_span_t *span)
#define FIO_SPAN_STOP_ARGS (ftdm_span_t *span)
/*! \brief FreeTDM I/O layer interface function typedefs
* You don't need these unless your implementing an I/O interface module (most users don't) */
@@ -829,6 +855,8 @@ typedef ftdm_status_t (*fio_configure_span_signaling_t) FIO_CONFIGURE_SPAN_SIGNA
typedef ftdm_status_t (*fio_io_unload_t) FIO_IO_UNLOAD_ARGS ;
typedef ftdm_status_t (*fio_sig_unload_t) FIO_SIG_UNLOAD_ARGS ;
typedef ftdm_status_t (*fio_api_t) FIO_API_ARGS ;
typedef ftdm_status_t (*fio_span_start_t) FIO_SPAN_START_ARGS ;
typedef ftdm_status_t (*fio_span_stop_t) FIO_SPAN_STOP_ARGS ;
/*! \brief FreeTDM I/O layer interface function prototype wrapper macros
@@ -863,6 +891,8 @@ typedef ftdm_status_t (*fio_api_t) FIO_API_ARGS ;
#define FIO_IO_UNLOAD_FUNCTION(name) ftdm_status_t name FIO_IO_UNLOAD_ARGS
#define FIO_SIG_UNLOAD_FUNCTION(name) ftdm_status_t name FIO_SIG_UNLOAD_ARGS
#define FIO_API_FUNCTION(name) ftdm_status_t name FIO_API_ARGS
#define FIO_SPAN_START_FUNCTION(name) ftdm_status_t name FIO_SPAN_START_ARGS
#define FIO_SPAN_STOP_FUNCTION(name) ftdm_status_t name FIO_SPAN_STOP_ARGS
/*! \brief FreeTDM I/O layer function prototype wrapper macros
* You don't need these unless your implementing an I/O interface module (most users don't) */
@@ -883,6 +913,8 @@ struct ftdm_io_interface {
fio_span_next_event_t next_event; /*!< Retrieve an event from the span */
fio_channel_next_event_t channel_next_event; /*!< Retrieve an event from channel */
fio_api_t api; /*!< Execute a text command */
fio_span_start_t span_start; /*!< Start span I/O */
fio_span_stop_t span_stop; /*!< Stop span I/O */
};
/*! \brief FreeTDM supported I/O codecs */
@@ -1741,6 +1773,28 @@ FT_DECLARE(ftdm_trunk_type_t) ftdm_span_get_trunk_type(const ftdm_span_t *span);
/*! \brief For display debugging purposes you can display this string which describes the trunk type of a span */
FT_DECLARE(const char *) ftdm_span_get_trunk_type_str(const ftdm_span_t *span);
/*!
* Set the trunk mode for a span
* \note This must be called before configuring any channels within the span!
* \param[in] span The span
* \param[in] type The trunk mode
*/
FT_DECLARE(void) ftdm_span_set_trunk_mode(ftdm_span_t *span, ftdm_trunk_mode_t mode);
/*!
* Get the trunk mode for a span
* \param[in] span The span
* \return Span trunk mode
*/
FT_DECLARE(ftdm_trunk_mode_t) ftdm_span_get_trunk_mode(const ftdm_span_t *span);
/*!
* Get the trunk mode of a span in textual form
* \param[in] span The span
* \return Span mode name as a string
*/
FT_DECLARE(const char *) ftdm_span_get_trunk_mode_str(const ftdm_span_t *span);
/*!
* \brief Return the channel identified by the provided id
*
@@ -1811,6 +1865,40 @@ FT_DECLARE(void) ftdm_global_set_config_directory(const char *path);
/*! \brief Check if the FTDM library is initialized and running */
FT_DECLARE(ftdm_bool_t) ftdm_running(void);
/**
* Generate a stack trace and invoke a callback function for each entry
* \param[in] callback Callback function, that is invoked for each stack symbol
* \param[in] priv (User-)Private data passed to the callback
* \retval
* FTDM_SUCCESS On success
* FTDM_NOTIMPL Backtraces are not available
* FTDM_EINVAL Invalid arguments (callback was NULL)
*/
FT_DECLARE(ftdm_status_t) ftdm_backtrace_walk(void (* callback)(const int tid, const void *addr, const char *symbol, void *priv), void *priv);
/**
* Convenience function to print a backtrace for a span.
* \note The backtrace is generated with FTDM_LOG_DEBUG log level.
* \param[in] span Span object
* \retval
* FTDM_SUCCESS On success
* FTDM_NOTIMPL Backtraces are not available
* FTDM_EINVAL Invalid arguments (e.g. span was NULL)
*/
FT_DECLARE(ftdm_status_t) ftdm_backtrace_span(ftdm_span_t *span);
/**
* Convenience function to print a backtrace for a channel.
* \note The backtrace is generated with FTDM_LOG_DEBUG log level.
* \param[in] chan Channel object
* \retval
* FTDM_SUCCESS On success
* FTDM_NOTIMPL Backtraces are not available
* FTDM_EINVAL Invalid arguments (e.g. chan was NULL)
*/
FT_DECLARE(ftdm_status_t) ftdm_backtrace_chan(ftdm_channel_t *chan);
FT_DECLARE_DATA extern ftdm_logger_t ftdm_log;
/*! \brief Basic transcoding function prototype */
+50
View File
@@ -121,6 +121,36 @@ extern "C" {
#pragma comment(lib, "Winmm")
#endif
/*
* Compiler-specific format checking attributes
* use these on custom functions that use printf/scanf-style
* format strings (e.g. ftdm_log())
*/
#if defined(__GNUC__)
/**
* Enable compiler-specific printf()-style format and argument checks on a function
* @param fmtp Position of printf()-style format string parameter
* @param argp Position of variable argument list ("...") parameter
* @code
* void log(const int level, const char *fmt, ...) __ftdm_check_printf(2, 3);
* @endcode
*/
#define __ftdm_check_printf(fmtp, argp) __attribute__((format (printf, fmtp, argp)))
/**
* Enable compiler-specific scanf()-style format and argument checks on a function
* @param fmtp Position of scanf()-style format string parameter
* @param argp Position of variable argument list ("...") parameter
* @code
* void parse(struct foo *ctx, const char *fmt, ...) __ftdm_check_scanf(2, 3);
* @endcode
*/
#define __ftdm_check_scanf(fmtp, argp) __attribute__((format (scanf, fmtp, argp)))
#else
#define __ftdm_check_printf(fmtp, argp)
#define __ftdm_check_scanf(fmtp, argp)
#endif
#define FTDM_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) FT_DECLARE(_TYPE) _FUNC1 (const char *name); FT_DECLARE(const char *) _FUNC2 (_TYPE type);
#define FTDM_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \
FT_DECLARE(_TYPE) _FUNC1 (const char *name) \
@@ -160,6 +190,9 @@ typedef __int16 int16_t;
typedef __int8 int8_t;
#define FTDM_O_BINARY O_BINARY
#define FTDM_SIZE_FMT "Id"
#define FTDM_INT64_FMT "lld"
#define FTDM_UINT64_FMT "llu"
#define FTDM_XINT64_FMT "llx"
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
@@ -168,6 +201,15 @@ typedef __int8 int8_t;
#else /* __WINDOWS__ */
#define FTDM_O_BINARY 0
#define FTDM_SIZE_FMT "zd"
#if (defined(__SIZEOF_LONG__) && (__SIZEOF_LONG__ == 8)) || defined(__LP64__) || defined(__LLP64__)
#define FTDM_INT64_FMT "ld"
#define FTDM_UINT64_FMT "lu"
#define FTDM_XINT64_FMT "lx"
#else
#define FTDM_INT64_FMT "lld"
#define FTDM_UINT64_FMT "llu"
#define FTDM_XINT64_FMT "llx"
#endif
#define FTDM_INVALID_SOCKET -1
typedef int ftdm_socket_t;
#include <stdio.h>
@@ -203,6 +245,14 @@ typedef enum {
FTDM_TRUE
} ftdm_bool_t;
/*! \brief I/O waiting flags */
typedef enum {
FTDM_NO_FLAGS = 0,
FTDM_READ = (1 << 0),
FTDM_WRITE = (1 << 1),
FTDM_EVENTS = (1 << 2)
} ftdm_wait_flag_t;
/*!
* \brief FreeTDM channel.
* This is the basic data structure used to place calls and I/O operations
+51
View File
@@ -53,6 +53,8 @@ extern "C" {
/*! \brief time data type */
typedef uint64_t ftdm_time_t;
/*! format string for ftdm_time_t */
#define FTDM_TIME_FMT FTDM_UINT64_FMT
/*! \brief sleep x amount of milliseconds */
#ifdef __WINDOWS__
@@ -76,6 +78,55 @@ typedef uint64_t ftdm_time_t;
/*! \brief array len helper */
#define ftdm_array_len(array) sizeof(array)/sizeof(array[0])
/*! \brief Get smaller value */
#define ftdm_min(x,y) ((x) < (y) ? (x) : (y))
/*! \brief Get larger value */
#define ftdm_max(x,y) ((x) > (y) ? (x) : (y))
/*! \brief Get value that is in range [vmin,vmax] */
#define ftdm_clamp(val,vmin,vmax) ftdm_max(vmin,ftdm_min(val,vmax))
/*!
* \brief Get offset of member in structure
* \param[in] type Type of struct
* \param[in] member Name of struct member
* \code
* struct a {
* int foo;
* int bar;
* };
*
* int offset_a_bar = ftdm_offset_of(struct a, bar); // 4 byte offset
* \endcode
*/
#define ftdm_offset_of(type,member) (uintptr_t)&(((type *)0)->member)
/*!
* \brief Get pointer to enclosing structrure from pointer to embedded member
* \param[in] ptr Pointer to embedded member
* \param[in] type Type of parent/container structure
* \param[in] member Name of embedded member in parent/container struct
* \code
* struct engine {
* int nr_cyl;
* };
*
* struct car {
* char model[10];
* struct engine eng; // struct engine embedded in car(!)
* };
*
* int somefunc(struct engine *e) {
* struct car *c = ftdm_container_of(e, struct car, eng);
*
* ... do something with car ...
* }
* \endcode
*/
#define ftdm_container_of(ptr,type,member) (type *)((uintptr_t)(ptr) - ftdm_offset_of(type, member))
/*! \brief The memory handler.
Do not use directly this variable, use the memory macros and ftdm_global_set_memory_handler to override */
FT_DECLARE_DATA extern ftdm_memory_handler_t g_ftdm_mem_handler;
+2 -1
View File
@@ -52,11 +52,12 @@ FT_DECLARE(ftdm_status_t) _ftdm_mutex_trylock(const char *file, int line, const
#define ftdm_mutex_unlock(_x) _ftdm_mutex_unlock(__FILE__, __LINE__, __FUNCTION__, _x)
FT_DECLARE(ftdm_status_t) _ftdm_mutex_unlock(const char *file, int line, const char *func, ftdm_mutex_t *mutex);
FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **cond, ftdm_socket_t device);
FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **cond, ftdm_socket_t device, ftdm_wait_flag_t device_flags);
FT_DECLARE(ftdm_status_t) ftdm_interrupt_destroy(ftdm_interrupt_t **cond);
FT_DECLARE(ftdm_status_t) ftdm_interrupt_signal(ftdm_interrupt_t *cond);
FT_DECLARE(ftdm_status_t) ftdm_interrupt_wait(ftdm_interrupt_t *cond, int ms);
FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interrupts[], ftdm_size_t size, int ms);
FT_DECLARE(ftdm_wait_flag_t) ftdm_interrupt_device_ready(ftdm_interrupt_t *interrupt);
#ifdef __cplusplus
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
+25 -3
View File
@@ -214,12 +214,33 @@ extern "C" {
ftdm_mutex_lock(obj->mutex); \
} \
if(!__safety) { \
ftdm_log(FTDM_LOG_CRIT, "flag %d was never cleared\n", flag); \
ftdm_log(FTDM_LOG_CRIT, "flag %"FTDM_UINT64_FMT" was never cleared\n", (uint64_t)flag); \
} \
} while(0);
#define ftdm_is_dtmf(key) ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119)
#ifdef __linux__
#define ftdm_print_stack(level) \
do { \
void *__stacktrace[100] = { 0 }; \
char **__symbols = NULL; \
int __size = 0; \
int __i = 0; \
__size = backtrace(__stacktrace, ftdm_array_len(__stacktrace)); \
__symbols = backtrace_symbols(__stacktrace, __size); \
if (__symbols) { \
for (__i = 0; __i < __size; __i++) { \
ftdm_log(__level, "%s\n", __symbols[i]); \
} \
free(__symbols); \
} \
} while (0);
#else
#define ftdm_print_stack(level) ftdm_log(level, "FTDM_PRINT_STACK is not implemented in this operating system!\n");
#endif
#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP)
/*!
\brief Copy flags from one arbitrary object to another
@@ -464,6 +485,7 @@ struct ftdm_span {
fio_event_cb_t event_callback;
ftdm_mutex_t *mutex;
ftdm_trunk_type_t trunk_type;
ftdm_trunk_mode_t trunk_mode;
ftdm_analog_start_type_t start_type;
ftdm_signal_type_t signal_type;
uint32_t last_used_index;
@@ -673,7 +695,7 @@ FT_DECLARE(ftdm_status_t) ftdm_sigmsg_set_raw_data(ftdm_sigmsg_t *sigmsg, void *
*/
#define ftdm_assert(assertion, msg) \
if (!(assertion)) { \
ftdm_log(FTDM_LOG_CRIT, msg); \
ftdm_log(FTDM_LOG_CRIT, "%s", msg); \
if (g_ftdm_crash_policy & FTDM_CRASH_ON_ASSERT) { \
ftdm_abort(); \
} \
@@ -684,7 +706,7 @@ FT_DECLARE(ftdm_status_t) ftdm_sigmsg_set_raw_data(ftdm_sigmsg_t *sigmsg, void *
*/
#define ftdm_assert_return(assertion, retval, msg) \
if (!(assertion)) { \
ftdm_log(FTDM_LOG_CRIT, msg); \
ftdm_log(FTDM_LOG_CRIT, "%s", msg); \
if (g_ftdm_crash_policy & FTDM_CRASH_ON_ASSERT) { \
ftdm_abort(); \
} else { \
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -163,7 +163,8 @@ typedef enum {
FTDM_SIGTYPE_SANGOMABOOST,
FTDM_SIGTYPE_M3UA,
FTDM_SIGTYPE_R2,
FTDM_SIGTYPE_SS7
FTDM_SIGTYPE_SS7,
FTDM_SIGTYPE_GSM
} ftdm_signal_type_t;
typedef enum {
@@ -173,6 +174,12 @@ typedef enum {
FTDM_SPAN_SUSPENDED = (1 << 3),
FTDM_SPAN_IN_THREAD = (1 << 4),
FTDM_SPAN_STOP_THREAD = (1 << 5),
/*! Signaling modules set this flag to use fchan->pendingchans queue instead
* of the FTDM_SPAN_STATE_CHANGE flag to detect when there is channels with
* a state change pending in the span. If you set this member you can't rely
* on FTDM_SPAN_STATE_CHANGE anymore and must use the queue only instead. This
* is the new way of detecting state changes, new modules should always set this
* flag, the old modules still relying on FTDM_SPAN_STATE_CHANGE should be updated */
FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6),
FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7),
FTDM_SPAN_USE_AV_RATE = (1 << 8),
@@ -1,6 +1,6 @@
/*
* libteletone
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* libteletone
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* libteletone
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -4,7 +4,7 @@
* Author(s): Anthony Minessale II <anthm@freeswitch.org>
* Nenad Corbic <ncorbic@sangoma.com>
*
* Copyright: (c) 2005 Anthony Minessale II
* Copyright: (c) 2005-2012 Anthony Minessale II
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+1 -1
View File
@@ -4,7 +4,7 @@
* Author(s): Anthony Minessale II <anthm@freeswitch.org>
* Nenad Corbic <ncorbic@sangoma.com>
*
* Copyright: (c) 2005 Anthony Minessale II
* Copyright: (c) 2005-2012 Anthony Minessale II
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+1 -1
View File
@@ -4,7 +4,7 @@
* Author(s): Anthony Minessale II <anthm@freeswitch.org>
* Nenad Corbic <ncorbic@sangoma.com>
*
* Copyright: (c) 2005 Anthony Minessale II
* Copyright: (c) 2005-2012 Anthony Minessale II
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
+1 -1
View File
@@ -144,7 +144,7 @@ int main(int argc, char *argv[])
ftdm_channel_call_indicate(lchan, ind);
stop = ftdm_current_time_in_ms();
diff = stop - start;
ftdm_log(FTDM_LOG_DEBUG, "Setting indication %s took %llums\n",
ftdm_log(FTDM_LOG_DEBUG, "Setting indication %s took %"FTDM_TIME_FMT" ms\n",
ftdm_channel_indication2str(ind), diff);
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* libDingaLing XMPP Jingle Library
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
File diff suppressed because it is too large. Load diff
+90 -10
View File
@@ -1,6 +1,6 @@
/*
* libDingaLing XMPP Jingle Library
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -28,6 +28,7 @@
* libdingaling.h -- Main Header File
*
*/
/*! \file libdingaling.h
\brief Main Header File
*/
@@ -60,12 +61,18 @@ extern "C" {
#endif
#define LDL_HANDLE_QLEN 2000
#define LDL_MAX_CANDIDATES 10
#define LDL_MAX_CANDIDATES 25
#define LDL_MAX_PAYLOADS 50
#define LDL_RETRY 3
#define IKS_NS_COMPONENT "jabber:component:accept"
/* period between keep alive signals in 1sec units*/
#define LDL_KEEPALIVE_TIMEOUT 300
/* period between keep alive signals in 0.1sec units*/
#define LDL_KEEPALIVE_TIMEOUT 6000
typedef struct ldl_crypto_data_s {
char *tag;
char *suite;
char *key;
} ldl_crypto_data_t;
/*! \brief A structure to store a jingle candidate */
struct ldl_candidate {
@@ -90,19 +97,89 @@ struct ldl_candidate {
};
typedef struct ldl_candidate ldl_candidate_t;
/*! \brief A structure to store a jingle payload */
typedef enum {
LDL_PAYLOAD_AUDIO,
LDL_PAYLOAD_VIDEO
} ldl_payload_type_t;
/*! \brief A structure to store a jingle audio payload */
struct ldl_payload {
/*! the type of the payload */
ldl_payload_type_t type;
/*! the iana name of the payload type */
char *name;
/*! the iana id of the payload type */
unsigned int id;
/* Audio */
/*! the transfer rate of the payload type */
unsigned int rate;
/*! the bits per second of the payload type */
unsigned int bps;
/* Video */
/*! the width of the video payload type */
unsigned int width;
/*! the width of the video payload type */
unsigned int height;
/*! the framerate of the video payload type */
unsigned int framerate;
unsigned int ptime;
};
typedef struct ldl_payload ldl_payload_t;
enum ldl_transport_type {
LDL_TPORT_RTP,
LDL_TPORT_VIDEO_RTP,
LDL_TPORT_RTCP,
LDL_TPORT_VIDEO_RTCP,
/* Nothing below that line */
LDL_TPORT_MAX
};
typedef enum ldl_transport_type ldl_transport_type_t;
static inline const char *ldl_transport_type_str(ldl_transport_type_t type)
{
static const char *name[] = { "rtp", "video_rtp", "rtcp", "video_rtcp" };
return type >= LDL_TPORT_MAX ? NULL : name[type];
}
static inline ldl_transport_type_t ldl_transport_type_parse(const char *type) {
if (!strcasecmp(type, "rtp")) {
return LDL_TPORT_RTP;
} else if (!strcasecmp(type, "rtcp")) {
return LDL_TPORT_RTCP;
} else if (!strcasecmp(type, "video_rtp")) {
return LDL_TPORT_VIDEO_RTP;
} else if (!strcasecmp(type, "video_rtcp")) {
return LDL_TPORT_VIDEO_RTCP;
} else {
return LDL_TPORT_MAX;
}
}
#if 0
/*! \brief A structure to store a jingle video payload */
struct ldl_vpayload {
/*! the iana name of the video payload type */
char *name;
/*! the iana id of the video payload type */
unsigned int id;
/*! the width of the video payload type */
unsigned int width;
/*! the width of the video payload type */
unsigned int height;
/*! the framerate of the video payload type */
unsigned int framerate;
};
typedef struct ldl_vpayload ldl_vpayload_t;
#endif
struct ldl_handle;
typedef struct ldl_handle ldl_handle_t;
@@ -132,7 +209,8 @@ typedef enum {
LDL_FLAG_SASL_MD5 = (1 << 12),
LDL_FLAG_COMPONENT = (1 << 13),
LDL_FLAG_OUTBOUND = (1 << 14),
LDL_FLAG_GATEWAY = (1 << 15)
LDL_FLAG_GATEWAY = (1 << 15),
LDL_FLAG_JINGLE = (1 << 16)
} ldl_user_flag_t;
typedef enum {
@@ -514,9 +592,10 @@ unsigned int ldl_session_transport(ldl_session_t *session,
\return the message_id of the generated xmpp request
*/
unsigned int ldl_session_describe(ldl_session_t *session,
ldl_payload_t *payloads,
unsigned int plen,
ldl_description_t description);
ldl_payload_t *payloads,
unsigned int plen,
ldl_description_t description, unsigned int *audio_ssrc, unsigned int *video_ssrc,
ldl_crypto_data_t *audio_crypto_data, ldl_crypto_data_t *video_crypto_data);
/*!
@@ -530,11 +609,12 @@ ldl_state_t ldl_session_get_state(ldl_session_t *session);
/*!
\brief get the candidates
\param session the session
\param tport type of transport (rtp,rtcp,video_rtp,video_rtcp,etc.)
\param candidates pointer to point at array of the candidates
\param len the resulting len of the array pointer
\return success or failure
*/
ldl_status ldl_session_get_candidates(ldl_session_t *session, ldl_candidate_t **candidates, unsigned int *len);
ldl_status ldl_session_get_candidates(ldl_session_t *session, ldl_transport_type_t tport, ldl_candidate_t **candidates, unsigned int *len);
/*!
\brief get the payloads
+1 -1
View File
@@ -18,7 +18,7 @@ a separate process, and your application communicates with it through pipes or
sockets.
This implementation of G.722.1 is adapted from the reference source code
provided by Polycom. Polycom has given its concent for this library to be
provided by Polycom. Polycom has given its consent for this library to be
distributed as source code, either on its own or as part of a larger package
which they have licenced under their royalty free licencing scheme.
+6
View File
@@ -0,0 +1,6 @@
%{
#include "scgi.h"
#include "scgi_oop.h"
%}
%include "scgi_oop.h"
+51
View File
@@ -0,0 +1,51 @@
PWD=$(shell pwd)
INCS=-I$(PWD)/src/include
DEBUG=-g -ggdb
BASE_FLAGS=$(INCS) $(DEBUG) -fPIC
PICKY=-O2
CFLAGS=$(BASE_FLAGS) $(PICKY)
CXXFLAGS=$(BASE_FLAGS)
MYLIB=libscgi.a
LIBS=
LDFLAGS=-L.
OBJS=src/scgi.o
SRC=src/scgi.c src/scgi_oop.cpp
HEADERS=src/include/scgi.h src/include/scgi_oop.h
SOLINK=-shared -Xlinker -x
# comment the next line to disable c++ (no swig mods for you then)
OBJS += src/scgi_oop.o
all: $(MYLIB) testclient testserver
$(MYLIB): $(OBJS) $(HEADERS) $(SRC)
ar rcs $(MYLIB) $(OBJS)
ranlib $(MYLIB)
%.o: %.c $(HEADERS)
$(CC) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@
%.o: %.cpp $(HEADERS)
$(CXX) $(CXX_CFLAGS) $(CXXFLAGS) -c $< -o $@
testclient: $(MYLIB) testclient.c
$(CC) $(CC_CFLAGS) $(CFLAGS) testclient.c -o testclient -lscgi $(LDFLAGS) $(LIBS)
testserver: $(MYLIB) testserver.c
$(CC) $(CC_CFLAGS) $(CFLAGS) testserver.c -o testserver -lscgi $(LDFLAGS) $(LIBS)
clean:
rm -f *.o src/*.o libscgi.a *~ src/*~ src/include/*~ testclient testserver
$(MAKE) -C perl clean
reswig: swigclean
$(MAKE) -C perl reswig
swigclean: clean
$(MAKE) -C perl swigclean
perlmod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C perl
perlmod-install: perlmod
$(MAKE) -C perl install
+105
View File
@@ -0,0 +1,105 @@
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 1.3.35
#
# Don't modify this file, modify the SWIG interface instead.
package FSSCGI;
require Exporter;
require DynaLoader;
@ISA = qw(Exporter DynaLoader);
package FSSCGIc;
bootstrap FSSCGI;
package FSSCGI;
@EXPORT = qw( );
# ---------- BASE METHODS -------------
package FSSCGI;
sub TIEHASH {
my ($classname,$obj) = @_;
return bless $obj, $classname;
}
sub CLEAR { }
sub FIRSTKEY { }
sub NEXTKEY { }
sub FETCH {
my ($self,$field) = @_;
my $member_func = "swig_${field}_get";
$self->$member_func();
}
sub STORE {
my ($self,$field,$newval) = @_;
my $member_func = "swig_${field}_set";
$self->$member_func($newval);
}
sub this {
my $ptr = shift;
return tied(%$ptr);
}
# ------- FUNCTION WRAPPERS --------
package FSSCGI;
############# Class : FSSCGI::SCGIhandle ##############
package FSSCGI::SCGIhandle;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( FSSCGI );
%OWNER = ();
%ITERATORS = ();
sub new {
my $pkg = shift;
my $self = FSSCGIc::new_SCGIhandle(@_);
bless $self, $pkg if defined($self);
}
sub DESTROY {
return unless $_[0]->isa('HASH');
my $self = tied(%{$_[0]});
return unless defined $self;
delete $ITERATORS{$self};
if (exists $OWNER{$self}) {
FSSCGIc::delete_SCGIhandle($self);
delete $OWNER{$self};
}
}
*connected = *FSSCGIc::SCGIhandle_connected;
*socketDescriptor = *FSSCGIc::SCGIhandle_socketDescriptor;
*disconnect = *FSSCGIc::SCGIhandle_disconnect;
*addParam = *FSSCGIc::SCGIhandle_addParam;
*addBody = *FSSCGIc::SCGIhandle_addBody;
*getBody = *FSSCGIc::SCGIhandle_getBody;
*getParam = *FSSCGIc::SCGIhandle_getParam;
*sendRequest = *FSSCGIc::SCGIhandle_sendRequest;
*respond = *FSSCGIc::SCGIhandle_respond;
*bind = *FSSCGIc::SCGIhandle_bind;
*accept = *FSSCGIc::SCGIhandle_accept;
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
# ------- VARIABLE STUBS --------
package FSSCGI;
1;
+38
View File
@@ -0,0 +1,38 @@
PERL=$(shell which perl)
PERL_SITEDIR=$(shell perl -MConfig -e 'print $$Config{sitelibexp}')
PERL_LIBDIR=-L$(shell perl -MConfig -e 'print $$Config{archlib}')/CORE
PERL_LIBS=$(shell perl -MConfig -e 'print $$Config{libs}')
LOCAL_CFLAGS=-w -DMULTIPLICITY $(shell $(PERL) -MExtUtils::Embed -e ccopts) -DEMBED_PERL
LOCAL_LDFLAGS=$(shell $(PERL) -MExtUtils::Embed -e ldopts) $(shell $(PERL) -MConfig -e 'print $$Config{libs}')
GCC_WARNING_JUNK=-w
PERL_INC=$(shell $(PERL) -MExtUtils::Embed -e perl_inc)
all: FSSCGI.so
scgi_wrap.cpp:
swig -module FSSCGI -shadow -perl5 -c++ -DMULTIPLICITY -I../src/include -o scgi_wrap.cpp ../FSSCGI.i
perlxsi.c:
$(PERL) -MExtUtils::Embed -e xsinit -- -o perlxsi.c
perlxsi.o: perlxsi.c
$(CC) $(CC_CFLAGS) $(CFLAGS) $(LOCAL_CFLAGS) -c perlxsi.c -o perlxsi.o
scgi_wrap.o: scgi_wrap.cpp
$(CXX) $(CXX_CFLAGS) $(CXXFLAGS) $(GCC_WARNING_JUNK) $(PERL_INC) -c scgi_wrap.cpp -o scgi_wrap.o
FSSCGI.so: scgi_wrap.o perlxsi.o
$(CXX) $(SOLINK) scgi_wrap.o perlxsi.o $(MYLIB) $(LOCAL_LDFLAGS) -o FSSCGI.so -L. $(LIBS)
clean:
rm -f *.o *.so *~
swigclean:
rm -f scgi_wrap.* FSSCGI.so FSSCGI.pm perlxsi.*
reswig: swigclean scgi_wrap.cpp perlxsi.c
install: FSSCGI.so
install -m 755 FSSCGI.so $(PERL_SITEDIR)
install -m 755 FSSCGI.pm $(PERL_SITEDIR)
install -d -m 755 FSSCGI $(PERL_SITEDIR)/FSSCGI
install -m 755 FSSCGI/* $(PERL_SITEDIR)/FSSCGI
File diff suppressed because it is too large. Load diff
+16
View File
@@ -0,0 +1,16 @@
#include <EXTERN.h>
#include <perl.h>
EXTERN_C void xs_init (pTHX);
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
EXTERN_C void
xs_init(pTHX)
{
char *file = __FILE__;
dXSUB_SYS;
/* DynaLoader is a special case */
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
}
File diff suppressed because it is too large. Load diff
+19
View File
@@ -0,0 +1,19 @@
use FSSCGI;
my $handle = new FSSCGI::SCGIhandle();
$handle->addParam( "REQUEST_METHOD", "POST");
$handle->addParam( "REQUEST_URI", "/deepthought");
$handle->addParam( "TESTING", "TRUE");
$handle->addParam( "TESTING", "TRUE");
$handle->addBody("What is the answer to life?");
if ((my $response = $handle->sendRequest("127.0.0.1", 7777, 10000))) {
print "RESP[$response]\n";
} else {
print "ERROR!\n";
}
+17
View File
@@ -0,0 +1,17 @@
use FSSCGI;
my $handle = new FSSCGI::SCGIhandle();
if ($handle->bind("127.0.0.1", 7777)) {
while($handle->accept()) {
print "REQ: " . $handle->getBody(). "\n\n";
$handle->respond("W00t!!!!!!\n");
}
print "DONE\n";
} else {
print "FAIL\n";
}
Loaded 100 of 1605 files, more files were not shown because too many files have changed in this diff. Show more