diff --git a/build/modules.conf.in b/build/modules.conf.in
index 3f77b125b5..f7b36831cc 100644
--- a/build/modules.conf.in
+++ b/build/modules.conf.in
@@ -99,6 +99,7 @@ event_handlers/mod_cdr_sqlite
#event_handlers/mod_event_multicast
event_handlers/mod_event_socket
#event_handlers/mod_event_zmq
+#event_handlers/mod_format_cdr
#event_handlers/mod_json_cdr
#event_handlers/mod_radius_cdr
#event_handlers/mod_rayo
diff --git a/conf/vanilla/autoload_configs/format_cdr.conf.xml b/conf/vanilla/autoload_configs/format_cdr.conf.xml
new file mode 100644
index 0000000000..227bcb4722
--- /dev/null
+++ b/conf/vanilla/autoload_configs/format_cdr.conf.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/configure.in b/configure.in
index eb845c3282..278243b6d4 100644
--- a/configure.in
+++ b/configure.in
@@ -420,9 +420,9 @@ if test "$PG_CONFIG" != "no"; then
POSTGRESQL_CXXFLAGS="`$PG_CONFIG --cppflags` -I`$PG_CONFIG --includedir`"
POSTGRESQL_LDFLAGS="`$PG_CONFIG --ldflags|sed 's/ -Wl,--as-needed//g'` -L`$PG_CONFIG --libdir` -lpq"
POSTGRESQL_VERSION=`$PG_CONFIG --version | sed -e 's#PostgreSQL ##'`
- POSTGRESQL_MAJOR_VERSION=`$PG_CONFIG --version | sed -re 's#PostgreSQL ([0-9]+).[0-9]+.[0-9]+#\1#'`
- POSTGRESQL_MINOR_VERSION=`$PG_CONFIG --version | sed -re 's#PostgreSQL [0-9]+.([0-9]+).[0-9]+#\1#'`
- POSTGRESQL_PATCH_VERSION=`$PG_CONFIG --version | sed -re 's#PostgreSQL [0-9]+.[0-9]+.([0-9]+)#\1#'`
+ POSTGRESQL_MAJOR_VERSION=`$PG_CONFIG --version | sed -e 's/devel//' | sed -re 's#PostgreSQL ([0-9]+).[0-9]+.?[0-9]+?#\1#'`
+ POSTGRESQL_MINOR_VERSION=`$PG_CONFIG --version | sed -e 's/devel//' | sed -re 's#PostgreSQL [0-9]+.([0-9]+).?[0-9]+?#\1#'`
+ POSTGRESQL_PATCH_VERSION=`$PG_CONFIG --version | sed -e 's/devel//' | sed -re 's#PostgreSQL [0-9]+.[0-9]+.?([0-9]+)?#\1#'`
AC_DEFINE([SWITCH_HAVE_PGSQL], [1], [Define to 1 if PostgreSQL libraries are available])
AC_DEFINE_UNQUOTED([POSTGRESQL_VERSION], "${POSTGRESQL_VERSION}", [Specifies the version of PostgreSQL we are linking against])
AC_DEFINE_UNQUOTED([POSTGRESQL_MAJOR_VERSION], ${POSTGRESQL_MAJOR_VERSION}, [Specifies the version of PostgreSQL we are linking against])
diff --git a/debian/control-modules b/debian/control-modules
index 679082187c..61f0b33a80 100644
--- a/debian/control-modules
+++ b/debian/control-modules
@@ -229,7 +229,7 @@ Description: Voicemail detection
Module: applications/mod_voicemail
Description: Voicemail
This module provides a voicemail system.
-Depends: mail-transport-agent
+Depends: ssmtp | mail-transport-agent
Module: applications/mod_voicemail_ivr
Description: Voicemail IVR
diff --git a/docs/phrase/phrase_en.xml b/docs/phrase/phrase_en.xml
index 15e80f8882..a37dd5e3cc 100644
--- a/docs/phrase/phrase_en.xml
+++ b/docs/phrase/phrase_en.xml
@@ -198,8 +198,10 @@
+
+
@@ -218,13 +220,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -232,10 +255,14 @@
+
+
+
+
@@ -260,6 +287,7 @@
+
@@ -388,7 +416,7 @@
-
+
@@ -443,7 +471,7 @@
-
+
@@ -507,6 +535,7 @@
+
@@ -598,12 +627,16 @@
+
+
+
+
diff --git a/libs/esl/php/Makefile b/libs/esl/php/Makefile
index dce8fd4bd1..97674f85be 100644
--- a/libs/esl/php/Makefile
+++ b/libs/esl/php/Makefile
@@ -17,6 +17,7 @@ all: ESL.so
esl_wrap.cpp:
swig -module ESL -php5 -c++ -DMULTIPLICITY -I../src/include -o esl_wrap.cpp ../ESL.i
+ sed -e 's/ char \*type_name;/ const char \*type_name;/' -i esl_wrap.cpp
esl_wrap.o: esl_wrap.cpp
$(CXX) $(CXX_CFLAGS) $(CXXFLAGS) $(LOCAL_CFLAGS) $(WRAP_GCC_WARNING_SILENCE) -c esl_wrap.cpp -o esl_wrap.o
diff --git a/libs/esl/php/esl_wrap.cpp b/libs/esl/php/esl_wrap.cpp
index 8c91f25452..0389cc2151 100644
--- a/libs/esl/php/esl_wrap.cpp
+++ b/libs/esl/php/esl_wrap.cpp
@@ -857,7 +857,7 @@ SWIG_ZTS_ConvertResourcePtr(zval *z, swig_type_info *ty, int flags TSRMLS_DC) {
swig_object_wrapper *value;
void *p;
int type;
- char *type_name;
+ const char *type_name;
value = (swig_object_wrapper *) zend_list_find(z->value.lval, &type);
if ( flags && SWIG_POINTER_DISOWN ) {
diff --git a/libs/esl/src/include/cc.h b/libs/esl/src/include/cc.h
index 965aa9cbac..d2635f3b1c 100644
--- a/libs/esl/src/include/cc.h
+++ b/libs/esl/src/include/cc.h
@@ -1,4 +1,4 @@
-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";
+const char *cc = ".=======================================================================================================.\n| ____ _ ____ |\n| / ___| |_ _ ___ / ___|___ _ __ |\n| | | | | | | |/ _ \\ | / _ \\| '_ \\ |\n| | |___| | |_| | __/ |__| (_) | | | | |\n| \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |\n| |\n| _____ _ _ ____ __ |\n| |_ _|__| | ___ _ __ | |__ ___ _ __ _ _ / ___|___ _ __ / _| ___ _ __ ___ _ __ ___ ___ |\n| | |/ _ \\ |/ _ \\ '_ \\| '_ \\ / _ \\| '_ \\| | | | | | / _ \\| '_ \\| |_ / _ \\ '__/ _ \\ '_ \\ / __/ _ \\ |\n| | | __/ | __/ |_) | | | | (_) | | | | |_| | | |__| (_) | | | | _| __/ | | __/ | | | (_| __/ |\n| |_|\\___|_|\\___| .__/|_| |_|\\___/|_| |_|\\__, | \\____\\___/|_| |_|_| \\___|_| \\___|_| |_|\\___\\___| |\n| |_| |___/ |\n| _____ _ _ |\n| | ____|_ _____ _ __ _ _ / \\ _ _ __ _ _ _ ___| |_ |\n| | _| \\ \\ / / _ \\ '__| | | | / _ \\| | | |/ _` | | | / __| __| |\n| | |___ \\ V / __/ | | |_| | / ___ \\ |_| | (_| | |_| \\__ \\ |_ |\n| |_____| \\_/ \\___|_| \\__, | /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| |\n| |___/ |___/ |\n| ____ _ ____ |\n| __ ____ ____ __ / ___| |_ _ ___ / ___|___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / | | | | | | |/ _ \\ | / _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | |___| | |_| | __/ |__| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\____|_|\\__,_|\\___|\\____\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.=======================================================================================================.\n";
const char *cc_s = ".===============================================================.\n| _ |\n| ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.===============================================================.\n";
diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
index cb0d80ff20..471afe080c 100644
--- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
+++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
@@ -1913,6 +1913,12 @@ static int on_ring(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event
ftdm_set_string(caller_data->dnis.digits, (char *)pevent->ring.callednum);
ftdm_set_string(caller_data->rdnis.digits, (char *)pevent->ring.redirectingnum);
+ caller_data->cid_num.type = pevent->ring.callingplan >> 4;
+ caller_data->cid_num.plan = pevent->ring.callingplan & 0x0F;
+
+ caller_data->dnis.type = pevent->ring.calledplan >> 4;
+ caller_data->dnis.plan = pevent->ring.calledplan & 0x0F;
+
if (!ftdm_strlen_zero((char *)pevent->ring.callingname)) {
ftdm_set_string(caller_data->cid_name, (char *)pevent->ring.callingname);
} else {
diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update
index 76ab95f85f..36fa387d65 100644
--- a/libs/sofia-sip/.update
+++ b/libs/sofia-sip/.update
@@ -1 +1 @@
-Tue Sep 17 06:24:17 CDT 2013
+Tue Oct 8 12:10:32 CDT 2013
diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c
index 4c48dfc133..7877100978 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c
@@ -1589,7 +1589,7 @@ static void parse_media_attr(sdp_parser_t *p, char *r, sdp_media_t *m,
if (p->pr_mode_manual)
;
- else if (su_casematch(name, "inactive")) {
+ else if (m->m_port == 0 || su_casematch(name, "inactive")) {
m->m_mode = sdp_inactive;
return;
}
diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c
index 537e9fe606..70a5b23b72 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c
@@ -640,14 +640,16 @@ static void print_media(sdp_printer_t *p,
print_key(p, m->m_key);
for (rm = m->m_rtpmaps; rm; rm = rm->rm_next) {
- if (!rm->rm_predef || p->pr_all_rtpmaps)
- sdp_printf(p, "a=rtpmap:%u %s/%lu%s%s" CRLF,
- rm->rm_pt, rm->rm_encoding, rm->rm_rate,
- rm->rm_params ? "/" : "",
- rm->rm_params ? rm->rm_params : "");
- if (rm->rm_fmtp)
- sdp_printf(p, "a=fmtp:%u %s" CRLF,
- rm->rm_pt, rm->rm_fmtp);
+ if (rm->rm_encoding && *rm->rm_encoding && (!rm->rm_predef || p->pr_all_rtpmaps)) {
+ sdp_printf(p, "a=rtpmap:%u %s/%lu%s%s" CRLF,
+ rm->rm_pt, rm->rm_encoding, rm->rm_rate,
+ rm->rm_params ? "/" : "",
+ rm->rm_params ? rm->rm_params : "");
+ }
+ if (rm->rm_fmtp) {
+ sdp_printf(p, "a=fmtp:%u %s" CRLF,
+ rm->rm_pt, rm->rm_fmtp);
+ }
}
if (!p->pr_mode_manual && !m->m_rejected &&
diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_feature.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_feature.c
index b2940526b3..e203964a82 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_feature.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_feature.c
@@ -116,7 +116,7 @@ static int sip_allow_update(msg_common_t *h,
k->k_bitmap = 0;
}
else {
- sip_method_t method = sip_method_code(name);
+ int method = (int)sip_method_code(name);
if (method >= 0 && method < 32)
k->k_bitmap |= 1 << method;
@@ -130,14 +130,16 @@ int sip_is_allowed(sip_allow_t const *allow,
sip_method_t method,
char const *name)
{
- if (method < sip_method_unknown || !allow)
+ int meth = method;
+
+ if (meth < sip_method_unknown || !allow)
return 0;
- if (sip_method_unknown < method && method < 32)
+ if (sip_method_unknown < meth && meth < 32)
/* Well-known method */
- return (allow->k_bitmap & (1 << method)) != 0;
+ return (allow->k_bitmap & (1 << meth)) != 0;
- if (method == sip_method_unknown &&
+ if (meth == sip_method_unknown &&
(allow->k_bitmap & (1 << sip_method_unknown)) == 0)
return 0;
diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c
index cf470075a2..a2880df520 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c
@@ -672,7 +672,7 @@ static void sip_fragment_clear_chain(sip_header_t *h)
{
void const *next;
- for (h = h; h; h = h->sh_succ) {
+ for (; h; h = h->sh_succ) {
next = (char *)h->sh_data + h->sh_len;
sip_fragment_clear(h->sh_common);
diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport.c
index 50050e2289..ccffb5e007 100644
--- a/libs/sofia-sip/libsofia-sip-ua/tport/tport.c
+++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport.c
@@ -3322,7 +3322,8 @@ tport_t *tport_tsend(tport_t *self,
self = primary->pri_primary;
}
else if (tport_is_secondary(self) && tport_is_clear_to_send(self)) {
- self = self;
+ /* self = self; */
+ ;
}
/*
* Try to find an already open connection to the destination,
diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c
index 6039aea826..a8d056c895 100644
--- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c
+++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c
@@ -223,6 +223,7 @@ int ws_handshake(wsh_t *wsh)
char key[256] = "";
char version[5] = "";
char proto[256] = "";
+ char proto_buf[384] = "";
char uri[256] = "";
char input[256] = "";
unsigned char output[SHA1_HASH_SIZE] = "";
@@ -242,7 +243,7 @@ int ws_handshake(wsh_t *wsh)
}
}
- if (bytes > sizeof(wsh->buffer)) {
+ if (bytes > sizeof(wsh->buffer) -1) {
goto err;
}
@@ -273,14 +274,18 @@ int ws_handshake(wsh_t *wsh)
sha1_digest(output, input);
b64encode((unsigned char *)output, SHA1_HASH_SIZE, (unsigned char *)b64, sizeof(b64));
+ if (*proto) {
+ snprintf(proto_buf, sizeof(proto_buf), "Sec-WebSocket-Protocol: %s\r\n", proto);
+ }
+
snprintf(respond, sizeof(respond),
"HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: %s\r\n"
- "Sec-WebSocket-Protocol: %s\r\n\r\n",
+ "%s\r\n",
b64,
- proto);
+ proto_buf);
ws_raw_write(wsh, respond, strlen(respond));
@@ -319,7 +324,7 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes)
#endif
} while (r == -1 && SSL_get_error(wsh->ssl, r) == SSL_ERROR_WANT_READ && x < 100);
- return r;
+ goto end;
}
do {
@@ -336,6 +341,12 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes)
r = -1;
}
+ end:
+
+ if (r > 0) {
+ *((char *)data + r) = '\0';
+ }
+
return r;
}
@@ -530,7 +541,7 @@ ssize_t ws_close(wsh_t *wsh, int16_t reason)
restore_socket(wsh->sock);
- if (wsh->close_sock) {
+ if (wsh->close_sock && wsh->sock != ws_sock_invalid) {
close(wsh->sock);
}
@@ -559,7 +570,11 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data)
return ws_close(wsh, WS_PROTO_ERR);
}
- if ((wsh->datalen = ws_raw_read(wsh, wsh->buffer, 9)) < need) {
+ if ((wsh->datalen = ws_raw_read(wsh, wsh->buffer, 9)) < 0) {
+ return ws_close(wsh, WS_PROTO_ERR);
+ }
+
+ if (wsh->datalen < need) {
if ((wsh->datalen += ws_raw_read(wsh, wsh->buffer + wsh->datalen, 9 - wsh->datalen)) < need) {
/* too small - protocol err */
return ws_close(wsh, WS_PROTO_ERR);
diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.h b/libs/sofia-sip/libsofia-sip-ua/tport/ws.h
index ac383e9c8b..11e6b93068 100644
--- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.h
+++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.h
@@ -13,6 +13,7 @@
#include
#else
#pragma warning(disable:4996)
+#include
#endif
#include
#include
@@ -26,14 +27,7 @@
#include
#ifdef _MSC_VER
-#ifdef _WIN64
-#define WS_SSIZE_T __int64
-#elif _MSC_VER >= 1400
-#define WS_SSIZE_T __int32 __w64
-#else
-#define WS_SSIZE_T __int32
-#endif
-typedef WS_SSIZE_T ssize_t
+typedef intptr_t ssize_t;
#endif
diff --git a/libs/spandsp/src/fax.c b/libs/spandsp/src/fax.c
index 3a08d49218..8d8b3b25bc 100644
--- a/libs/spandsp/src/fax.c
+++ b/libs/spandsp/src/fax.c
@@ -163,7 +163,8 @@ SPAN_DECLARE_NONSTD(int) fax_rx(fax_state_t *s, int16_t *amp, int len)
#endif
for (i = 0; i < len; i++)
amp[i] = dc_restore(&s->modems.dc_restore, amp[i]);
- s->modems.rx_handler(s->modems.rx_user_data, amp, len);
+ if (s->modems.rx_handler)
+ s->modems.rx_handler(s->modems.rx_user_data, amp, len);
t30_timer_update(&s->t30, len);
return 0;
}
@@ -197,26 +198,6 @@ SPAN_DECLARE_NONSTD(int) fax_rx_fillin(fax_state_t *s, int len)
}
/*- End of function --------------------------------------------------------*/
-static int set_next_tx_type(fax_state_t *s)
-{
- fax_modems_state_t *t;
-
- t = &s->modems;
- if (t->next_tx_handler)
- {
- fax_modems_set_tx_handler(t, t->next_tx_handler, t->next_tx_user_data);
- t->next_tx_handler = NULL;
- return 0;
- }
- /* If there is nothing else to change to, so use zero length silence */
- silence_gen_alter(&t->silence_gen, 0);
- fax_modems_set_tx_handler(t, (span_tx_handler_t) &silence_gen, &t->silence_gen);
- fax_modems_set_next_tx_handler(t, (span_tx_handler_t) NULL, NULL);
- t->transmit = false;
- return -1;
-}
-/*- End of function --------------------------------------------------------*/
-
SPAN_DECLARE_NONSTD(int) fax_tx(fax_state_t *s, int16_t *amp, int max_len)
{
int len;
@@ -226,41 +207,30 @@ SPAN_DECLARE_NONSTD(int) fax_tx(fax_state_t *s, int16_t *amp, int max_len)
required_len = max_len;
#endif
len = 0;
- if (s->modems.transmit)
+ while (s->modems.transmit && (len += s->modems.tx_handler(s->modems.tx_user_data, &[len], max_len - len)) < max_len)
{
- while ((len += s->modems.tx_handler(s->modems.tx_user_data, amp + len, max_len - len)) < max_len)
- {
- /* Allow for a change of tx handler within a block */
- if (set_next_tx_type(s) && s->modems.current_tx_type != T30_MODEM_NONE && s->modems.current_tx_type != T30_MODEM_DONE)
- t30_front_end_status(&s->t30, T30_FRONT_END_SEND_STEP_COMPLETE);
- if (!s->modems.transmit)
- {
- if (s->modems.transmit_on_idle)
- {
- /* Pad to the requested length with silence */
- memset(amp + len, 0, (max_len - len)*sizeof(int16_t));
- len = max_len;
- }
- break;
- }
- }
+ /* Allow for a change of tx handler within a block */
+ if (fax_modems_set_next_tx_type(&s->modems) && s->modems.current_tx_type != T30_MODEM_NONE && s->modems.current_tx_type != T30_MODEM_DONE)
+ t30_front_end_status(&s->t30, T30_FRONT_END_SEND_STEP_COMPLETE);
+ /*endif*/
}
- else
+ /*endwhile*/
+ if (s->modems.transmit_on_idle)
{
- if (s->modems.transmit_on_idle)
- {
- /* Pad to the requested length with silence */
- memset(amp, 0, max_len*sizeof(int16_t));
- len = max_len;
- }
+ /* Pad to the requested length with silence */
+ memset(&[len], 0, (max_len - len)*sizeof(int16_t));
+ len = max_len;
}
+ /*endif*/
#if defined(LOG_FAX_AUDIO)
if (s->modems.audio_tx_log >= 0)
{
if (len < required_len)
- memset(amp + len, 0, (required_len - len)*sizeof(int16_t));
+ memset(&[len], 0, (required_len - len)*sizeof(int16_t));
+ /*endif*/
write(s->modems.audio_tx_log, amp, required_len*sizeof(int16_t));
}
+ /*endif*/
#endif
return len;
}
@@ -285,7 +255,6 @@ static void fax_set_rx_type(void *user_data, int type, int bit_rate, int short_t
{
case T30_MODEM_V21:
fax_modems_start_slow_modem(t, FAX_MODEM_V21_RX);
- fax_modems_set_rx_handler(t, (span_rx_handler_t) &fsk_rx, &t->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &t->v21_rx);
break;
case T30_MODEM_V17:
fax_modems_start_fast_modem(t, FAX_MODEM_V17_RX, bit_rate, short_train, use_hdlc);
@@ -316,6 +285,7 @@ static void fax_set_tx_type(void *user_data, int type, int bit_rate, int short_t
span_log(&s->logging, SPAN_LOG_FLOW, "Set tx type %d\n", type);
if (t->current_tx_type == type)
return;
+
switch (type)
{
case T30_MODEM_PAUSE:
diff --git a/libs/spandsp/src/fax_modems.c b/libs/spandsp/src/fax_modems.c
index 413a464330..e298f4d70a 100644
--- a/libs/spandsp/src/fax_modems.c
+++ b/libs/spandsp/src/fax_modems.c
@@ -101,6 +101,50 @@
#define HDLC_FRAMING_OK_THRESHOLD 5
+SPAN_DECLARE(const char *) fax_modem_to_str(int modem)
+{
+ switch (modem)
+ {
+ case FAX_MODEM_NONE:
+ return "None";
+ case FAX_MODEM_FLUSH:
+ return "Flush";
+ case FAX_MODEM_SILENCE_TX:
+ return "Silence Tx";
+ case FAX_MODEM_SILENCE_RX:
+ return "Silence Rx";
+ case FAX_MODEM_CED_TONE_TX:
+ return "CED Tx";
+ case FAX_MODEM_CNG_TONE_TX:
+ return "CNG Tx";
+ case FAX_MODEM_NOCNG_TONE_TX:
+ return "No CNG Tx";
+ case FAX_MODEM_CED_TONE_RX:
+ return "CED Rx";
+ case FAX_MODEM_CNG_TONE_RX:
+ return "CNG Rx";
+ case FAX_MODEM_V21_TX:
+ return "V.21 Tx";
+ case FAX_MODEM_V17_TX:
+ return "V.17 Tx";
+ case FAX_MODEM_V27TER_TX:
+ return "V.27ter Tx";
+ case FAX_MODEM_V29_TX:
+ return "V.29 Tx";
+ case FAX_MODEM_V21_RX:
+ return "V.21 Rx";
+ case FAX_MODEM_V17_RX:
+ return "V.17 Rx";
+ case FAX_MODEM_V27TER_RX:
+ return "V.27ter Rx";
+ case FAX_MODEM_V29_RX:
+ return "V.29 Rx";
+ }
+ /*endswitch*/
+ return "???";
+}
+/*- End of function --------------------------------------------------------*/
+
static void fax_modems_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok)
{
fax_modems_state_t *s;
@@ -489,6 +533,23 @@ SPAN_DECLARE(void) fax_modems_set_next_tx_handler(fax_modems_state_t *s, span_tx
}
/*- End of function --------------------------------------------------------*/
+SPAN_DECLARE(int) fax_modems_set_next_tx_type(fax_modems_state_t *s)
+{
+ if (s->next_tx_handler)
+ {
+ fax_modems_set_tx_handler(s, s->next_tx_handler, s->next_tx_user_data);
+ fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+ return 0;
+ }
+ /* There is nothing else to change to, so use zero length silence */
+ silence_gen_alter(&s->silence_gen, 0);
+ fax_modems_set_tx_handler(s, (span_tx_handler_t) &silence_gen, &s->silence_gen);
+ fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL);
+ s->transmit = false;
+ return -1;
+}
+/*- End of function --------------------------------------------------------*/
+
SPAN_DECLARE(void) fax_modems_set_tep_mode(fax_modems_state_t *s, int use_tep)
{
s->use_tep = use_tep;
diff --git a/libs/spandsp/src/make_at_dictionary.c b/libs/spandsp/src/make_at_dictionary.c
index 7f05dd9b14..3a881af992 100644
--- a/libs/spandsp/src/make_at_dictionary.c
+++ b/libs/spandsp/src/make_at_dictionary.c
@@ -24,10 +24,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#if defined(HAVE_CONFIG_H)
-#include "config.h"
-#endif
-
#include
#include
#include
diff --git a/libs/spandsp/src/make_cielab_luts.c b/libs/spandsp/src/make_cielab_luts.c
index 5fca6c7236..b143817d85 100644
--- a/libs/spandsp/src/make_cielab_luts.c
+++ b/libs/spandsp/src/make_cielab_luts.c
@@ -25,22 +25,13 @@
/*! \file */
-#if defined(HAVE_CONFIG_H)
-#include "config.h"
-#endif
-
#include
#include
#include
#include
#include
#include
-#if defined(HAVE_TGMATH_H)
-#include
-#endif
-#if defined(HAVE_MATH_H)
#include
-#endif
typedef struct
{
diff --git a/libs/spandsp/src/make_math_fixed_tables.c b/libs/spandsp/src/make_math_fixed_tables.c
index 64b33ca328..075cb15bd2 100644
--- a/libs/spandsp/src/make_math_fixed_tables.c
+++ b/libs/spandsp/src/make_math_fixed_tables.c
@@ -24,10 +24,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#if defined(HAVE_CONFIG_H)
-#include "config.h"
-#endif
-
#include
#include
#include
diff --git a/libs/spandsp/src/make_modem_filter.c b/libs/spandsp/src/make_modem_filter.c
index b0faed4a02..bd9427e24f 100644
--- a/libs/spandsp/src/make_modem_filter.c
+++ b/libs/spandsp/src/make_modem_filter.c
@@ -24,10 +24,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#if defined(HAVE_CONFIG_H)
-#include "config.h"
-#endif
-
#include
#include
#include
@@ -35,22 +31,20 @@
#include
#include
#include
-#if defined(HAVE_TGMATH_H)
-#include
-#endif
-#if defined(HAVE_MATH_H)
#include
-#endif
#if defined(HAVE_STDBOOL_H)
#include
#else
#include "spandsp/stdbool.h"
#endif
-#include "floating_fudge.h"
#if defined(__sunos) || defined(__solaris) || defined(__sun)
#include
#endif
+#if defined (_MSC_VER)
+ #define __inline__ __inline
+#endif
+
#include "spandsp/telephony.h"
#include "spandsp/complex.h"
#include "filter_tools.h"
diff --git a/libs/spandsp/src/make_t43_gray_code_tables.c b/libs/spandsp/src/make_t43_gray_code_tables.c
index c44adc27bb..90117c5d83 100644
--- a/libs/spandsp/src/make_t43_gray_code_tables.c
+++ b/libs/spandsp/src/make_t43_gray_code_tables.c
@@ -24,10 +24,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#if defined(HAVE_CONFIG_H)
-#include "config.h"
-#endif
-
#include
#include
#include
@@ -41,12 +37,13 @@ int main(int argc, char *argv[])
int j;
int gray;
int new_gray;
- int restore = 0;
+ int restore;
printf("static const int16_t gray_code[4096] =\n{\n");
for (i = 0; i < 4096; i++)
{
gray = i & 0x800;
+ restore = i;
for (j = 10; j >= 0; j--)
{
if (((i >> (j + 1)) & 1) ^ ((i >> j) & 1))
diff --git a/libs/spandsp/src/msvc/spandsp.h b/libs/spandsp/src/msvc/spandsp.h
index b98aa66aa4..fb7b1431b1 100644
--- a/libs/spandsp/src/msvc/spandsp.h
+++ b/libs/spandsp/src/msvc/spandsp.h
@@ -36,9 +36,10 @@
#define SPANDSP_USE_EXPORT_CAPABILITY 1
-#undef SPANDSP_SUPPORT_T42
#undef SPANDSP_SUPPORT_T43
+#undef SPANDSP_SUPPORT_V32BIS
#undef SPANDSP_SUPPORT_V34
+#undef SPANDSP_SUPPORT_TIFF_FX
#include
#include
diff --git a/libs/spandsp/src/spandsp/bit_operations.h b/libs/spandsp/src/spandsp/bit_operations.h
index 2deca2828a..311408123e 100644
--- a/libs/spandsp/src/spandsp/bit_operations.h
+++ b/libs/spandsp/src/spandsp/bit_operations.h
@@ -42,7 +42,7 @@ extern "C"
/*! \brief Find the bit position of the highest set bit in a word
\param bits The word to be searched
\return The bit number of the highest set bit, or -1 if the word is zero. */
-static __inline__ int top_bit(unsigned int bits)
+static __inline__ int top_bit(uint32_t bits)
{
#if defined(SPANDSP_USE_86_ASM)
int res;
@@ -141,7 +141,7 @@ static __inline__ int top_bit(unsigned int bits)
/*! \brief Find the bit position of the lowest set bit in a word
\param bits The word to be searched
\return The bit number of the lowest set bit, or -1 if the word is zero. */
-static __inline__ int bottom_bit(unsigned int bits)
+static __inline__ int bottom_bit(uint32_t bits)
{
int res;
diff --git a/libs/spandsp/src/spandsp/fax_modems.h b/libs/spandsp/src/spandsp/fax_modems.h
index 3c76022575..2ffb7be7c5 100644
--- a/libs/spandsp/src/spandsp/fax_modems.h
+++ b/libs/spandsp/src/spandsp/fax_modems.h
@@ -59,6 +59,12 @@ extern "C"
{
#endif
+/*! Convert a FAX modem type to a short text description.
+ \brief Convert a FAX modem type to a short text description.
+ \param modem The modem code.
+ \return A pointer to the description. */
+SPAN_DECLARE(const char *) fax_modem_to_str(int modem);
+
/* N.B. the following are currently a work in progress */
SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], int len);
SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len);
@@ -93,6 +99,8 @@ SPAN_DECLARE(void) fax_modems_set_tx_handler(fax_modems_state_t *s, span_tx_hand
SPAN_DECLARE(void) fax_modems_set_next_tx_handler(fax_modems_state_t *s, span_tx_handler_t handler, void *user_data);
+SPAN_DECLARE(int) fax_modems_set_next_tx_type(fax_modems_state_t *s);
+
SPAN_DECLARE(int) fax_modems_restart(fax_modems_state_t *s);
/*! Get a pointer to the logging context associated with a FAX modems context.
diff --git a/libs/spandsp/src/spandsp/t30_logging.h b/libs/spandsp/src/spandsp/t30_logging.h
index 2dc9bb321c..7122b1c6eb 100644
--- a/libs/spandsp/src/spandsp/t30_logging.h
+++ b/libs/spandsp/src/spandsp/t30_logging.h
@@ -53,6 +53,12 @@ SPAN_DECLARE(void) t30_decode_dis_dtc_dcs(t30_state_t *s, const uint8_t *dis, in
\return A pointer to the description. */
SPAN_DECLARE(const char *) t30_completion_code_to_str(int result);
+/*! Convert a T.30 modem type to a short text description.
+ \brief Convert a T.30 modem type to a short text description.
+ \param modem The modem code.
+ \return A pointer to the description. */
+SPAN_DECLARE(const char *) t30_modem_to_str(int modem);
+
#if defined(__cplusplus)
}
#endif
diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c
index 7defb47d15..de71d91067 100644
--- a/libs/spandsp/src/t30.c
+++ b/libs/spandsp/src/t30.c
@@ -421,7 +421,7 @@ static const struct
{ 7200, T30_MODEM_V29, T30_SUPPORT_V29, (DISBIT4 | DISBIT3)},
{ 4800, T30_MODEM_V27TER, T30_SUPPORT_V27TER, DISBIT4},
{ 2400, T30_MODEM_V27TER, T30_SUPPORT_V27TER, 0},
- { 0, 0, 0, 0}
+ { 0, 0, 0, 0}
};
static void queue_phase(t30_state_t *s, int phase);
@@ -437,6 +437,7 @@ static void decode_20digit_msg(t30_state_t *s, char *msg, const uint8_t *pkt, in
static void decode_url_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len);
static int decode_nsf_nss_nsc(t30_state_t *s, uint8_t *msg[], const uint8_t *pkt, int len);
static void set_min_scan_time(t30_state_t *s);
+static int build_dcs(t30_state_t *s);
static void timer_t2_start(t30_state_t *s);
static void timer_t2a_start(t30_state_t *s);
static void timer_t2b_start(t30_state_t *s);
@@ -470,6 +471,27 @@ static int find_fallback_entry(int dcs_code)
}
/*- End of function --------------------------------------------------------*/
+static int step_fallback_entry(t30_state_t *s)
+{
+ while (fallback_sequence[++s->current_fallback].bit_rate)
+ {
+ if ((fallback_sequence[s->current_fallback].which & s->current_permitted_modems))
+ break;
+ }
+ if (fallback_sequence[s->current_fallback].bit_rate == 0)
+ {
+ /* Reset the fallback sequence */
+ s->current_fallback = 0;
+ return -1;
+ }
+ /* We need to update the minimum scan time, in case we are in non-ECM mode. */
+ set_min_scan_time(s);
+ /* Now we need to rebuild the DCS message we will send. */
+ build_dcs(s);
+ return s->current_fallback;
+}
+/*- End of function --------------------------------------------------------*/
+
static int terminate_operation_in_progress(t30_state_t *s)
{
/* Make sure any FAX in progress is tidied up. If the tidying up has
@@ -2242,23 +2264,6 @@ static int analyze_rx_dcs(t30_state_t *s, const uint8_t *msg, int len)
}
/*- End of function --------------------------------------------------------*/
-static int step_fallback_entry(t30_state_t *s)
-{
- while (fallback_sequence[++s->current_fallback].which)
- {
- if ((fallback_sequence[s->current_fallback].which & s->current_permitted_modems))
- break;
- }
- if (fallback_sequence[s->current_fallback].which == 0)
- return -1;
- /* We need to update the minimum scan time, in case we are in non-ECM mode. */
- set_min_scan_time(s);
- /* Now we need to rebuild the DCS message we will send. */
- build_dcs(s);
- return s->current_fallback;
-}
-/*- End of function --------------------------------------------------------*/
-
static void send_dcn(t30_state_t *s)
{
queue_phase(s, T30_PHASE_D_TX);
@@ -2710,6 +2715,13 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
send_dcn(s);
return -1;
}
+ /* Start document transmission */
+ span_log(&s->logging,
+ SPAN_LOG_FLOW,
+ "Put document with modem (%d) %s at %dbps\n",
+ fallback_sequence[s->current_fallback].modem_type,
+ t30_modem_to_str(fallback_sequence[s->current_fallback].modem_type),
+ fallback_sequence[s->current_fallback].bit_rate);
s->retries = 0;
send_dcs_sequence(s, true);
return 0;
@@ -2773,9 +2785,10 @@ static int process_rx_dcs(t30_state_t *s, const uint8_t *msg, int len)
/* Start document reception */
span_log(&s->logging,
SPAN_LOG_FLOW,
- "Get document at %dbps, modem %d\n",
- fallback_sequence[s->current_fallback].bit_rate,
- fallback_sequence[s->current_fallback].modem_type);
+ "Get document with modem (%d) %s at %dbps\n",
+ fallback_sequence[s->current_fallback].modem_type,
+ t30_modem_to_str(fallback_sequence[s->current_fallback].modem_type),
+ fallback_sequence[s->current_fallback].bit_rate);
if (s->rx_file[0] == '\0')
{
span_log(&s->logging, SPAN_LOG_FLOW, "No document to receive\n");
@@ -3439,7 +3452,6 @@ static void process_state_d_post_tcf(t30_state_t *s, const uint8_t *msg, int len
if (step_fallback_entry(s) < 0)
{
/* We have fallen back as far as we can go. Give up. */
- s->current_fallback = 0;
t30_set_status(s, T30_ERR_CANNOT_TRAIN);
send_dcn(s);
break;
@@ -4091,7 +4103,6 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
if (step_fallback_entry(s) < 0)
{
/* We have fallen back as far as we can go. Give up. */
- s->current_fallback = 0;
t30_set_status(s, T30_ERR_CANNOT_TRAIN);
send_dcn(s);
break;
@@ -4152,7 +4163,6 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
if (step_fallback_entry(s) < 0)
{
/* We have fallen back as far as we can go. Give up. */
- s->current_fallback = 0;
t30_set_status(s, T30_ERR_CANNOT_TRAIN);
send_dcn(s);
break;
@@ -4186,7 +4196,6 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
if (step_fallback_entry(s) < 0)
{
/* We have fallen back as far as we can go. Give up. */
- s->current_fallback = 0;
t30_set_status(s, T30_ERR_CANNOT_TRAIN);
send_dcn(s);
break;
diff --git a/libs/spandsp/src/t30_logging.c b/libs/spandsp/src/t30_logging.c
index a3dea97b2e..51739999d1 100644
--- a/libs/spandsp/src/t30_logging.c
+++ b/libs/spandsp/src/t30_logging.c
@@ -246,6 +246,36 @@ SPAN_DECLARE(const char *) t30_completion_code_to_str(int result)
}
/*- End of function --------------------------------------------------------*/
+SPAN_DECLARE(const char *) t30_modem_to_str(int modem)
+{
+ switch (modem)
+ {
+ case T30_MODEM_NONE:
+ return "None";
+ case T30_MODEM_PAUSE:
+ return "Pause";
+ case T30_MODEM_CED:
+ return "CED";
+ case T30_MODEM_CNG:
+ return "CNG";
+ case T30_MODEM_V21:
+ return "V.21";
+ case T30_MODEM_V27TER:
+ return "V.27ter";
+ case T30_MODEM_V29:
+ return "V.29";
+ case T30_MODEM_V17:
+ return "V.17";
+ case T30_MODEM_V34HDX:
+ return "V.34HDX";
+ case T30_MODEM_DONE:
+ return "Done";
+ }
+ /*endswitch*/
+ return "???";
+}
+/*- End of function --------------------------------------------------------*/
+
SPAN_DECLARE(const char *) t30_frametype(uint8_t x)
{
switch (x)
diff --git a/libs/spandsp/src/t31.c b/libs/spandsp/src/t31.c
index 79ba8f5286..76aa7e56ab 100644
--- a/libs/spandsp/src/t31.c
+++ b/libs/spandsp/src/t31.c
@@ -2830,7 +2830,8 @@ SPAN_DECLARE_NONSTD(int) t31_rx(t31_state_t *s, int16_t amp[], int len)
}
/*endif*/
- s->audio.modems.rx_handler(s->audio.modems.rx_user_data, amp, len);
+ if (s->audio.modems.rx_handler)
+ s->audio.modems.rx_handler(s->audio.modems.rx_user_data, amp, len);
return 0;
}
/*- End of function --------------------------------------------------------*/
@@ -2861,23 +2862,6 @@ SPAN_DECLARE_NONSTD(int) t31_rx_fillin(t31_state_t *s, int len)
}
/*- End of function --------------------------------------------------------*/
-static int set_next_tx_type(t31_state_t *s)
-{
- if (s->audio.next_tx_handler)
- {
- fax_modems_set_tx_handler(&s->audio.modems, s->audio.next_tx_handler, s->audio.next_tx_user_data);
- fax_modems_set_next_tx_handler(&s->audio.modems, (span_tx_handler_t) NULL, NULL);
- return 0;
- }
- /*endif*/
- /* There is nothing else to change to, so use zero length silence */
- silence_gen_alter(&s->audio.modems.silence_gen, 0);
- fax_modems_set_tx_handler(&s->audio.modems, (span_tx_handler_t) &silence_gen, &s->audio.modems.silence_gen);
- fax_modems_set_next_tx_handler(&s->audio.modems, (span_tx_handler_t) NULL, NULL);
- return -1;
-}
-/*- End of function --------------------------------------------------------*/
-
SPAN_DECLARE_NONSTD(int) t31_tx(t31_state_t *s, int16_t amp[], int max_len)
{
int len;
@@ -2888,8 +2872,8 @@ SPAN_DECLARE_NONSTD(int) t31_tx(t31_state_t *s, int16_t amp[], int max_len)
if ((len = s->audio.modems.tx_handler(s->audio.modems.tx_user_data, amp, max_len)) < max_len)
{
/* Allow for one change of tx handler within a block */
- set_next_tx_type(s);
- if ((len += s->audio.modems.tx_handler(s->audio.modems.tx_user_data, amp + len, max_len - len)) < max_len)
+ fax_modems_set_next_tx_type(&s->audio.modems);
+ if ((len += s->audio.modems.tx_handler(s->audio.modems.tx_user_data, &[len], max_len - len)) < max_len)
front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE);
/*endif*/
}
@@ -2899,7 +2883,7 @@ SPAN_DECLARE_NONSTD(int) t31_tx(t31_state_t *s, int16_t amp[], int max_len)
if (s->audio.modems.transmit_on_idle)
{
/* Pad to the requested length with silence */
- memset(amp + len, 0, (max_len - len)*sizeof(int16_t));
+ memset(&[len], 0, (max_len - len)*sizeof(int16_t));
len = max_len;
}
/*endif*/
diff --git a/libs/spandsp/src/t38_gateway.c b/libs/spandsp/src/t38_gateway.c
index 77225cc63f..c41df87c75 100644
--- a/libs/spandsp/src/t38_gateway.c
+++ b/libs/spandsp/src/t38_gateway.c
@@ -2061,7 +2061,8 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_rx(t38_gateway_state_t *s, int16_t amp[], i
for (i = 0; i < len; i++)
amp[i] = dc_restore(&s->audio.modems.dc_restore, amp[i]);
/*endfor*/
- s->audio.modems.rx_handler(s->audio.modems.rx_user_data, amp, len);
+ if (s->audio.modems.rx_handler)
+ s->audio.modems.rx_handler(s->audio.modems.rx_user_data, amp, len);
return 0;
}
/*- End of function --------------------------------------------------------*/
@@ -2102,12 +2103,13 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_tx(t38_gateway_state_t *s, int16_t amp[], i
required_len = max_len;
#endif
+ len = 0;
if ((len = s->audio.modems.tx_handler(s->audio.modems.tx_user_data, amp, max_len)) < max_len)
{
if (set_next_tx_type(s))
{
/* Give the new handler a chance to file the remaining buffer space */
- len += s->audio.modems.tx_handler(s->audio.modems.tx_user_data, amp + len, max_len - len);
+ len += s->audio.modems.tx_handler(s->audio.modems.tx_user_data, &[len], max_len - len);
if (len < max_len)
{
silence_gen_set(&s->audio.modems.silence_gen, 0);
@@ -2121,7 +2123,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_tx(t38_gateway_state_t *s, int16_t amp[], i
if (s->audio.modems.transmit_on_idle)
{
/* Pad to the requested length with silence */
- memset(amp + len, 0, (max_len - len)*sizeof(int16_t));
+ memset(&[len], 0, (max_len - len)*sizeof(int16_t));
len = max_len;
}
/*endif*/
@@ -2129,7 +2131,7 @@ SPAN_DECLARE_NONSTD(int) t38_gateway_tx(t38_gateway_state_t *s, int16_t amp[], i
if (s->audio.modems.audio_tx_log >= 0)
{
if (len < required_len)
- memset(amp + len, 0, (required_len - len)*sizeof(int16_t));
+ memset(&[len], 0, (required_len - len)*sizeof(int16_t));
/*endif*/
write(s->audio.modems.audio_tx_log, amp, required_len*sizeof(int16_t));
}
diff --git a/libs/spandsp/tests/super_tone_tx_tests.c b/libs/spandsp/tests/super_tone_tx_tests.c
index 561b333c36..9f32ea6c78 100644
--- a/libs/spandsp/tests/super_tone_tx_tests.c
+++ b/libs/spandsp/tests/super_tone_tx_tests.c
@@ -41,7 +41,6 @@
#include
#include
#include
-#include
#include
#if defined(HAVE_LIBXML_XMLMEMORY_H)
diff --git a/src/fs_encode.c b/src/fs_encode.c
index 83b5484e5e..417ff7dc2f 100644
--- a/src/fs_encode.c
+++ b/src/fs_encode.c
@@ -129,7 +129,8 @@ int main(int argc, char *argv[])
}
switch_loadable_module_init(SWITCH_FALSE);
-
+ switch_loadable_module_load_module("", "CORE_PCM_MODULE", SWITCH_TRUE, &err);
+
for (i = 0; i < extra_modules_count; i++) {
if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) extra_modules[i], SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
fprintf(stderr, "Cannot init %s [%s]\n", extra_modules[i], err);
diff --git a/src/include/cc.h b/src/include/cc.h
index 965aa9cbac..d2635f3b1c 100644
--- a/src/include/cc.h
+++ b/src/include/cc.h
@@ -1,4 +1,4 @@
-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";
+const char *cc = ".=======================================================================================================.\n| ____ _ ____ |\n| / ___| |_ _ ___ / ___|___ _ __ |\n| | | | | | | |/ _ \\ | / _ \\| '_ \\ |\n| | |___| | |_| | __/ |__| (_) | | | | |\n| \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |\n| |\n| _____ _ _ ____ __ |\n| |_ _|__| | ___ _ __ | |__ ___ _ __ _ _ / ___|___ _ __ / _| ___ _ __ ___ _ __ ___ ___ |\n| | |/ _ \\ |/ _ \\ '_ \\| '_ \\ / _ \\| '_ \\| | | | | | / _ \\| '_ \\| |_ / _ \\ '__/ _ \\ '_ \\ / __/ _ \\ |\n| | | __/ | __/ |_) | | | | (_) | | | | |_| | | |__| (_) | | | | _| __/ | | __/ | | | (_| __/ |\n| |_|\\___|_|\\___| .__/|_| |_|\\___/|_| |_|\\__, | \\____\\___/|_| |_|_| \\___|_| \\___|_| |_|\\___\\___| |\n| |_| |___/ |\n| _____ _ _ |\n| | ____|_ _____ _ __ _ _ / \\ _ _ __ _ _ _ ___| |_ |\n| | _| \\ \\ / / _ \\ '__| | | | / _ \\| | | |/ _` | | | / __| __| |\n| | |___ \\ V / __/ | | |_| | / ___ \\ |_| | (_| | |_| \\__ \\ |_ |\n| |_____| \\_/ \\___|_| \\__, | /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| |\n| |___/ |___/ |\n| ____ _ ____ |\n| __ ____ ____ __ / ___| |_ _ ___ / ___|___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / | | | | | | |/ _ \\ | / _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | |___| | |_| | __/ |__| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\____|_|\\__,_|\\___|\\____\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.=======================================================================================================.\n";
const char *cc_s = ".===============================================================.\n| _ |\n| ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.===============================================================.\n";
diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h
index fffd51abac..f6d3474386 100644
--- a/src/include/private/switch_core_pvt.h
+++ b/src/include/private/switch_core_pvt.h
@@ -290,10 +290,14 @@ struct switch_session_manager {
switch_queue_t *thread_queue;
switch_thread_t *manager_thread;
switch_mutex_t *mutex;
+ switch_thread_cond_t *cond;
+ switch_mutex_t *cond_mutex;
+ switch_mutex_t *cond2_mutex;
int ready;
int running;
int busy;
int popping;
+ int starting;
};
extern struct switch_session_manager session_manager;
diff --git a/src/include/switch_core.h b/src/include/switch_core.h
index 8f02987281..064ab56324 100644
--- a/src/include/switch_core.h
+++ b/src/include/switch_core.h
@@ -1751,7 +1751,7 @@ SWITCH_DECLARE(void) switch_core_db_test_reactive(switch_core_db_t *db, char *te
SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, const char *func, int line,
_In_ switch_file_handle_t *fh,
_In_opt_z_ const char *file_path,
- _In_ uint8_t channels,
+ _In_ uint32_t channels,
_In_ uint32_t rate, _In_ unsigned int flags, _In_opt_ switch_memory_pool_t *pool);
/*!
diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h
index b4ea5a4bc8..b6f4f11554 100644
--- a/src/include/switch_module_interfaces.h
+++ b/src/include/switch_module_interfaces.h
@@ -310,7 +310,7 @@ struct switch_file_handle {
/*! the current native samplerate */
uint32_t native_rate;
/*! the number of channels */
- uint8_t channels;
+ uint32_t channels;
/*! integer representation of the format */
unsigned int format;
/*! integer representation of the sections */
@@ -353,6 +353,8 @@ struct switch_file_handle {
const char *prefix;
int max_samples;
switch_event_t *params;
+ uint32_t cur_channels;
+ uint32_t cur_samplerate;
};
/*! \brief Abstract interface to an asr module */
diff --git a/src/include/switch_types.h b/src/include/switch_types.h
index 9c86e56ae9..27a88dcc73 100644
--- a/src/include/switch_types.h
+++ b/src/include/switch_types.h
@@ -1041,7 +1041,9 @@ typedef enum {
SWITCH_STATUS_FOUND,
SWITCH_STATUS_CONTINUE,
SWITCH_STATUS_TERM,
- SWITCH_STATUS_NOT_INITALIZED
+ SWITCH_STATUS_NOT_INITALIZED,
+ SWITCH_STATUS_XBREAK = 35,
+ SWITCH_STATUS_WINBREAK = 730035
} switch_status_t;
@@ -1615,7 +1617,8 @@ typedef enum {
SWITCH_FILE_BUFFER_DONE = (1 << 14),
SWITCH_FILE_WRITE_APPEND = (1 << 15),
SWITCH_FILE_WRITE_OVER = (1 << 16),
- SWITCH_FILE_NOMUX = (1 << 17)
+ SWITCH_FILE_NOMUX = (1 << 17),
+ SWITCH_FILE_BREAK_ON_CHANGE = (1 << 18)
} switch_file_flag_enum_t;
typedef uint32_t switch_file_flag_t;
diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c
index 4e9e852aa9..3286cea05a 100644
--- a/src/mod/applications/mod_callcenter/mod_callcenter.c
+++ b/src/mod/applications/mod_callcenter/mod_callcenter.c
@@ -24,6 +24,7 @@
* Contributor(s):
*
* Marc Olivier Chouinard
+ * Emmanuel Schmidbauer
*
*
* mod_callcenter.c -- Call Center Module
@@ -1452,9 +1453,12 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_channel_process_export(member_channel, NULL, ovars, "cc_export_vars");
t_agent_called = local_epoch_time_now(NULL);
- dialstr = switch_mprintf("%s", h->originate_string);
+
+ dialstr = switch_channel_expand_variables(member_channel, h->originate_string);
status = switch_ivr_originate(NULL, &agent_session, &cause, dialstr, 60, NULL, cid_name ? cid_name : h->member_cid_name, h->member_cid_number, NULL, ovars, SOF_NONE, NULL);
- switch_safe_free(dialstr);
+ if (dialstr != h->originate_string) {
+ switch_safe_free(dialstr);
+ }
switch_safe_free(cid_name);
switch_event_destroy(&ovars);
diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c
index 2b7804dd31..97ec23f9c9 100644
--- a/src/mod/applications/mod_commands/mod_commands.c
+++ b/src/mod/applications/mod_commands/mod_commands.c
@@ -1329,6 +1329,8 @@ SWITCH_STANDARD_API(stun_function)
switch_port_t port = 0;
switch_memory_pool_t *pool = NULL;
char *error = "";
+ char *argv[3] = { 0 };
+ char *mycmd = NULL;
ip = ip_buf;
@@ -1337,9 +1339,15 @@ SWITCH_STANDARD_API(stun_function)
return SWITCH_STATUS_SUCCESS;
}
- stun_ip = strdup(cmd);
+ mycmd = strdup(cmd);
+ switch_split(mycmd, ' ', argv);
+
+ stun_ip = argv[0];
+
switch_assert(stun_ip);
+ port = argv[1] ? atoi(argv[1]) : 0;
+
if ((p = strchr(stun_ip, ':'))) {
int iport;
*p++ = '\0';
@@ -1374,7 +1382,7 @@ SWITCH_STANDARD_API(stun_function)
}
switch_core_destroy_memory_pool(&pool);
- free(stun_ip);
+ switch_safe_free(mycmd);
return SWITCH_STATUS_SUCCESS;
}
@@ -4608,7 +4616,6 @@ SWITCH_STANDARD_API(show_function)
char *command = NULL, *as = NULL;
switch_core_flag_t cflags = switch_core_flags();
switch_status_t status = SWITCH_STATUS_SUCCESS;
- const char *hostname = switch_core_get_switchname();
int html = 0;
char *nl = "\n";
stream_format format = { 0 };
@@ -4661,33 +4668,33 @@ SWITCH_STANDARD_API(show_function)
if (end_of(command) == 's') {
end_of(command) = '\0';
}
- sprintf(sql, "select type, name, ikey from interfaces where hostname='%s' and type = '%s' order by type,name", hostname, command);
+ sprintf(sql, "select type, name, ikey from interfaces where hostname='%s' and type = '%s' order by type,name", switch_core_get_hostname(), command);
} else if (!strncasecmp(command, "module", 6)) {
if (argv[1] && strcasecmp(argv[1], "as")) {
sprintf(sql, "select distinct type, name, ikey, filename from interfaces where hostname='%s' and ikey = '%s' order by type,name",
- hostname, argv[1]);
+ switch_core_get_hostname(), argv[1]);
} else {
- sprintf(sql, "select distinct type, name, ikey, filename from interfaces where hostname='%s' order by type,name", hostname);
+ sprintf(sql, "select distinct type, name, ikey, filename from interfaces where hostname='%s' order by type,name", switch_core_get_hostname());
}
} else if (!strcasecmp(command, "interfaces")) {
- sprintf(sql, "select type, name, ikey from interfaces where hostname='%s' order by type,name", hostname);
+ sprintf(sql, "select type, name, ikey from interfaces where hostname='%s' order by type,name", switch_core_get_hostname());
} else if (!strcasecmp(command, "interface_types")) {
- sprintf(sql, "select type,count(type) as total from interfaces where hostname='%s' group by type order by type", hostname);
+ sprintf(sql, "select type,count(type) as total from interfaces where hostname='%s' group by type order by type", switch_core_get_switchname());
} else if (!strcasecmp(command, "tasks")) {
- sprintf(sql, "select * from %s where hostname='%s'", command, hostname);
+ sprintf(sql, "select * from %s where hostname='%s'", command, switch_core_get_hostname());
} else if (!strcasecmp(command, "application") || !strcasecmp(command, "api")) {
if (argv[1] && strcasecmp(argv[1], "as")) {
sprintf(sql,
"select name, description, syntax, ikey from interfaces where hostname='%s' and type = '%s' and description != '' and name = '%s' order by type,name",
- hostname, command, argv[1]);
+ switch_core_get_hostname(), command, argv[1]);
} else {
- sprintf(sql, "select name, description, syntax, ikey from interfaces where hostname='%s' and type = '%s' and description != '' order by type,name", hostname, command);
+ sprintf(sql, "select name, description, syntax, ikey from interfaces where hostname='%s' and type = '%s' and description != '' order by type,name", switch_core_get_hostname(), command);
}
/* moved refreshable webpage show commands i.e. show calls|registrations|channels||detailed_calls|bridged_calls|detailed_bridged_calls */
} else if (!strcasecmp(command, "aliases")) {
- sprintf(sql, "select * from aliases where hostname='%s' order by alias", hostname);
+ sprintf(sql, "select * from aliases where hostname='%s' order by alias", switch_core_get_switchname());
} else if (!strcasecmp(command, "complete")) {
- sprintf(sql, "select * from complete where hostname='%s' order by a1,a2,a3,a4,a5,a6,a7,a8,a9,a10", hostname);
+ sprintf(sql, "select * from complete where hostname='%s' order by a1,a2,a3,a4,a5,a6,a7,a8,a9,a10", switch_core_get_switchname());
} else if (!strncasecmp(command, "help", 4)) {
char *cmdname = NULL;
@@ -4697,9 +4704,9 @@ SWITCH_STANDARD_API(show_function)
*cmdname++ = '\0';
switch_snprintfv(sql, sizeof(sql),
"select name, syntax, description, ikey from interfaces where hostname='%s' and type = 'api' and name = '%q' order by name",
- hostname, cmdname);
+ switch_core_get_hostname(), cmdname);
} else {
- switch_snprintfv(sql, sizeof(sql), "select name, syntax, description, ikey from interfaces where hostname='%q' and type = 'api' order by name", hostname);
+ switch_snprintfv(sql, sizeof(sql), "select name, syntax, description, ikey from interfaces where hostname='%q' and type = 'api' order by name", switch_core_get_hostname());
}
} else if (!strcasecmp(command, "nat_map")) {
switch_snprintf(sql, sizeof(sql) - 1,
@@ -4707,7 +4714,7 @@ SWITCH_STANDARD_API(show_function)
" CASE proto "
" WHEN 0 THEN 'udp' "
" WHEN 1 THEN 'tcp' "
- " ELSE 'unknown' " " END AS proto, " " proto AS proto_num, " " sticky " " FROM nat where hostname='%s' ORDER BY port, proto", hostname);
+ " ELSE 'unknown' " " END AS proto, " " proto AS proto_num, " " sticky " " FROM nat where hostname='%s' ORDER BY port, proto", switch_core_get_hostname());
} else {
/* from here on refreshable commands: calls|registrations|channels||detailed_calls|bridged_calls|detailed_bridged_calls */
if (holder.format->api) {
@@ -4726,18 +4733,18 @@ SWITCH_STANDARD_API(show_function)
}
if (!strcasecmp(command, "calls")) {
- sprintf(sql, "select * from basic_calls where hostname='%s' order by call_created_epoch", hostname);
+ sprintf(sql, "select * from basic_calls where hostname='%s' order by call_created_epoch", switch_core_get_switchname());
if (argv[1] && !strcasecmp(argv[1], "count")) {
- sprintf(sql, "select count(*) from basic_calls where hostname='%s'", hostname);
+ sprintf(sql, "select count(*) from basic_calls where hostname='%s'", switch_core_get_switchname());
holder.justcount = 1;
if (argv[3] && !strcasecmp(argv[2], "as")) {
as = argv[3];
}
}
} else if (!strcasecmp(command, "registrations")) {
- sprintf(sql, "select * from registrations where hostname='%s'", hostname);
+ sprintf(sql, "select * from registrations where hostname='%s'", switch_core_get_switchname());
if (argv[1] && !strcasecmp(argv[1], "count")) {
- sprintf(sql, "select count(*) from registrations where hostname='%s'", hostname);
+ sprintf(sql, "select count(*) from registrations where hostname='%s'", switch_core_get_switchname());
holder.justcount = 1;
if (argv[3] && !strcasecmp(argv[2], "as")) {
as = argv[3];
@@ -4754,39 +4761,39 @@ SWITCH_STANDARD_API(show_function)
if (strchr(argv[2], '%')) {
sprintf(sql,
"select * from channels where hostname='%s' and uuid like '%s' or name like '%s' or cid_name like '%s' or cid_num like '%s' or presence_data like '%s' order by created_epoch",
- hostname, argv[2], argv[2], argv[2], argv[2], argv[2]);
+ switch_core_get_switchname(), argv[2], argv[2], argv[2], argv[2], argv[2]);
} else {
sprintf(sql,
"select * from channels where hostname='%s' and uuid like '%%%s%%' or name like '%%%s%%' or cid_name like '%%%s%%' or cid_num like '%%%s%%' or presence_data like '%%%s%%' order by created_epoch",
- hostname, argv[2], argv[2], argv[2], argv[2], argv[2]);
+ switch_core_get_switchname(), argv[2], argv[2], argv[2], argv[2], argv[2]);
}
if (argv[4] && !strcasecmp(argv[3], "as")) {
as = argv[4];
}
} else {
- sprintf(sql, "select * from channels where hostname='%s' order by created_epoch", hostname);
+ sprintf(sql, "select * from channels where hostname='%s' order by created_epoch", switch_core_get_switchname());
}
} else if (!strcasecmp(command, "channels")) {
- sprintf(sql, "select * from channels where hostname='%s' order by created_epoch", hostname);
+ sprintf(sql, "select * from channels where hostname='%s' order by created_epoch", switch_core_get_switchname());
if (argv[1] && !strcasecmp(argv[1], "count")) {
- sprintf(sql, "select count(*) from channels where hostname='%s'", hostname);
+ sprintf(sql, "select count(*) from channels where hostname='%s'", switch_core_get_switchname());
holder.justcount = 1;
if (argv[3] && !strcasecmp(argv[2], "as")) {
as = argv[3];
}
}
} else if (!strcasecmp(command, "detailed_calls")) {
- sprintf(sql, "select * from detailed_calls where hostname='%s' order by created_epoch", hostname);
+ sprintf(sql, "select * from detailed_calls where hostname='%s' order by created_epoch", switch_core_get_switchname());
if (argv[2] && !strcasecmp(argv[1], "as")) {
as = argv[2];
}
} else if (!strcasecmp(command, "bridged_calls")) {
- sprintf(sql, "select * from basic_calls where b_uuid is not null and hostname='%s' order by created_epoch", hostname);
+ sprintf(sql, "select * from basic_calls where b_uuid is not null and hostname='%s' order by created_epoch", switch_core_get_switchname());
if (argv[2] && !strcasecmp(argv[1], "as")) {
as = argv[2];
}
} else if (!strcasecmp(command, "detailed_bridged_calls")) {
- sprintf(sql, "select * from detailed_calls where b_uuid is not null and hostname='%s' order by created_epoch", hostname);
+ sprintf(sql, "select * from detailed_calls where b_uuid is not null and hostname='%s' order by created_epoch", switch_core_get_switchname());
if (argv[2] && !strcasecmp(argv[1], "as")) {
as = argv[2];
}
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index 111e4ef917..db38e5c7eb 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -286,6 +286,17 @@ struct vid_helper {
int up;
};
+struct conference_obj;
+
+/* Record Node */
+typedef struct conference_record {
+ struct conference_obj *conference;
+ char *path;
+ switch_memory_pool_t *pool;
+ switch_bool_t autorec;
+ struct conference_record *next;
+} conference_record_t;
+
/* Conference Object */
typedef struct conference_obj {
char *name;
@@ -352,7 +363,7 @@ typedef struct conference_obj {
int pin_retries;
int broadcast_chat_messages;
int comfort_noise_level;
- int is_recording;
+ int auto_recording;
int record_count;
int video_running;
int ivr_dtmf_timeout;
@@ -385,6 +396,7 @@ typedef struct conference_obj {
cdr_event_mode_t cdr_event_mode;
struct vid_helper vh[2];
struct vid_helper mh;
+ conference_record_t *rec_node_head;
} conference_obj_t;
/* Relationship with another member */
@@ -421,6 +433,7 @@ struct conference_member {
switch_codec_t write_codec;
char *rec_path;
switch_time_t rec_time;
+ conference_record_t *rec;
uint8_t *frame;
uint8_t *last_frame;
uint32_t frame_size;
@@ -455,13 +468,6 @@ struct conference_member {
switch_thread_t *input_thread;
};
-/* Record Node */
-typedef struct conference_record {
- conference_obj_t *conference;
- char *path;
- switch_memory_pool_t *pool;
-} conference_record_t;
-
typedef enum {
CONF_API_SUB_ARGS_SPLIT,
CONF_API_SUB_MEMBER_TARGET,
@@ -529,7 +535,7 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c
static switch_status_t chat_send(switch_event_t *message_event);
-static void launch_conference_record_thread(conference_obj_t *conference, char *path);
+static void launch_conference_record_thread(conference_obj_t *conference, char *path, switch_bool_t autorec);
static int launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b);
typedef switch_status_t (*conf_api_args_cmd_t) (conference_obj_t *, switch_stream_handle_t *, int, char **);
@@ -547,7 +553,6 @@ static switch_status_t conference_add_event_member_data(conference_member_t *mem
static switch_status_t conf_api_sub_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data);
static switch_status_t conf_api_sub_vid_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data);
static switch_status_t conf_api_sub_clear_vid_floor(conference_obj_t *conference, switch_stream_handle_t *stream, void *data);
-static switch_status_t conf_api_sub_enforce_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data);
#define lock_member(_member) switch_mutex_lock(_member->write_mutex); switch_mutex_lock(_member->read_mutex)
@@ -1217,7 +1222,7 @@ static conference_member_t *conference_member_get(conference_obj_t *conference,
}
/* stop the specified recording */
-static switch_status_t conference_record_stop(conference_obj_t *conference, char *path)
+static switch_status_t conference_record_stop(conference_obj_t *conference, switch_stream_handle_t *stream, char *path)
{
conference_member_t *member = NULL;
int count = 0;
@@ -1226,10 +1231,21 @@ static switch_status_t conference_record_stop(conference_obj_t *conference, char
switch_mutex_lock(conference->member_mutex);
for (member = conference->members; member; member = member->next) {
if (switch_test_flag(member, MFLAG_NOCHANNEL) && (!path || !strcmp(path, member->rec_path))) {
+ if (member->rec && member->rec->autorec) {
+ stream->write_function(stream, "Stopped AUTO recording file %s (Auto Recording Now Disabled)\n", member->rec_path);
+ conference->auto_record = 0;
+ } else {
+ stream->write_function(stream, "Stopped recording file %s\n", member->rec_path);
+ }
+
switch_clear_flag_locked(member, MFLAG_RUNNING);
count++;
+
}
}
+
+ conference->record_count -= count;
+
switch_mutex_unlock(conference->member_mutex);
return count;
}
@@ -2067,7 +2083,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
globals.threads++;
switch_mutex_unlock(globals.hash_mutex);
- conference->is_recording = 0;
+ conference->auto_recording = 0;
conference->record_count = 0;
@@ -2169,15 +2185,15 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
}
/* Start recording if there's more than one participant. */
- if (conference->auto_record && !conference->is_recording && conference->count > 1) {
- conference->is_recording = 1;
+ if (conference->auto_record && !conference->auto_recording && conference->count > 1) {
+ conference->auto_recording++;
conference->record_count++;
imember = conference->members;
if (imember) {
switch_channel_t *channel = switch_core_session_get_channel(imember->session);
char *rfile = switch_channel_expand_variables(channel, conference->auto_record);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Auto recording file: %s\n", rfile);
- launch_conference_record_thread(conference, rfile);
+ launch_conference_record_thread(conference, rfile, SWITCH_TRUE);
if (rfile != conference->auto_record) {
conference->record_filename = switch_core_strdup(conference->pool, rfile);
switch_safe_free(rfile);
@@ -2607,13 +2623,6 @@ static void conference_loop_fn_vid_floor_force(conference_member_t *member, call
conf_api_sub_vid_floor(member, NULL, "force");
}
-static void conference_loop_fn_enforce_floor(conference_member_t *member, caller_control_action_t *action)
-{
- if (member == NULL) return;
-
- conf_api_sub_enforce_floor(member, NULL, NULL);
-}
-
static void conference_loop_fn_mute_toggle(conference_member_t *member, caller_control_action_t *action)
{
if (member == NULL)
@@ -3185,7 +3194,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
- return NULL;
+ goto end;
}
switch_assert(member != NULL);
@@ -3482,10 +3491,12 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
switch_resample_destroy(&member->read_resampler);
- switch_clear_flag_locked(member, MFLAG_ITHREAD);
-
switch_core_session_rwunlock(session);
+ end:
+
+ switch_clear_flag_locked(member, MFLAG_ITHREAD);
+
return NULL;
}
@@ -3583,7 +3594,9 @@ static void launch_conference_loop_input(conference_member_t *member, switch_mem
switch_threadattr_create(&thd_attr, pool);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_set_flag_locked(member, MFLAG_ITHREAD);
- switch_thread_create(&member->input_thread, thd_attr, conference_loop_input, member, pool);
+ if (switch_thread_create(&member->input_thread, thd_attr, conference_loop_input, member, pool) != SWITCH_STATUS_SUCCESS) {
+ switch_clear_flag_locked(member, MFLAG_ITHREAD);
+ }
}
/* marshall frames from the conference (or file or tts output) to the call leg */
@@ -3919,6 +3932,7 @@ static void conference_loop_output(conference_member_t *member)
switch_clear_flag_locked(member, MFLAG_RUNNING);
+ /* Wait for the input thread to end */
if (member->input_thread) {
switch_thread_join(&st, member->input_thread);
}
@@ -3932,11 +3946,6 @@ static void conference_loop_output(conference_member_t *member)
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
member->conference->bridge_hangup_cause = switch_channel_get_cause(channel);
}
-
- /* Wait for the input thread to end */
- while (switch_test_flag(member, MFLAG_ITHREAD)) {
- switch_cond_next();
- }
}
/* Sub-Routine called by a record entity inside a conference */
@@ -3945,7 +3954,7 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th
int16_t *data_buf;
switch_file_handle_t fh = { 0 };
conference_member_t smember = { 0 }, *member;
- conference_record_t *rec = (conference_record_t *) obj;
+ conference_record_t *rp, *last = NULL, *rec = (conference_record_t *) obj;
conference_obj_t *conference = rec->conference;
uint32_t samples = switch_samples_per_packet(conference->rate, conference->interval);
uint32_t mux_used;
@@ -3983,7 +3992,7 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th
fh.samplerate = conference->rate;
member->id = next_member_id();
member->pool = rec->pool;
-
+ member->rec = rec;
member->frame_size = SWITCH_RECOMMENDED_BUFFER_SIZE;
member->frame = switch_core_alloc(member->pool, member->frame_size);
member->mux_frame = switch_core_alloc(member->pool, member->frame_size);
@@ -4126,8 +4135,6 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th
switch_mutex_unlock(member->audio_out_mutex);
}
- conference->is_recording = 0;
-
switch_safe_free(data_buf);
switch_core_timer_destroy(&timer);
conference_del_member(conference, member);
@@ -4146,6 +4153,23 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th
switch_event_fire(&event);
}
+ if (rec->autorec && conference->auto_recording) {
+ conference->auto_recording--;
+ }
+
+ switch_mutex_lock(conference->flag_mutex);
+ for (rp = conference->rec_node_head; rp; rp = rp->next) {
+ if (rec == rp) {
+ if (last) {
+ last->next = rp->next;
+ } else {
+ conference->rec_node_head = rp->next;
+ }
+ }
+ }
+ switch_mutex_unlock(conference->flag_mutex);
+
+
if (rec->pool) {
switch_memory_pool_t *pool = rec->pool;
rec = NULL;
@@ -5390,26 +5414,6 @@ static switch_status_t conf_api_sub_vid_floor(conference_member_t *member, switc
return SWITCH_STATUS_SUCCESS;
}
-static switch_status_t conf_api_sub_enforce_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data)
-{
- if (member == NULL)
- return SWITCH_STATUS_GENERR;
-
- switch_mutex_lock(member->conference->mutex);
-
- if (member->conference->floor_holder != member) {
- conference_set_floor_holder(member->conference, member);
-
- if (stream != NULL) {
- stream->write_function(stream, "OK floor %u\n", member->id);
- }
- }
-
- switch_mutex_unlock(member->conference->mutex);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
static switch_xml_t add_x_tag(switch_xml_t x_member, const char *name, const char *value, int off)
{
switch_size_t dlen;
@@ -6278,11 +6282,20 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc
static switch_status_t conf_api_sub_check_record(conference_obj_t *conference, switch_stream_handle_t *stream, int arc, char **argv)
{
- if (conference->is_recording) {
- stream->write_function(stream, "Record file %s\n", conference->record_filename);
- } else {
+ conference_record_t *rec;
+ int x = 0;
+
+ switch_mutex_lock(conference->flag_mutex);
+ for (rec = conference->rec_node_head; rec; rec = rec->next) {
+ stream->write_function(stream, "Record file %s%s%s\n", rec->path, rec->autorec ? " " : "", rec->autorec ? "(Auto)" : "");
+ x++;
+ }
+
+ if (!x) {
stream->write_function(stream, "Conference is not being recorded.\n");
}
+ switch_mutex_unlock(conference->flag_mutex);
+
return SWITCH_STATUS_SUCCESS;
}
@@ -6291,19 +6304,20 @@ static switch_status_t conf_api_sub_record(conference_obj_t *conference, switch_
switch_assert(conference != NULL);
switch_assert(stream != NULL);
- if (argc <= 2)
+ if (argc <= 2) {
return SWITCH_STATUS_GENERR;
+ }
stream->write_function(stream, "Record file %s\n", argv[2]);
conference->record_filename = switch_core_strdup(conference->pool, argv[2]);
conference->record_count++;
- launch_conference_record_thread(conference, argv[2]);
+ launch_conference_record_thread(conference, argv[2], SWITCH_FALSE);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t conf_api_sub_norecord(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
{
- int all;
+ int all, before = conference->record_count, ttl = 0;
switch_event_t *event;
switch_assert(conference != NULL);
@@ -6313,15 +6327,10 @@ static switch_status_t conf_api_sub_norecord(conference_obj_t *conference, switc
return SWITCH_STATUS_GENERR;
all = (strcasecmp(argv[2], "all") == 0);
- stream->write_function(stream, "Stop recording file %s\n", argv[2]);
- if (!conference_record_stop(conference, all ? NULL : argv[2]) && !all) {
+
+ if (!conference_record_stop(conference, stream, all ? NULL : argv[2]) && !all) {
stream->write_function(stream, "non-existant recording '%s'\n", argv[2]);
} else {
- if (all) {
- conference->record_count = 0;
- } else {
- conference->record_count--;
- }
if (test_eflag(conference, EFLAG_RECORD) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_add_event_data(conference, event);
@@ -6332,6 +6341,9 @@ static switch_status_t conf_api_sub_norecord(conference_obj_t *conference, switc
}
}
+ ttl = before - conference->record_count;
+ stream->write_function(stream, "Stopped recording %d file%s\n", ttl, ttl == 1 ? "" : "s");
+
return SWITCH_STATUS_SUCCESS;
}
@@ -6383,6 +6395,13 @@ static switch_status_t conf_api_sub_recording(conference_obj_t *conference, swit
switch_assert(conference != NULL);
switch_assert(stream != NULL);
+ if (argc > 2 && argc <= 3) {
+ if (strcasecmp(argv[2], "stop") == 0 || strcasecmp(argv[2], "check") == 0) {
+ argv[3] = "all";
+ argc++;
+ }
+ }
+
if (argc <= 3) {
/* It means that old syntax is used */
return conf_api_sub_record(conference,stream,argc,argv);
@@ -6604,8 +6623,7 @@ static api_command_t conf_api_sub_commands[] = {
{"set", (void_fn_t) & conf_api_sub_set, CONF_API_SUB_ARGS_SPLIT, "set", " "},
{"floor", (void_fn_t) & conf_api_sub_floor, CONF_API_SUB_MEMBER_TARGET, "floor", ""},
{"vid-floor", (void_fn_t) & conf_api_sub_vid_floor, CONF_API_SUB_MEMBER_TARGET, "vid-floor", " [force]"},
- {"clear-vid-floor", (void_fn_t) & conf_api_sub_clear_vid_floor, CONF_API_SUB_ARGS_AS_ONE, "clear-vid-floor", ""},
- {"enforce_floor", (void_fn_t) & conf_api_sub_enforce_floor, CONF_API_SUB_MEMBER_TARGET, "enforce_floor", ""},
+ {"clear-vid-floor", (void_fn_t) & conf_api_sub_clear_vid_floor, CONF_API_SUB_ARGS_AS_ONE, "clear-vid-floor", ""}
};
#define CONFFUNCAPISIZE (sizeof(conf_api_sub_commands)/sizeof(conf_api_sub_commands[0]))
@@ -8117,9 +8135,7 @@ static int launch_conference_video_bridge_thread(conference_member_t *member_a,
}
-
-
-static void launch_conference_record_thread(conference_obj_t *conference, char *path)
+static void launch_conference_record_thread(conference_obj_t *conference, char *path, switch_bool_t autorec)
{
switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL;
@@ -8138,11 +8154,15 @@ static void launch_conference_record_thread(conference_obj_t *conference, char *
return;
}
- conference->is_recording = 1;
-
rec->conference = conference;
rec->path = switch_core_strdup(pool, path);
rec->pool = pool;
+ rec->autorec = autorec;
+
+ switch_mutex_lock(conference->flag_mutex);
+ rec->next = conference->rec_node_head;
+ conference->rec_node_head = rec;
+ switch_mutex_unlock(conference->flag_mutex);
switch_threadattr_create(&thd_attr, rec->pool);
switch_threadattr_detach_set(thd_attr, 1);
@@ -9189,8 +9209,7 @@ static struct _mapping control_mappings[] = {
{"execute_application", conference_loop_fn_exec_app},
{"floor", conference_loop_fn_floor_toggle},
{"vid-floor", conference_loop_fn_vid_floor_toggle},
- {"vid-floor-force", conference_loop_fn_vid_floor_force},
- {"enforce_floor", conference_loop_fn_enforce_floor},
+ {"vid-floor-force", conference_loop_fn_vid_floor_force}
};
#define MAPPING_LEN (sizeof(control_mappings)/sizeof(control_mappings[0]))
diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c
index a05f880a4a..5fe2c57e5b 100755
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@ -283,10 +283,17 @@ SWITCH_STANDARD_APP(clear_digit_action_function)
{
//switch_channel_t *channel = switch_core_session_get_channel(session);
switch_ivr_dmachine_t *dmachine;
- char *realm = switch_core_session_strdup(session, data);
+ char *realm = NULL;
char *target_str;
switch_digit_action_target_t target = DIGIT_TARGET_SELF;
+ if (zstr(realm)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "clear_digit_action called with no args");
+ return;
+ }
+
+ realm = switch_core_session_strdup(session, data);
+
if ((target_str = strchr(realm, ','))) {
*target_str++ = '\0';
target = str2target(target_str);
@@ -2538,8 +2545,8 @@ SWITCH_STANDARD_APP(play_and_get_digits_function)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Transfer on failure = [%s].\n", transfer_on_failure);
}
- if (min_digits <= 1) {
- min_digits = 1;
+ if (min_digits <= 0) {
+ min_digits = 0;
}
if (max_digits < min_digits) {
@@ -4509,8 +4516,8 @@ static switch_status_t next_file(switch_file_handle_t *handle)
}
handle->samples = context->fh.samples;
- //handle->samplerate = context->fh.samplerate;
- //handle->channels = context->fh.channels;
+ handle->cur_samplerate = context->fh.samplerate;
+ handle->cur_channels = context->fh.channels;
handle->format = context->fh.format;
handle->sections = context->fh.sections;
handle->seekable = context->fh.seekable;
@@ -4518,6 +4525,7 @@ static switch_status_t next_file(switch_file_handle_t *handle)
handle->interval = context->fh.interval;
handle->max_samples = 0;
+
if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) {
switch_set_flag(handle, SWITCH_FILE_NATIVE);
} else {
@@ -4602,13 +4610,19 @@ static switch_status_t file_string_file_read(switch_file_handle_t *handle, void
if ((status = next_file(handle)) != SWITCH_STATUS_SUCCESS) {
return status;
}
- *len = llen;
- status = switch_core_file_read(&context->fh, data, len);
+ if (switch_test_flag(handle, SWITCH_FILE_BREAK_ON_CHANGE)) {
+ *len = 0;
+ status = SWITCH_STATUS_BREAK;
+ } else {
+ *len = llen;
+ status = switch_core_file_read(&context->fh, data, len);
+ }
}
return status;
}
+
static switch_status_t file_string_file_write(switch_file_handle_t *handle, void *data, size_t *len)
{
file_string_context_t *context = handle->private_info;
@@ -4627,10 +4641,101 @@ static switch_status_t file_string_file_write(switch_file_handle_t *handle, void
return status;
}
+static switch_status_t file_url_file_seek(switch_file_handle_t *handle, unsigned int *cur_sample, int64_t samples, int whence)
+{
+ switch_file_handle_t *fh = handle->private_info;
+ return switch_core_file_seek(fh, cur_sample, samples, whence);
+}
+
+static switch_status_t file_url_file_close(switch_file_handle_t *handle)
+{
+ switch_file_handle_t *fh = handle->private_info;
+ if (switch_test_flag(fh, SWITCH_FILE_OPEN)) {
+ switch_core_file_close(fh);
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t file_url_file_read(switch_file_handle_t *handle, void *data, size_t *len)
+{
+ switch_file_handle_t *fh = handle->private_info;
+ return switch_core_file_read(fh, data, len);
+}
+
+static switch_status_t file_url_file_open(switch_file_handle_t *handle, const char *path)
+{
+ switch_file_handle_t *fh = switch_core_alloc(handle->memory_pool, sizeof(*fh));
+ switch_status_t status;
+ char *url_host;
+ char *url_path;
+
+ if (zstr(path)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NULL path\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
+ /* parse and check host */
+ url_host = switch_core_strdup(handle->memory_pool, path);
+ if (!(url_path = strchr(url_host, '/'))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing path\n");
+ return SWITCH_STATUS_FALSE;
+ }
+ *url_path = '\0';
+ /* TODO allow this host */
+ if (!zstr(url_host) && strcasecmp(url_host, "localhost")) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not localhost\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
+ /* decode and check path */
+ url_path++;
+ if (zstr(url_path)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "empty path\n");
+ return SWITCH_STATUS_FALSE;
+ }
+ if (strstr(url_path, "%2f") || strstr(url_path, "%2F")) {
+ /* don't allow %2f or %2F encoding (/) */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "encoded slash is not allowed\n");
+ return SWITCH_STATUS_FALSE;
+ }
+ url_path = switch_core_sprintf(handle->memory_pool, "/%s", url_path);
+ switch_url_decode(url_path);
+
+ /* TODO convert to native file separators? */
+
+ handle->private_info = fh;
+ status = switch_core_file_open(fh, url_path, handle->channels, handle->samplerate, handle->flags, NULL);
+ if (status == SWITCH_STATUS_SUCCESS) {
+ handle->samples = fh->samples;
+ handle->cur_samplerate = fh->samplerate;
+ handle->cur_channels = fh->channels;
+ handle->format = fh->format;
+ handle->sections = fh->sections;
+ handle->seekable = fh->seekable;
+ handle->speed = fh->speed;
+ handle->interval = fh->interval;
+ handle->max_samples = 0;
+
+ if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
+ switch_set_flag(handle, SWITCH_FILE_NATIVE);
+ } else {
+ switch_clear_flag(handle, SWITCH_FILE_NATIVE);
+ }
+ }
+ return status;
+}
+
+static switch_status_t file_url_file_write(switch_file_handle_t *handle, void *data, size_t *len)
+{
+ switch_file_handle_t *fh = handle->private_info;
+ return switch_core_file_write(fh, data, len);
+}
/* Registration */
static char *file_string_supported_formats[SWITCH_MAX_CODECS] = { 0 };
+static char *file_url_supported_formats[SWITCH_MAX_CODECS] = { 0 };
/* /FILE STRING INTERFACE */
@@ -5498,6 +5603,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
file_interface->file_write = file_string_file_write;
file_interface->file_seek = file_string_file_seek;
+ file_url_supported_formats[0] = "file";
+
+ file_interface = (switch_file_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
+ file_interface->interface_name = modname;
+ file_interface->extens = file_url_supported_formats;
+ file_interface->file_open = file_url_file_open;
+ file_interface->file_close = file_url_file_close;
+ file_interface->file_read = file_url_file_read;
+ file_interface->file_write = file_url_file_write;
+ file_interface->file_seek = file_url_file_seek;
+
error_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
error_endpoint_interface->interface_name = "error";
@@ -5652,7 +5768,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "unbind_meta_app", "Unbind a key from an application", "Unbind a key from an application", dtmf_unbind_function,
UNBIND_SYNTAX, SAF_SUPPORT_NOMEDIA);
- SWITCH_ADD_APP(app_interface, "block_dfmf", "Block DTMF", "Block DTMF", dtmf_block_function, "", SAF_SUPPORT_NOMEDIA);
+ SWITCH_ADD_APP(app_interface, "block_dtmf", "Block DTMF", "Block DTMF", dtmf_block_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "unblock_dtmf", "Stop blocking DTMF", "Stop blocking DTMF", dtmf_unblock_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "intercept", "intercept", "intercept", intercept_function, INTERCEPT_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "eavesdrop", "eavesdrop on a uuid", "eavesdrop on a uuid", eavesdrop_function, eavesdrop_SYNTAX, SAF_MEDIA_TAP);
diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c
index 1affefa3e4..886930f096 100644
--- a/src/mod/applications/mod_fifo/mod_fifo.c
+++ b/src/mod/applications/mod_fifo/mod_fifo.c
@@ -1366,7 +1366,11 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void
if (!switch_event_get_header(ovars, "origination_caller_id_name")) {
if ((caller_id_name = switch_event_get_header(pop, "caller-caller-id-name"))) {
if (!zstr(node->outbound_name)) {
- switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "origination_caller_id_name", "(%s) %s", node->outbound_name, caller_id_name);
+ if ( node->outbound_name[0] == '=' ) {
+ switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "origination_caller_id_name", "%s", node->outbound_name + 1);
+ } else {
+ switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "origination_caller_id_name", "(%s) %s", node->outbound_name, caller_id_name);
+ }
} else {
switch_event_add_header_string(ovars, SWITCH_STACK_BOTTOM, "origination_caller_id_name", caller_id_name);
}
diff --git a/src/mod/applications/mod_sonar/mod_sonar.c b/src/mod/applications/mod_sonar/mod_sonar.c
index 4453deea90..446319b2a8 100644
--- a/src/mod/applications/mod_sonar/mod_sonar.c
+++ b/src/mod/applications/mod_sonar/mod_sonar.c
@@ -24,6 +24,7 @@
* Contributor(s):
*
* William King
+ * Seven Du
*
* mod_sonar.c -- Sonar ping timer
*
@@ -40,6 +41,14 @@
#include
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
/* Prototypes */
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sonar_shutdown);
SWITCH_MODULE_RUNTIME_FUNCTION(mod_sonar_runtime);
@@ -50,18 +59,38 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sonar_load);
*/
SWITCH_MODULE_DEFINITION(mod_sonar, mod_sonar_load, mod_sonar_shutdown, NULL);
-switch_time_t start, end, diff;
+
+struct sonar_ping_helper_s {
+ switch_time_t start, end, diff;
+ int samples[1024];
+ int received;
+ int sum, min, max;
+};
+
+typedef struct sonar_ping_helper_s sonar_ping_helper_t;
switch_bool_t sonar_ping_callback(switch_core_session_t *session, const char *app, const char *app_data){
-
- if ( end ) {
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ sonar_ping_helper_t *ph = switch_channel_get_private(channel, "__sonar_ping__");
+ int diff;
+
+ if (!ph) return SWITCH_TRUE;
+
+ if ( ph->end ) {
return SWITCH_TRUE;
}
-
- end = switch_time_now();
- diff = end - start;
- start = 0;
+
+ ph->end = switch_time_now();
+ diff = ph->end - ph->start;
+
+ ph->start = 0;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Sonar ping took %ld milliseconds\n", (long)diff / 1000);
+
+ diff /= 1000;
+ ph->sum += diff;
+ ph->max = MAX(ph->max, diff);
+ ph->min = MIN(ph->min, diff);
+ ph->samples[ph->received++] = diff;
return SWITCH_TRUE;
}
@@ -70,15 +99,31 @@ SWITCH_STANDARD_APP(sonar_app)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
char *tone = "%(500,0,1004)";
- int loops = atoi(data);
-
- if ( ! loops ) {
+ const char *arg = (char *) data;
+ int loops;
+ int lost = 0;
+ int x;
+ int avg = 0, sdev = 0, mdev = 0;
+ int sum2;
+ switch_event_t *event;
+ sonar_ping_helper_t ph = { 0 };
+
+ if (zstr(arg)) {
loops = 5;
+ } else {
+ loops = atoi(data);
+ }
+
+ if (loops < 0) {
+ loops = 5;
+ } else if (loops > 1024) {
+ loops = 1024;
}
switch_channel_answer(channel);
switch_ivr_sleep(session, 1000, SWITCH_FALSE, NULL);
-
+ switch_channel_set_private(channel, "__sonar_ping__", &ph);
+
switch_ivr_tone_detect_session(session,
"ping", "1004",
"r", 0,
@@ -86,18 +131,81 @@ SWITCH_STANDARD_APP(sonar_app)
switch_ivr_sleep(session, 1000, SWITCH_FALSE, NULL);
- for( int x = 0; x < loops; x++ ) {
- end = 0;
- start = switch_time_now();
+ ph.min = 999999;
+ for( x = 0; x < loops; x++ ) {
+ ph.end = 0;
+ ph.start = switch_time_now();
switch_ivr_gentones(session, tone, 1, NULL);
switch_ivr_sleep(session, 2000, SWITCH_FALSE, NULL);
- if ( start ) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Lost sonar ping\n");
+ if ( ph.start ) {
+ lost++;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Lost sonar ping\n");
}
}
switch_ivr_sleep(session, 1000, SWITCH_FALSE, NULL);
switch_ivr_stop_tone_detect_session(session);
+
+ if (loops == lost) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too bad, we lost all!\n");
+ return;
+ }
+
+ if (ph.received + lost != loops) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Race happend %d + %d != %d\n", ph.received, lost, loops);
+ }
+
+ if (ph.received > 0) avg = ph.sum / ph.received;
+
+ sum2 = 0;
+ for(x = 0; x < ph.received; x++) {
+ sum2 += abs(ph.samples[x] - avg);
+ }
+
+ if (ph.received > 0) {
+ mdev = sum2 / ph.received;
+ }
+
+
+ sum2 = 0;
+ for(x = 0; x < ph.received; x++) {
+ sum2 += (ph.samples[x] - avg) * (ph.samples[x] - avg);
+ }
+
+ if (ph.received > 1) {
+ sdev = sqrt(sum2 / (ph.received - 1));
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
+ "Sonar Ping (in ms): min:%d max:%d avg:%d sdev:%d mdev:%d sent:%d recv: %d lost:%d lost/send:%2.2f%%\n",
+ ph.min, ph.max, avg, sdev, mdev, loops, ph.received, lost, lost * 1.0 / loops);
+
+ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, "sonar::ping") == SWITCH_STATUS_SUCCESS) {
+ const char *verbose_event;
+
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_min", "%d", ph.min);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_max", "%d", ph.max);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_avg", "%d", avg);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_sdev", "%d", sdev);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_mdev", "%d", mdev);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_sent", "%d", loops);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_recv", "%d", ph.received);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "ping_lost", "%d", lost);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "lost_rate", "%2.2f%%", lost * 1.0 / loops);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "destination_number",
+ switch_channel_get_variable(channel, "ping_destination_number"));
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sonar_ping_ref",
+ switch_channel_get_variable(channel, "sonar_ping_ref"));
+
+ verbose_event = switch_channel_get_variable(channel, "sonar_channel_event");
+
+ if (verbose_event && switch_true(verbose_event)) {
+ switch_channel_event_set_data(channel, event);
+ }
+
+ switch_event_fire(&event);
+ }
+
}
/* Macro expands to: switch_status_t mod_sonar_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_modem.c b/src/mod/applications/mod_spandsp/mod_spandsp_modem.c
index 3a84a451de..7c43577427 100644
--- a/src/mod/applications/mod_spandsp/mod_spandsp_modem.c
+++ b/src/mod/applications/mod_spandsp/mod_spandsp_modem.c
@@ -239,7 +239,6 @@ switch_status_t modem_init(modem_t *modem, modem_control_handler_t control_handl
modem->stty = ttyname(modem->slave);
#else
#ifdef WIN32
- modem->slot = 4 + globals.NEXT_ID++; /* need work here we start at COM4 for now*/
snprintf(modem->devlink, sizeof(modem->devlink), "COM%d", modem->slot);
modem->master = CreateFile(modem->devlink,
@@ -884,6 +883,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
if (outbound_profile) {
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
caller_profile->source = switch_core_strdup(caller_profile->pool, "mod_spandsp");
+ caller_profile->destination_number = switch_core_strdup(caller_profile->pool, number);
switch_channel_set_caller_profile(channel, caller_profile);
tech_pvt->caller_profile = caller_profile;
} else {
diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c
index a87e849001..07d4d2fe95 100644
--- a/src/mod/applications/mod_voicemail/mod_voicemail.c
+++ b/src/mod/applications/mod_voicemail/mod_voicemail.c
@@ -3078,16 +3078,24 @@ static switch_status_t deliver_vm(vm_profile_t *profile,
vm_cc_num = switch_separate_string(vm_cc_dup, ',', vm_cc_list, (sizeof(vm_cc_list) / sizeof(vm_cc_list[0])));
for (vm_cc_i=0; vm_cc_i
+
+
+
+
+
diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c
index e329affb5c..cc94f1129f 100644
--- a/src/mod/endpoints/mod_skinny/mod_skinny.c
+++ b/src/mod/endpoints/mod_skinny/mod_skinny.c
@@ -173,6 +173,7 @@ switch_status_t skinny_profile_dump(const skinny_profile_t *profile, switch_stre
stream->write_function(stream, "Ext-Redial \t%s\n", profile->ext_redial);
stream->write_function(stream, "Ext-MeetMe \t%s\n", profile->ext_meetme);
stream->write_function(stream, "Ext-PickUp \t%s\n", profile->ext_pickup);
+ stream->write_function(stream, "Ext-CFwdAll \t%s\n", profile->ext_cfwdall);
stream->write_function(stream, "%s\n", line);
return SWITCH_STATUS_SUCCESS;
@@ -1939,6 +1940,10 @@ switch_status_t skinny_profile_set(skinny_profile_t *profile, const char *var, c
if (!profile->ext_pickup || strcmp(val, profile->ext_pickup)) {
profile->ext_pickup = switch_core_strdup(profile->pool, val);
}
+ } else if (!strcasecmp(var, "ext-cfwdall")) {
+ if (!profile->ext_cfwdall || strcmp(val, profile->ext_cfwdall)) {
+ profile->ext_cfwdall = switch_core_strdup(profile->pool, val);
+ }
} else {
return SWITCH_STATUS_FALSE;
}
@@ -2039,6 +2044,10 @@ static switch_status_t load_skinny_config(void)
skinny_profile_set(profile, "ext-pickup", "pickup");
}
+ if (!profile->ext_cfwdall) {
+ skinny_profile_set(profile, "ext-pickup", "cfwdall");
+ }
+
if (profile->port == 0) {
profile->port = 2000;
}
diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h
index df876d0894..b252dd7e4a 100644
--- a/src/mod/endpoints/mod_skinny/mod_skinny.h
+++ b/src/mod/endpoints/mod_skinny/mod_skinny.h
@@ -59,6 +59,11 @@
"[%s:%d @ %s:%d] " _fmt, skinny_undef_str(listener->device_name), listener->device_instance, skinny_undef_str(listener->remote_ip), \
listener->remote_port, __VA_ARGS__)
+#define skinny_log_l_ffl_msg(listener, file, func, line, level, _fmt) switch_log_printf( \
+ SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, level, \
+ "[%s:%d @ %s:%d] " _fmt, skinny_undef_str(listener->device_name), listener->device_instance, skinny_undef_str(listener->remote_ip), \
+ listener->remote_port)
+
#define skinny_log_ls(listener, session, level, _fmt, ...) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), level, \
"[%s:%d @ %s:%d] " _fmt, skinny_undef_str(listener->device_name), listener->device_instance, skinny_undef_str(listener->remote_ip), \
listener->remote_port, __VA_ARGS__)
@@ -125,6 +130,7 @@ struct skinny_profile {
char *ext_redial;
char *ext_meetme;
char *ext_pickup;
+ char *ext_cfwdall;
/* db */
char *dbname;
char *odbc_dsn;
@@ -194,6 +200,7 @@ struct listener {
char *ext_redial;
char *ext_meetme;
char *ext_pickup;
+ char *ext_cfwdall;
};
typedef struct listener listener_t;
diff --git a/src/mod/endpoints/mod_skinny/skinny_api.c b/src/mod/endpoints/mod_skinny/skinny_api.c
index db9338b000..f4c9560352 100644
--- a/src/mod/endpoints/mod_skinny/skinny_api.c
+++ b/src/mod/endpoints/mod_skinny/skinny_api.c
@@ -235,6 +235,7 @@ static switch_status_t skinny_api_list_settings(const char *line, const char *cu
switch_console_push_match(&my_matches, "ext-redial");
switch_console_push_match(&my_matches, "ext-meetme");
switch_console_push_match(&my_matches, "ext-pickup");
+ switch_console_push_match(&my_matches, "ext-cfwdall");
if (my_matches) {
*matches = my_matches;
@@ -384,6 +385,50 @@ static switch_status_t skinny_api_cmd_profile_device_send_call_state_message(con
return SWITCH_STATUS_SUCCESS;
}
+static switch_status_t skinny_api_cmd_profile_device_send_forward_stat_message(const char *profile_name, const char *device_name, const char *number, switch_stream_handle_t *stream)
+{
+ skinny_profile_t *profile;
+
+ if ((profile = skinny_find_profile(profile_name))) {
+ listener_t *listener = NULL;
+ skinny_profile_find_listener_by_device_name(profile, device_name, &listener);
+ if(listener) {
+
+ send_forward_stat(listener, number);
+
+ stream->write_function(stream, "+OK\n");
+ } else {
+ stream->write_function(stream, "Listener not found!\n");
+ }
+ } else {
+ stream->write_function(stream, "Profile not found!\n");
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t skinny_api_cmd_profile_device_send_display_prompt_status_message(const char *profile_name, const char *device_name, const char *display, switch_stream_handle_t *stream)
+{
+ skinny_profile_t *profile;
+
+ if ((profile = skinny_find_profile(profile_name))) {
+ listener_t *listener = NULL;
+ skinny_profile_find_listener_by_device_name(profile, device_name, &listener);
+ if(listener) {
+
+ send_display_prompt_status(listener, 0, display, 0, 0);
+
+ stream->write_function(stream, "+OK\n");
+ } else {
+ stream->write_function(stream, "Listener not found!\n");
+ }
+ } else {
+ stream->write_function(stream, "Profile not found!\n");
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
static switch_status_t skinny_api_cmd_profile_device_send_reset_message(const char *profile_name, const char *device_name, const char *reset_type, switch_stream_handle_t *stream)
{
skinny_profile_t *profile;
@@ -497,6 +542,8 @@ SWITCH_STANDARD_API(skinny_function)
"skinny profile device send SetLampMessage \n"
"skinny profile device send SetSpeakerModeMessage \n"
"skinny profile device send CallStateMessage \n"
+ "skinny profile device send ForwardStatMessage \n"
+ "skinny profile device send DisplayPromptStatus \n"
"skinny profile device send [ =;... ] \n"
"skinny profile set \n"
"--------------------------------------------------------------------------------\n";
@@ -560,6 +607,21 @@ SWITCH_STANDARD_API(skinny_function)
status = skinny_api_cmd_profile_device_send_call_state_message(argv[1], argv[3], argv[6], argv[7], argv[8], stream);
}
break;
+ case FORWARD_STAT_MESSAGE:
+ if (argc == 7) {
+ /* ForwardStatMessage */
+ status = skinny_api_cmd_profile_device_send_forward_stat_message(argv[1], argv[3], argv[6], stream);
+ } else if (argc == 6) {
+ /* ForwardStatMessage */
+ status = skinny_api_cmd_profile_device_send_forward_stat_message(argv[1], argv[3], NULL, stream);
+ }
+ break;
+ case DISPLAY_PROMPT_STATUS_MESSAGE:
+ if (argc == 7) {
+ /* DisplayPromptStatus */
+ status = skinny_api_cmd_profile_device_send_display_prompt_status_message(argv[1], argv[3], argv[6], stream);
+ }
+ break;
case RESET_MESSAGE:
if (argc == 7) {
/* ResetMessage */
@@ -610,6 +672,8 @@ switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetLampMessage ::skinny::list_stimuli ::skinny::list_stimulus_instances ::skinny::list_stimulus_modes");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetSpeakerModeMessage ::skinny::list_speaker_modes");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send CallStateMessage ::skinny::list_call_states ::skinny::list_line_instances ::skinny::list_call_ids");
+ switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send ForwardStatMessage");
+ switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send DisplayPromptStatusMessage");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataMessage");
switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataVersion1Message");
switch_console_set_complete("add skinny profile ::skinny::list_profiles set ::skinny::list_settings");
diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c
index ce756da34a..5498e5ebee 100644
--- a/src/mod/endpoints/mod_skinny/skinny_protocol.c
+++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c
@@ -592,6 +592,38 @@ switch_status_t perform_send_set_ringer(listener_t *listener,
return skinny_send_reply_quiet(listener, message, SWITCH_TRUE);
}
+switch_status_t perform_send_forward_stat(listener_t *listener,
+ const char *file, const char *func, int line,
+ const char *number)
+{
+ skinny_message_t *message;
+
+ skinny_create_message(message, FORWARD_STAT_MESSAGE, forward_stat);
+
+ if ( number && number[0] )
+ {
+ message->data.forward_stat.active_forward = 1;
+ message->data.forward_stat.line_instance = 1;
+ message->data.forward_stat.forward_all_active = 1;
+ message->data.forward_stat.forward_busy_active = 1;
+ message->data.forward_stat.forward_noanswer_active = 1;
+
+ strncpy(message->data.forward_stat.forward_all_number, number, sizeof(message->data.forward_stat.forward_all_number));
+ strncpy(message->data.forward_stat.forward_busy_number, number, sizeof(message->data.forward_stat.forward_all_number));
+ strncpy(message->data.forward_stat.forward_noanswer_number, number, sizeof(message->data.forward_stat.forward_all_number));
+ skinny_log_l_ffl(listener, file, func, line, SWITCH_LOG_DEBUG,
+ "Sending ForwardStat with Number (%s)\n", number);
+ }
+ else
+ {
+ skinny_log_l_ffl_msg(listener, file, func, line, SWITCH_LOG_DEBUG,
+ "Sending ForwardStat with No Number (Inactive)\n");
+ }
+
+
+ return skinny_send_reply_quiet(listener, message, SWITCH_TRUE);
+}
+
switch_status_t perform_send_set_lamp(listener_t *listener,
const char *file, const char *func, int line,
uint32_t stimulus,
diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h
index 43b2502e81..8a5178302e 100644
--- a/src/mod/endpoints/mod_skinny/skinny_protocol.h
+++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h
@@ -1019,6 +1019,11 @@ switch_status_t perform_send_set_ringer(listener_t *listener,
uint32_t call_id);
#define send_set_ringer(listener, ...) perform_send_set_ringer(listener, __FILE__, __SWITCH_FUNC__, __LINE__, __VA_ARGS__)
+switch_status_t perform_send_forward_stat(listener_t *listener,
+ const char *file, const char *func, int line,
+ const char *forward_to);
+#define send_forward_stat(listener, ...) perform_send_forward_stat(listener, __FILE__, __SWITCH_FUNC__, __LINE__, __VA_ARGS__)
+
switch_status_t perform_send_set_lamp(listener_t *listener,
const char *file, const char *func, int line,
uint32_t stimulus,
diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c
index 1dbf66b7b2..76486633ba 100644
--- a/src/mod/endpoints/mod_skinny/skinny_server.c
+++ b/src/mod/endpoints/mod_skinny/skinny_server.c
@@ -592,7 +592,6 @@ int skinny_ring_lines_callback(void *pArg, int argc, char **argv, char **columnN
device_name, device_instance, &listener);
if(listener && helper->tech_pvt->session && helper->remote_session) {
switch_channel_t *channel = switch_core_session_get_channel(helper->tech_pvt->session);
- switch_channel_t *remchannel = switch_core_session_get_channel(helper->remote_session);
switch_channel_set_state(channel, CS_ROUTING);
helper->lines_count++;
switch_channel_set_variable(channel, "effective_callee_id_number", value);
@@ -632,7 +631,7 @@ int skinny_ring_lines_callback(void *pArg, int argc, char **argv, char **columnN
skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance);
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_BLINK);
send_set_ringer(listener, SKINNY_RING_INSIDE, SKINNY_RING_FOREVER, 0, helper->tech_pvt->call_id);
- switch_channel_ring_ready(remchannel);
+ switch_channel_ring_ready(channel);
}
return 0;
}
@@ -1097,6 +1096,10 @@ switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *r
if (!listener->ext_pickup || strcmp(value,listener->ext_pickup)) {
listener->ext_pickup = switch_core_strdup(profile->pool, value);
}
+ } else if (!strcasecmp(name, "ext-cfwdall")) {
+ if (!listener->ext_cfwdall || strcmp(value,listener->ext_cfwdall)) {
+ listener->ext_cfwdall = switch_core_strdup(profile->pool, value);
+ }
}
}
}
@@ -1256,7 +1259,7 @@ switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny
digit = '*';
} else if (request->data.keypad_button.button == 15) {
digit = '#';
- } else if (request->data.keypad_button.button >= 0 && request->data.keypad_button.button <= 9) {
+ } else if (request->data.keypad_button.button <= 9) { /* unsigned, so guaranteed to be >= 0 */
digit = '0' + request->data.keypad_button.button;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "UNKNOW DTMF RECEIVED ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button);
@@ -2001,6 +2004,11 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn
skinny_session_process_dest(session, listener, line_instance,
empty_null2(listener->ext_pickup, listener->profile->ext_pickup), '\0', 0);
break;
+ case SOFTKEY_CFWDALL:
+ skinny_create_incoming_session(listener, &line_instance, &session);
+ skinny_session_process_dest(session, listener, line_instance,
+ empty_null2(listener->ext_cfwdall, listener->profile->ext_cfwdall), '\0', 0);
+ break;
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Unknown SoftKeyEvent type: %d.\n", request->data.soft_key_event.event);
diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c
index ea29918cbb..9c053d6b58 100644
--- a/src/mod/endpoints/mod_skinny/skinny_tables.c
+++ b/src/mod/endpoints/mod_skinny/skinny_tables.c
@@ -212,6 +212,7 @@ SKINNY_DECLARE_STR2ID(skinny_str2ring_mode, SKINNY_RING_MODES, -1)
{SKINNY_BUTTON_LAST_NUMBER_REDIAL, "LastNumberRedial"},
{SKINNY_BUTTON_SPEED_DIAL, "SpeedDial"},
{SKINNY_BUTTON_HOLD, "Hold"},
+ {SKINNY_BUTTON_FORWARDALL, "ForwardAll"},
{SKINNY_BUTTON_TRANSFER, "Transfer"},
{SKINNY_BUTTON_LINE, "Line"},
{SKINNY_BUTTON_VOICEMAIL, "Voicemail"},
diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h
index 647837f212..4fea984756 100644
--- a/src/mod/endpoints/mod_skinny/skinny_tables.h
+++ b/src/mod/endpoints/mod_skinny/skinny_tables.h
@@ -165,13 +165,14 @@ enum skinny_button_definition {
SKINNY_BUTTON_SPEED_DIAL = 0x02,
SKINNY_BUTTON_HOLD = 0x03,
SKINNY_BUTTON_TRANSFER = 0x04,
+ SKINNY_BUTTON_FORWARDALL = 0x05,
SKINNY_BUTTON_LINE = 0x09,
SKINNY_BUTTON_VOICEMAIL = 0x0F,
SKINNY_BUTTON_PRIVACY = 0x13,
SKINNY_BUTTON_SERVICE_URL = 0x14,
SKINNY_BUTTON_UNDEFINED = 0xFF,
};
-extern struct skinny_table SKINNY_BUTTONS[11];
+extern struct skinny_table SKINNY_BUTTONS[12];
const char *skinny_button2str(uint32_t id);
uint32_t skinny_str2button(const char *str);
#define SKINNY_PUSH_STIMULI SKINNY_DECLARE_PUSH_MATCH(SKINNY_BUTTONS)
diff --git a/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml b/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml
index 411ea3e44e..1b64f63bc7 100644
--- a/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml
+++ b/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml
@@ -64,6 +64,10 @@
+
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 2bc0476da7..a4c8913ee5 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -1,4 +1,4 @@
-/*
+/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2012, Anthony Minessale II
*
@@ -22,7 +22,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II
* Ken Rice
* Paul D. Tinsley
@@ -65,8 +65,8 @@ static switch_status_t sofia_kill_channel(switch_core_session_t *session, int si
/* BODY OF THE MODULE */
/*************************************************************************************************************************************************************/
-/*
- State methods they get called when the state changes to the specific state
+/*
+ State methods they get called when the state changes to the specific state
returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
*/
@@ -375,7 +375,7 @@ switch_status_t sofia_on_destroy(switch_core_session_t *session)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SOFIA DESTROY\n", switch_channel_get_name(channel));
if (tech_pvt) {
-
+
if (tech_pvt->respond_phrase) {
switch_yield(100000);
}
@@ -402,7 +402,7 @@ switch_status_t sofia_on_destroy(switch_core_session_t *session)
sofia_profile_destroy(tech_pvt->profile);
}
}
-
+
return SWITCH_STATUS_SUCCESS;
}
@@ -552,18 +552,18 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
case 401:
case 407:
{
- const char *to_host = switch_channel_get_variable(channel, "sip_challenge_realm");
+ const char *to_host = switch_channel_get_variable(channel, "sip_challenge_realm");
if (zstr(to_host)) {
- to_host = switch_channel_get_variable(channel, "sip_to_host");
+ to_host = switch_channel_get_variable(channel, "sip_to_host");
}
-
+
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Challenging call\n");
- sofia_reg_auth_challenge(tech_pvt->profile, tech_pvt->nh, NULL, REG_INVITE, to_host, 0, 0);
+ sofia_reg_auth_challenge(tech_pvt->profile, tech_pvt->nh, NULL, REG_INVITE, to_host, 0, 0);
*reason = '\0';
}
break;
-
+
case 484:
{
const char *to = switch_channel_get_variable(channel, "sip_to_uri");
@@ -575,13 +575,13 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
if ((p = strstr(to_uri, ":5060"))) {
*p = '\0';
}
-
+
tech_pvt->respond_dest = to_uri;
-
+
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Overlap Dial with %d %s\n", sip_cause, phrase);
-
+
}
break;
@@ -590,7 +590,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
}
}
-
+
if (tech_pvt->respond_dest && !sofia_test_pflag(tech_pvt->profile, PFLAG_MANUAL_REDIRECT)) {
added_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);
}
@@ -611,12 +611,12 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
nua_respond(tech_pvt->nh, sip_cause, phrase,
TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)),
- TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
- TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
- TAG_IF(!zstr(resp_headers), SIPTAG_HEADER_STR(resp_headers)),
- TAG_IF(!zstr(added_headers), SIPTAG_HEADER_STR(added_headers)),
+ TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
+ TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
+ TAG_IF(!zstr(resp_headers), SIPTAG_HEADER_STR(resp_headers)),
+ TAG_IF(!zstr(added_headers), SIPTAG_HEADER_STR(added_headers)),
TAG_IF(tech_pvt->respond_dest, SIPTAG_CONTACT_STR(tech_pvt->respond_dest)),
- TAG_IF(!zstr(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards)),
+ TAG_IF(!zstr(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards)),
TAG_END());
switch_safe_free(resp_headers);
@@ -663,7 +663,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
int is_3pcc = 0;
char *sticky = NULL;
const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
-
+
if (switch_channel_test_flag(channel, CF_CONFERENCE)) {
tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s;isfocus", tech_pvt->reply_contact);
}
@@ -671,7 +671,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
//switch_core_media_set_local_sdp
if(sofia_test_flag(tech_pvt, TFLAG_3PCC_INVITE)) {
// SNARK: complete hack to get final ack sent when a 3pcc invite has been passed from the other leg in bypass_media mode.
- // This code handles the pass_indication sent after the 3pcc ack is received by the other leg in the is_3pcc && is_proxy case below.
+ // This code handles the pass_indication sent after the 3pcc ack is received by the other leg in the is_3pcc && is_proxy case below.
// Is there a better place to hang this...?
b_sdp = switch_channel_get_variable(channel, SWITCH_B_SDP_VARIABLE);
switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE);
@@ -818,7 +818,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}
-
+
if (tech_pvt->nh) {
if (tech_pvt->mparams.local_sdp_str) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Local SDP %s:\n%s\n", switch_channel_get_name(channel),
@@ -853,14 +853,14 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->mparams.early_sdp) {
char *a, *b;
-
+
/* start at the s= line to avoid some devices who update the o= between messages */
a = strstr(tech_pvt->mparams.early_sdp, "s=");
b = strstr(tech_pvt->mparams.local_sdp_str, "s=");
if (!a || !b || strcmp(a, b)) {
- /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless
+ /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless
we do so in this case we will abandon the SOA rules and go rogue.
*/
sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
@@ -873,7 +873,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
tech_pvt->session_refresher = nua_no_refresher;
}
-
+
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, SIP_200_OK,
@@ -928,7 +928,7 @@ static switch_status_t sofia_read_video_frame(switch_core_session_t *session, sw
#if 0
while (!(tech_pvt->video_read_codec.implementation && switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_VIDEO) && !switch_channel_test_flag(channel, CF_REQ_MEDIA))) {
switch_ivr_parse_all_messages(tech_pvt->session);
-
+
if (--sanity && switch_channel_ready(channel)) {
switch_yield(10000);
} else {
@@ -1110,7 +1110,7 @@ static switch_status_t sofia_send_dtmf(switch_core_session_t *session, const swi
dtmf_type = tech_pvt->mparams.dtmf_type;
/* We only can send INFO when we have no media */
- if (!switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO) ||
+ if (!switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO) ||
!switch_channel_media_ready(tech_pvt->channel) || switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE)) {
dtmf_type = DTMF_INFO;
}
@@ -1187,7 +1187,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
break;
case SWITCH_MESSAGE_INDICATE_BRIDGE:
switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, NULL);
-
+
if (switch_true(switch_channel_get_variable(channel, "sip_auto_simplify"))) {
sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY);
}
@@ -1269,8 +1269,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
}
- if (((var = switch_channel_get_variable(channel, SOFIA_SECURE_MEDIA_VARIABLE)) ||
- (var = switch_channel_get_variable(channel, "rtp_secure_media"))) &&
+ if (((var = switch_channel_get_variable(channel, SOFIA_SECURE_MEDIA_VARIABLE)) ||
+ (var = switch_channel_get_variable(channel, "rtp_secure_media"))) &&
(switch_true(var) || !strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_32) || !strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_80))) {
switch_channel_set_flag(tech_pvt->channel, CF_SECURE);
}
@@ -1306,10 +1306,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if (!zstr(msg->string_arg)) {
pl = msg->string_arg;
}
-
+
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END());
}
-
+
}
break;
case SWITCH_MESSAGE_INDICATE_BROADCAST:
@@ -1353,9 +1353,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if(zstr(tech_pvt->mparams.local_sdp_str)) {
sofia_set_flag(tech_pvt, TFLAG_3PCC_INVITE);
}
-
+
sofia_set_flag_locked(tech_pvt, TFLAG_SENT_UPDATE);
-
+
if (!switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
switch_channel_set_flag(channel, CF_REQ_MEDIA);
}
@@ -1416,7 +1416,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
switch_channel_set_variable(channel, "sip_require_timer", "false");
sofia_glue_do_invite(session);
} else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Request to send IMAGE on channel with not t38 options.\n",
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Request to send IMAGE on channel with not t38 options.\n",
switch_channel_get_name(channel));
}
}
@@ -1477,9 +1477,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
}
if (!switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
"Operation not permitted on an inbound non-answered call leg!\n");
- } else {
+ } else {
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_SUBSCRIPTION_STATE_STR("active"),
SIPTAG_EVENT_STR(event), TAG_END());
}
@@ -1546,23 +1546,23 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
"fs_send_unspported_info is deprecated in favor of correctly spelled fs_send_unsupported_info\n");
ok = 1;
}
-
+
if (switch_true(switch_channel_get_variable(channel, "fs_send_unsupported_info"))) {
ok = 1;
}
-
+
if (ok) {
char *headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_INFO_HEADER_PREFIX);
const char *pl = NULL;
-
+
if (!zstr(msg->string_array_arg[2])) {
pl = msg->string_array_arg[2];
}
-
+
nua_info(tech_pvt->nh,
SIPTAG_CONTENT_TYPE_STR(ct),
TAG_IF(!zstr(headers), SIPTAG_HEADER_STR(headers)),
- TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
+ TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(pl, SIPTAG_PAYLOAD_STR(pl)),
TAG_END());
@@ -1621,21 +1621,29 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
break;
case SWITCH_MESSAGE_INDICATE_DISPLAY:
{
- const char *name = msg->string_array_arg[0], *number = msg->string_array_arg[1];
- const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
-
+ const char *name = NULL, *number = NULL;
+ const char *call_info = NULL;
+
+ if (!sofia_test_pflag(tech_pvt->profile, PFLAG_SEND_DISPLAY_UPDATE)) {
+ goto end_lock;
+ }
+
+ name = msg->string_array_arg[0];
+ number = msg->string_array_arg[1];
+ call_info = switch_channel_get_variable(channel, "presence_call_info_full");
+
if (!zstr(name)) {
char message[256] = "";
const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent");
switch_event_t *event;
-
+
check_decode(name, tech_pvt->session);
if (zstr(number)) {
number = tech_pvt->caller_profile->destination_number;
}
-
+
switch_ivr_eavesdrop_update_display(session, name, number);
if (!sofia_test_flag(tech_pvt, TFLAG_UPDATING_DISPLAY) && switch_channel_test_flag(channel, CF_ANSWERED)) {
@@ -1660,7 +1668,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
} else if (ua && switch_stristr("snom", ua)) {
- const char *ver_str = NULL;
+ const char *ver_str = NULL;
int version = 0;
ver_str = switch_stristr( "/", ua);
@@ -1744,7 +1752,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
tech_pvt->last_sent_callee_id_name = switch_core_session_strdup(tech_pvt->session, name);
tech_pvt->last_sent_callee_id_number = switch_core_session_strdup(tech_pvt->session, number);
-
+
if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE) == SWITCH_STATUS_SUCCESS) {
const char *uuid = switch_channel_get_partner_uuid(channel);
@@ -1784,7 +1792,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if (!zstr(msg->string_arg)) {
char message[256] = "";
const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent");
-
+
if (ua && switch_stristr("snom", ua)) {
snprintf(message, sizeof(message), "From:\r\nTo: \"%s\" %s\r\n", msg->string_arg, tech_pvt->caller_profile->destination_number);
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
@@ -1853,9 +1861,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Redirecting to %s\n", dest);
-
+
tech_pvt->respond_dest = dest;
-
+
if (argc > 1) {
tech_pvt->respond_code = 300;
tech_pvt->respond_phrase = "Multiple Choices";
@@ -1997,7 +2005,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
/* Regain lock on sofia */
switch_mutex_lock(tech_pvt->sofia_mutex);
-
+
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Done waiting for ACK\n");
sofia_clear_flag(tech_pvt, TFLAG_3PCC);
sofia_clear_flag(tech_pvt, TFLAG_3PCC_HAS_ACK);
@@ -2102,7 +2110,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
}
}
} else {
- if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) ||
+ if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) ||
switch_core_media_codec_chosen(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO) != SWITCH_STATUS_SUCCESS) {
sofia_clear_flag_locked(tech_pvt, TFLAG_LATE_NEGOTIATION);
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
@@ -2150,11 +2158,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
char *cid = NULL;
cid = generate_pai_str(tech_pvt);
-
+
if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) &&
tech_pvt->mparams.early_sdp && strcmp(tech_pvt->mparams.early_sdp, tech_pvt->mparams.local_sdp_str)) {
- /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless
+ /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless
we do so in this case we will abandon the SOA rules and go rogue.
*/
sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
@@ -2202,7 +2210,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
case SWITCH_MESSAGE_INDICATE_UDPTL_MODE:
{
switch_t38_options_t *t38_options = switch_channel_get_private(channel, "t38_options");
-
+
if (!t38_options) {
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
}
@@ -3082,7 +3090,7 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
goto done;
}
-
+
if (!strcasecmp(argv[1], "recover")) {
if (argv[2] && !strcasecmp(argv[2], "flush")) {
sofia_glue_profile_recover(profile, SWITCH_TRUE);
@@ -3199,16 +3207,16 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
goto done;
}
- if (!strcasecmp(argv[1], "capture")) {
- if (argc > 2) {
- int value = switch_true(argv[2]);
- nua_set_params(profile->nua, TPTAG_CAPT(value ? mod_sofia_globals.capture_server : NULL), TAG_END());
- stream->write_function(stream, "%s sip capturing on %s", value ? "Enabled" : "Disabled", profile->name);
- } else {
- stream->write_function(stream, "Usage: sofia profile capture \n");
- }
- goto done;
- }
+ if (!strcasecmp(argv[1], "capture")) {
+ if (argc > 2) {
+ int value = switch_true(argv[2]);
+ nua_set_params(profile->nua, TPTAG_CAPT(value ? mod_sofia_globals.capture_server : NULL), TAG_END());
+ stream->write_function(stream, "%s sip capturing on %s", value ? "Enabled" : "Disabled", profile->name);
+ } else {
+ stream->write_function(stream, "Usage: sofia profile capture \n");
+ }
+ goto done;
+ }
if (!strcasecmp(argv[1], "watchdog")) {
if (argc > 2) {
@@ -3224,7 +3232,7 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
if (!strcasecmp(argv[1], "gwlist")) {
int up = 1;
-
+
if (argc > 2) {
if (!strcasecmp(argv[2], "down")) {
up = 0;
@@ -3250,13 +3258,13 @@ static int contact_callback(void *pArg, int argc, char **argv, char **columnName
{
struct cb_helper *cb = (struct cb_helper *) pArg;
char *contact;
-
+
cb->row_process++;
-
+
if (!zstr(argv[0]) && (contact = sofia_glue_get_url_from_contact(argv[0], 1))) {
if (cb->dedup) {
char *tmp = switch_mprintf("%ssofia/%s/sip:%s", argv[2], argv[1], sofia_glue_strip_proto(contact));
-
+
if (!strstr((char *)cb->stream->data, tmp)) {
cb->stream->write_function(cb->stream, "%s,", tmp);
}
@@ -3463,17 +3471,17 @@ SWITCH_STANDARD_API(sofia_username_of_function)
return SWITCH_STATUS_SUCCESS;
}
-static void select_from_profile(sofia_profile_t *profile,
+static void select_from_profile(sofia_profile_t *profile,
const char *user,
const char *domain,
const char *concat,
- const char *exclude_contact,
+ const char *exclude_contact,
switch_stream_handle_t *stream,
switch_bool_t dedup)
{
struct cb_helper cb;
char *sql;
-
+
cb.row_process = 0;
cb.profile = profile;
@@ -3552,7 +3560,7 @@ SWITCH_STANDARD_API(sofia_contact_function)
if (!zstr(profile_name)) {
profile = sofia_glue_find_profile(profile_name);
}
-
+
if (!profile && !zstr(domain)) {
profile = sofia_glue_find_profile(domain);
}
@@ -3571,32 +3579,32 @@ SWITCH_STANDARD_API(sofia_contact_function)
if (!zstr(profile->domain_name) && !zstr(profile_name) && !strcmp(profile_name, profile->name)) {
domain = profile->domain_name;
}
-
+
select_from_profile(profile, user, domain, concat, exclude_contact, &mystream, SWITCH_FALSE);
sofia_glue_release_profile(profile);
-
+
} else if (!zstr(domain)) {
switch_mutex_lock(mod_sofia_globals.hash_mutex);
if (mod_sofia_globals.profile_hash) {
switch_hash_index_t *hi;
const void *var;
void *val;
-
+
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
if ((profile = (sofia_profile_t *) val) && !strcmp((char *)var, profile->name)) {
- select_from_profile(profile, user, domain, concat, exclude_contact, &mystream, SWITCH_TRUE);
+ select_from_profile(profile, user, domain, concat, exclude_contact, &mystream, SWITCH_TRUE);
profile = NULL;
}
}
}
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
- }
-
+ }
+
reply = (char *) mystream.data;
end:
-
+
if (zstr(reply)) {
reply = "error/user_not_registered";
} else if (end_of(reply) == ',') {
@@ -3606,7 +3614,7 @@ SWITCH_STANDARD_API(sofia_contact_function)
stream->write_function(stream, "%s", reply);
reply = NULL;
- switch_safe_free(mystream.data);
+ switch_safe_free(mystream.data);
switch_safe_free(data);
switch_safe_free(dup_domain);
@@ -3933,12 +3941,12 @@ SWITCH_STANDARD_API(sofia_function)
mod_sofia_globals.debug_presence = 10;
stream->write_function(stream, "+OK Debugging presence\n");
}
-
+
if (strstr(argv[2], "sla")) {
mod_sofia_globals.debug_sla = 10;
stream->write_function(stream, "+OK Debugging sla\n");
}
-
+
if (strstr(argv[2], "none")) {
stream->write_function(stream, "+OK Debugging nothing\n");
mod_sofia_globals.debug_presence = 0;
@@ -3946,13 +3954,13 @@ SWITCH_STANDARD_API(sofia_function)
}
}
- stream->write_function(stream, "+OK Debugging summary: presence: %s sla: %s\n",
+ stream->write_function(stream, "+OK Debugging summary: presence: %s sla: %s\n",
mod_sofia_globals.debug_presence ? "on" : "off",
mod_sofia_globals.debug_sla ? "on" : "off");
-
+
goto done;
}
-
+
if (!strcasecmp(argv[1], "siptrace")) {
if (argc > 2) {
ston = switch_true(argv[2]);
@@ -3966,10 +3974,10 @@ SWITCH_STANDARD_API(sofia_function)
}
if (!strcasecmp(argv[1], "capture")) {
- if (argc > 2) {
- cton = switch_true(argv[2]);
- }
- }
+ if (argc > 2) {
+ cton = switch_true(argv[2]);
+ }
+ }
if (!strcasecmp(argv[1], "watchdog")) {
if (argc > 2) {
@@ -3993,7 +4001,7 @@ SWITCH_STANDARD_API(sofia_function)
} else {
stream->write_function(stream, "-ERR Usage: siptrace |capture |watchdog |debug gateway_name = switch_core_session_strdup(nsession, gateway_ptr->name);
switch_channel_set_variable(nchannel, "sip_gateway_name", gateway_ptr->name);
@@ -4217,7 +4225,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
dest_to = NULL;
}
}
-
+
if (params) {
tech_pvt->invite_contact = switch_core_session_sprintf(nsession, "%s;%s", gateway_ptr->register_contact, params);
tech_pvt->dest = switch_core_session_sprintf(nsession, "%s;%s", tech_pvt->dest, params);
@@ -4228,10 +4236,10 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
gateway_ptr->ob_calls++;
if (!zstr(gateway_ptr->from_domain) && !switch_channel_get_variable(nchannel, "sip_invite_domain")) {
-
+
if (!strcasecmp(gateway_ptr->from_domain, "auto-aleg-full")) {
const char *sip_full_from = switch_channel_get_variable(o_channel, "sip_full_from");
-
+
if (!zstr(sip_full_from)) {
switch_channel_set_variable(nchannel, "sip_force_full_from", sip_full_from);
}
@@ -4309,7 +4317,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
}
} else {
host++;
-
+
if (!strchr(host, '.') || switch_true(switch_event_get_header(var_event, "sip_gethostbyname"))) {
struct sockaddr_in sa;
struct hostent *he = gethostbyname(host);
@@ -4318,7 +4326,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
if (he) {
memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr));
ip = inet_ntoa(sa.sin_addr);
-
+
tmp = switch_string_replace(dest, host, ip);
//host = switch_core_session_strdup(nsession, ip);
//dest = switch_core_session_strdup(nsession, tmp);
@@ -4339,7 +4347,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
if (switch_stristr("fs_path", tech_pvt->dest)) {
char *remote_host = NULL;
const char *s;
-
+
if ((s = switch_stristr("fs_path=", tech_pvt->dest))) {
s += 8;
}
@@ -4351,7 +4359,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
if (!zstr(remote_host)) {
switch_split_user_domain(remote_host, NULL, &tech_pvt->mparams.remote_ip);
}
- }
+ }
if (zstr(tech_pvt->mparams.remote_ip)) {
switch_split_user_domain(switch_core_session_strdup(nsession, tech_pvt->dest), NULL, &tech_pvt->mparams.remote_ip);
@@ -4373,7 +4381,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
switch_channel_set_variable(nchannel, "rtp_secure_media", SWITCH_RTP_CRYPTO_KEY_80);
}
- if ((hval = switch_event_get_header(var_event, SOFIA_SECURE_MEDIA_VARIABLE)) ||
+ if ((hval = switch_event_get_header(var_event, SOFIA_SECURE_MEDIA_VARIABLE)) ||
(hval = switch_event_get_header(var_event, "rtp_secure_media"))) {
switch_channel_set_variable(nchannel, "rtp_secure_media", hval);
@@ -4384,7 +4392,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
switch_channel_set_variable(nchannel, "media_webrtc", "true");
switch_core_session_set_ice(nsession);
}
-
+
sofia_glue_attach_private(nsession, profile, tech_pvt, dest);
@@ -4518,7 +4526,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
}
if (switch_core_session_compare(session, nsession)) {
- /* It's another sofia channel! so lets cache what they use as a pt for telephone event so
+ /* It's another sofia channel! so lets cache what they use as a pt for telephone event so
we can keep it the same
*/
private_object_t *ctech_pvt;
@@ -4680,19 +4688,19 @@ static int notify_callback(void *pArg, int argc, char **argv, char **columnNames
dst = sofia_glue_get_destination((char *) contact);
-
+
if (dst->route_uri) {
route_uri = sofia_glue_strip_uri(dst->route_uri);
}
nh = nua_handle(profile->nua, NULL, NUTAG_URL(dst->contact), SIPTAG_FROM_STR(id), SIPTAG_TO_STR(id), SIPTAG_CONTACT_STR(profile->url), TAG_END());
-
+
nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
nua_notify(nh, NUTAG_NEWSUB(1), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
SIPTAG_EVENT_STR(es), SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_END());
-
+
switch_safe_free(route_uri);
sofia_glue_free_destination(dst);
@@ -4809,32 +4817,32 @@ static void general_event_handler(switch_event_t *event)
char *route_uri = NULL;
dst = sofia_glue_get_destination((char *) to_uri);
-
+
if (dst->route_uri) {
route_uri = sofia_glue_strip_uri(dst->route_uri);
}
-
-
+
+
nh = nua_handle(profile->nua,
NULL,
- NUTAG_URL(to_uri),
+ NUTAG_URL(to_uri),
SIPTAG_FROM_STR(from_uri),
SIPTAG_TO_STR(to_uri),
SIPTAG_CONTACT_STR(profile->url),
TAG_END());
nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
-
+
nua_notify(nh,
NUTAG_NEWSUB(1), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
SIPTAG_EVENT_STR(es), TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(ct)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
-
+
switch_safe_free(route_uri);
sofia_glue_free_destination(dst);
-
+
sofia_glue_release_profile(profile);
}
@@ -4891,7 +4899,7 @@ static void general_event_handler(switch_event_t *event)
const char *user = switch_event_get_header(event, "user");
const char *host = switch_event_get_header(event, "host");
const char *call_id = switch_event_get_header(event, "call-id");
- const char *csta_event = switch_event_get_header(event, "csta-event");
+ const char *csta_event = switch_event_get_header(event, "Feature-Event");
char *ct = "application/x-as-feature-event+xml";
@@ -4948,8 +4956,19 @@ static void general_event_handler(switch_event_t *event)
ct = switch_mprintf("multipart/mixed; boundary=\"%s\"", boundary_string);
} else {
+ char *fwd_type = NULL;
+ char *header_name = NULL;
+
+ if ((header_name = switch_event_get_header(event, "forward_immediate"))) {
+ fwd_type = "forwardImmediate";
+ } else if ((header_name = switch_event_get_header(event, "forward_busy"))) {
+ fwd_type = "forwardBusy";
+ } else if ((header_name = switch_event_get_header(event, "forward_no_answer"))) {
+ fwd_type = "forwardNoAns";
+ }
+
// this will need some work to handle the different types of forwarding events
- write_csta_xml_chunk(event, stream, csta_event, NULL);
+ write_csta_xml_chunk(event, stream, csta_event, fwd_type);
}
}
@@ -4998,7 +5017,7 @@ static void general_event_handler(switch_event_t *event)
char *contact, *p;
switch_console_callback_match_t *list = NULL;
switch_console_callback_match_node_t *m;
-
+
if (!(list = sofia_reg_find_reg_url_multi(profile, user, host))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find registered user %s@%s\n", user, host);
return;
@@ -5150,7 +5169,7 @@ static void general_event_handler(switch_event_t *event)
if (!strcmp(cond, "network-external-address-change") && mod_sofia_globals.auto_restart) {
const char *old_ip4 = switch_event_get_header_nil(event, "network-external-address-previous-v4");
const char *new_ip4 = switch_event_get_header_nil(event, "network-external-address-change-v4");
-
+
switch_mutex_lock(mod_sofia_globals.hash_mutex);
if (mod_sofia_globals.profile_hash && !zstr(old_ip4) && !zstr(new_ip4)) {
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
@@ -5168,7 +5187,7 @@ static void general_event_handler(switch_event_t *event)
}
}
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
- sofia_glue_restart_all_profiles();
+ sofia_glue_restart_all_profiles();
} else if (!strcmp(cond, "network-address-change") && mod_sofia_globals.auto_restart) {
const char *old_ip4 = switch_event_get_header_nil(event, "network-address-previous-v4");
const char *new_ip4 = switch_event_get_header_nil(event, "network-address-change-v4");
@@ -5248,30 +5267,35 @@ void write_csta_xml_chunk(switch_event_t *event, switch_stream_handle_t stream,
stream.write_function(&stream, " %s\n", dndstatus);
}
} else if(!strcmp(csta_event, "ForwardingEvent")) {
- const char *fwdstatus = switch_event_get_header(event, "forwardStatus");
+ const char *fwdstatus = NULL;
const char *fwdto = NULL;
const char *ringcount = NULL;
- if (strcmp("forwardImmediate", fwdtype)) {
- fwdto = switch_event_get_header(event, "forward_immediate");
- } else if (strcmp("forwardBusy", fwdtype)) {
- fwdto = switch_event_get_header(event, "forward_busy");
- } else if (strcmp("fowardNoAns", fwdtype)) {
- fwdto = switch_event_get_header(event, "forward_no_answer");
- ringcount = switch_event_get_header(event, "ringCount");
- }
+ if (fwdtype && !zstr(fwdtype)) {
+ if (!strcmp("forwardImmediate", fwdtype)) {
+ fwdto = switch_event_get_header(event, "forward_immediate");
+ fwdstatus = switch_event_get_header(event, "forward_immediate_enabled");
+ } else if (!strcmp("forwardBusy", fwdtype)) {
+ fwdto = switch_event_get_header(event, "forward_busy");
+ fwdstatus = switch_event_get_header(event, "forward_busy_enabled");
+ } else if (!strcmp("forwardNoAns", fwdtype)) {
+ fwdto = switch_event_get_header(event, "forward_no_answer");
+ fwdstatus = switch_event_get_header(event, "forward_no_answer_enabled");
+ ringcount = switch_event_get_header(event, "ringCount");
+ }
- if (fwdtype) {
- stream.write_function(&stream, " %s\n", fwdtype);
- }
- if (fwdstatus) {
- stream.write_function(&stream, " %s\n", fwdstatus);
- }
- if (fwdto) {
- stream.write_function(&stream, " %s\n", fwdto);
- }
- if (ringcount) {
- stream.write_function(&stream, " %s\n", ringcount);
+ if (fwdtype) {
+ stream.write_function(&stream, " %s\n", fwdtype);
+ }
+ if (fwdstatus) {
+ stream.write_function(&stream, " %s\n", fwdstatus);
+ }
+ if (fwdto) {
+ stream.write_function(&stream, " %s\n", fwdto);
+ }
+ if (ringcount) {
+ stream.write_function(&stream, " %s\n", ringcount);
+ }
}
}
@@ -5403,7 +5427,7 @@ SWITCH_STANDARD_APP(sofia_sla_function)
}
switch_channel_answer(channel);
-
+
if ((bargee_session = switch_core_session_locate((char *)data))) {
if (bargee_session == session) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "BARGE: %s (cannot barge on myself)\n", (char *) data);
@@ -5415,12 +5439,12 @@ SWITCH_STANDARD_APP(sofia_sla_function)
switch_channel_set_flag(tech_pvt->channel, CF_SLA_BARGE);
switch_ivr_transfer_variable(bargee_session, session, SWITCH_SIGNAL_BOND_VARIABLE);
}
-
+
if (switch_core_session_check_interface(session, sofia_endpoint_interface)) {
tech_pvt = switch_core_session_get_private(session);
switch_channel_set_flag(tech_pvt->channel, CF_SLA_BARGING);
}
-
+
switch_channel_set_variable(channel, "sip_barging_uuid", (char *)data);
}
@@ -5428,7 +5452,7 @@ SWITCH_STANDARD_APP(sofia_sla_function)
}
switch_channel_execute_on(channel, "execute_on_sip_barge");
-
+
switch_ivr_eavesdrop_session(session, data, NULL, ED_MUX_READ | ED_MUX_WRITE | ED_COPY_DISPLAY);
}
@@ -5482,12 +5506,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
/* start one message thread */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting initial message thread.\n");
sofia_msg_thread_start(0);
-
+
if (sofia_init() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_GENERR;
}
-
+
if (config_sofia(SOFIA_CONFIG_LOAD, NULL) != SWITCH_STATUS_SUCCESS) {
mod_sofia_globals.running = 0;
return SWITCH_STATUS_GENERR;
@@ -5573,7 +5597,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
management_interface->relative_oid = "1001";
management_interface->management_function = sofia_manage;
- SWITCH_ADD_APP(app_interface, "sofia_sla", "private sofia sla function",
+ SWITCH_ADD_APP(app_interface, "sofia_sla", "private sofia sla function",
"private sofia sla function", sofia_sla_function, "", SAF_NONE);
@@ -5597,7 +5621,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
switch_console_set_complete("add sofia profile");
switch_console_set_complete("add sofia profile restart all");
-
+
switch_console_set_complete("add sofia profile ::sofia::list_profiles start");
switch_console_set_complete("add sofia profile ::sofia::list_profiles stop wait");
switch_console_set_complete("add sofia profile ::sofia::list_profiles rescan");
@@ -5709,4 +5733,3 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/
-
diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c
index 27e9c6d669..11228355bf 100644
--- a/src/mod/endpoints/mod_sofia/sofia_presence.c
+++ b/src/mod/endpoints/mod_sofia/sofia_presence.c
@@ -1,4 +1,4 @@
-/*
+/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2012, Anthony Minessale II
*
@@ -22,14 +22,14 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II
* Ken Rice
* Paul D. Tinsley
* Bret McDanel
* Raymond Chandler
* William King
- * Emmanuel Schmidbauer
+ * Emmanuel Schmidbauer
*
* sofia_presence.c -- SOFIA SIP Endpoint (presence code)
*
@@ -98,7 +98,7 @@ struct presence_helper {
};
switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
-
+
{
char *prof = NULL, *user = NULL, *host = NULL;
sofia_profile_t *profile = NULL;
@@ -119,7 +119,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
char *p = NULL;
char *remote_host = NULL;
const char *proto;
- const char *from;
+ const char *from;
const char *to;
//const char *subject;
const char *body;
@@ -179,14 +179,14 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
if (!prof) {
prof = switch_event_get_header(message_event, "sip_profile");
}
-
+
if (!strncasecmp(user, "sip:", 4)) {
to_uri = user;
}
if ((host = strchr(user, '@'))) {
if (!to_uri) {
- *host++ = '\0';
+ *host++ = '\0';
} else {
host++;
}
@@ -228,12 +228,12 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
}
}
-
+
if (!strcasecmp(proto, SOFIA_CHAT_PROTO)) {
from = from_full;
} else {
char *fp, *p = NULL;
-
+
fp = strdup(from);
switch_assert(fp);
@@ -291,7 +291,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
break;
}
-
+
/* sofia_glue is running sofia_overcome_sip_uri_weakness we do not, not sure if it matters */
if (dst->route_uri) {
@@ -331,7 +331,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
if (dup_dest && (p = strstr(dup_dest, ";fs_"))) {
*p = '\0';
}
-
+
/* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */
//printf("DEBUG To: [%s] From: [%s] Contact: [%s] RURI [%s] ip [%s] port [%s]\n", to, from, contact, dst->route_uri, network_ip, network_port);
@@ -346,17 +346,17 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
TAG_END());
nua_handle_bind(msg_nh, &mod_sofia_globals.destroy_private);
-
+
switch_snprintf(header, sizeof(header), "X-FS-Sending-Message: %s", switch_core_get_uuid());
switch_uuid_str(uuid_str, sizeof(uuid_str));
-
+
if (is_blocking) {
switch_mutex_lock(profile->flag_mutex);
switch_core_hash_insert(profile->chat_hash, uuid_str, &mstatus);
switch_mutex_unlock(profile->flag_mutex);
}
-
+
nua_message(msg_nh,
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)),
TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
@@ -371,7 +371,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
SIPTAG_HEADER_STR(header),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_END());
-
+
if (is_blocking) {
sanity = 200;
@@ -379,7 +379,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
while(!mstatus && --sanity && !msg_nh->nh_destroyed) {
switch_yield(100000);
}
-
+
if (!(mstatus > 199 && mstatus < 300)) {
status = SWITCH_STATUS_FALSE;
}
@@ -394,7 +394,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
sofia_glue_free_destination(dst);
switch_safe_free(dup_dest);
switch_safe_free(remote_host);
- }
+ }
end:
@@ -425,23 +425,23 @@ void sofia_presence_cancel(void)
if (!mod_sofia_globals.profile_hash) {
return;
}
-
+
if (list_profiles_full(NULL, NULL, &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
switch_console_callback_match_node_t *m;
-
+
for (m = matches->head; m; m = m->next) {
if ((profile = sofia_glue_find_profile(m->val))) {
if (profile->pres_type == PRES_TYPE_FULL) {
helper.profile = profile;
helper.event = NULL;
-
+
sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
"full_via,expires,user_agent,accept,profile_name,network_ip"
",-1,'unavailable','unavailable' from sip_subscriptions where "
"event='presence' and hostname='%q' and profile_name='%q'",
mod_sofia_globals.hostname, profile->name);
-
+
r = sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_sub_callback, &helper);
switch_safe_free(sql);
@@ -453,7 +453,7 @@ void sofia_presence_cancel(void)
sofia_glue_release_profile(profile);
}
}
-
+
switch_console_free_matches(&matches);
}
@@ -528,16 +528,16 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
if ((pname = switch_event_get_header(event, "sofia-profile"))) {
profile = sofia_glue_find_profile(pname);
}
-
+
if (!profile) {
if (!host || !(profile = sofia_glue_find_profile(host))) {
char *sql;
char buf[512] = "";
switch_console_callback_match_t *matches;
- sql = switch_mprintf("select profile_name from sip_registrations where hostname='%q' and (sip_host='%s' or mwi_host='%s')",
+ sql = switch_mprintf("select profile_name from sip_registrations where hostname='%q' and (sip_host='%s' or mwi_host='%s')",
mod_sofia_globals.hostname, host, host);
-
+
if (list_profiles_full(NULL, NULL, &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
switch_console_callback_match_node_t *m;
@@ -597,7 +597,7 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
"full_via,expires,user_agent,accept,profile_name,network_ip"
",'%q',full_to,network_ip,network_port from sip_subscriptions "
"where hostname='%q' and event='message-summary' "
- "and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%')",
+ "and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%')",
stream.data, mod_sofia_globals.hostname, user, host, host);
} else if (sub_call_id) {
sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
@@ -618,11 +618,11 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
if (for_everyone) {
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',call_id "
- "from sip_registrations where hostname='%q' and mwi_user='%q' and mwi_host='%q'",
+ "from sip_registrations where hostname='%q' and mwi_user='%q' and mwi_host='%q'",
stream.data, mod_sofia_globals.hostname, user, host);
} else if (call_id) {
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',call_id "
- "from sip_registrations where hostname='%q' and call_id='%q'",
+ "from sip_registrations where hostname='%q' and call_id='%q'",
stream.data, mod_sofia_globals.hostname, call_id);
}
@@ -654,7 +654,7 @@ static int sofia_presence_dialog_callback(void *pArg, int argc, char **argv, cha
}
if (mod_sofia_globals.debug_presence > 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "CHECK DIALOG state[%s] status[%s] rpid[%s] pres[%s] uuid[%s]\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "CHECK DIALOG state[%s] status[%s] rpid[%s] pres[%s] uuid[%s]\n",
argv[0], argv[1], argv[2], argv[3], argv[4]);
}
@@ -683,7 +683,7 @@ static void do_normal_probe(switch_event_t *event)
sofia_profile_t *profile;
//DUMP_EVENT(event);
-
+
if (!proto || strcasecmp(proto, SOFIA_CHAT_PROTO) != 0) {
return;
}
@@ -703,10 +703,10 @@ static void do_normal_probe(switch_event_t *event)
if (probe_euser && probe_host && (profile = sofia_glue_find_profile(probe_host))) {
sql = switch_mprintf("select state,status,rpid,presence_id,uuid from sip_dialogs "
"where hostname='%q' and profile_name='%q' and call_info_state != 'seized' and "
- "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
+ "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
mod_sofia_globals.hostname, profile->name, probe_euser, probe_host, probe_euser, probe_host);
-
-
+
+
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_dialog_callback, &dh);
h.profile = profile;
@@ -736,7 +736,7 @@ static void do_normal_probe(switch_event_t *event)
"sip_dialogs.presence_id = sip_registrations.sip_user %q '@' %q sip_registrations.sub_host "
"or (sip_dialogs.sip_from_user = sip_registrations.sip_user "
"and sip_dialogs.sip_from_host = sip_registrations.sip_host)) "
-
+
"left join sip_presence on "
"sip_presence.hostname=sip_registrations.hostname and "
"(sip_registrations.sip_user=sip_presence.sip_user and sip_registrations.orig_server_host=sip_presence.sip_host and "
@@ -748,11 +748,11 @@ static void do_normal_probe(switch_event_t *event)
dh.status, dh.rpid, switch_str_nil(sub_call_id),
switch_sql_concat(), switch_sql_concat(),
mod_sofia_globals.hostname, profile->name, probe_euser, probe_host, probe_euser, probe_host, probe_host);
-
-
+
+
switch_assert(sql);
-
+
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s START_PRESENCE_PROBE_SQL\n", profile->name);
}
@@ -762,19 +762,19 @@ static void do_normal_probe(switch_event_t *event)
}
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_resub_callback, &h);
- switch_safe_free(sql);
+ switch_safe_free(sql);
if (!h.rowcount) {
h.noreg++;
-
+
/* find ones with presence_id defined that are not registred */
sql = switch_mprintf("select sip_from_user, sip_from_host, 'Registered', '', '', "
"uuid, state, direction, "
"sip_to_user, sip_to_host,"
"'%q','%q',presence_id, '','','' "
-
+
"from sip_dialogs "
-
+
"where call_info_state != 'seized' and hostname='%q' and profile_name='%q' and (presence_id='%q@%q' or "
"(sip_from_user='%q' and (sip_from_host='%q' or sip_to_host='%q')))",
mod_sofia_globals.hostname, profile->name,
@@ -790,7 +790,7 @@ static void do_normal_probe(switch_event_t *event)
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_resub_callback, &h);
switch_safe_free(sql);
-
+
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s END_PRESENCE_PROBE_SQL\n\n", profile->name);
}
@@ -804,13 +804,13 @@ static void do_normal_probe(switch_event_t *event)
switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", probe_euser, probe_host);
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "status", "Unregistered");
switch_event_fire(&sevent);
- }
+ }
}
sofia_glue_release_profile(profile);
}
-
+
switch_safe_free(probe_user);
}
@@ -935,7 +935,7 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event
const char *body = switch_event_get_body(event);
const char *type = "application/conference-info+xml";
const char *final = switch_event_get_header(event, "final");
-
+
if (!event_str) {
event_str = "conference";
}
@@ -962,36 +962,36 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event
if (call_id) {
if (switch_true(final)) {
- sql = switch_mprintf("update sip_subscriptions set expires=%ld where "
- "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' "
- "and call_id = '%q' ",
- (long)0,
- mod_sofia_globals.hostname, profile->name,
- from_user, from_host, event_str, call_id);
+ sql = switch_mprintf("update sip_subscriptions set expires=%ld where "
+ "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' "
+ "and call_id = '%q' ",
+ (long)0,
+ mod_sofia_globals.hostname, profile->name,
+ from_user, from_host, event_str, call_id);
- sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+ sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, "
"'%q' as ct,'%q' as pt "
" from sip_subscriptions where "
"hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' "
- "and call_id = '%q' ",
+ "and call_id = '%q' ",
switch_sql_concat(),
type,
switch_str_nil(body),
mod_sofia_globals.hostname, profile->name,
from_user, from_host, event_str, call_id);
} else {
- if (switch_true(final)) {
- sql = switch_mprintf("update sip_subscriptions set expires=%ld where "
- "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'",
- (long)0,
- mod_sofia_globals.hostname, profile->name,
- from_user, from_host, event_str);
+ if (switch_true(final)) {
+ sql = switch_mprintf("update sip_subscriptions set expires=%ld where "
+ "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'",
+ (long)0,
+ mod_sofia_globals.hostname, profile->name,
+ from_user, from_host, event_str);
- sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
- }
+ sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+ }
sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, "
"'%q' as ct,'%q' as pt "
@@ -1014,7 +1014,7 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event
"and call_id = '%q' ",
mod_sofia_globals.hostname, profile->name,
from_user, from_host, event_str, call_id);
-
+
} else {
sql = switch_mprintf("delete from sip_subscriptions where "
"hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'",
@@ -1045,7 +1045,7 @@ static void conference_data_event_handler(switch_event_t *event)
if ((pname = switch_event_get_header(event, "sofia-profile"))) {
profile = sofia_glue_find_profile(pname);
}
-
+
if (host && !profile) {
profile = sofia_glue_find_profile(host);
}
@@ -1055,17 +1055,17 @@ static void conference_data_event_handler(switch_event_t *event)
sofia_glue_release_profile(profile);
} else {
switch_console_callback_match_t *matches;
-
+
if (list_profiles_full(NULL, NULL, &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
switch_console_callback_match_node_t *m;
-
+
for (m = matches->head; m; m = m->next) {
if ((profile = sofia_glue_find_profile(m->val))) {
send_conference_data(profile, event);
sofia_glue_release_profile(profile);
}
}
-
+
switch_console_free_matches(&matches);
}
}
@@ -1091,7 +1091,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
char *call_info_state = switch_event_get_header(event, "presence-call-info-state");
const char *uuid = switch_event_get_header(event, "unique-id");
switch_console_callback_match_t *matches = NULL;
- struct presence_helper helper = { 0 };
+ struct presence_helper helper = { 0 };
int hup = 0;
switch_event_t *s_event = NULL;
@@ -1135,25 +1135,25 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
if ((profile = sofia_glue_find_profile(m->val))) {
if (profile->pres_type != PRES_TYPE_FULL) {
-
+
if (!mod_sofia_globals.profile_hash) {
switch_console_free_matches(&matches);
goto done;
}
-
+
if (from) {
-
+
sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and "
"sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'",
mod_sofia_globals.hostname, profile->name, from);
-
+
if (mod_sofia_globals.debug_presence > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
}
-
+
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-
-
+
+
sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
"sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
@@ -1173,13 +1173,13 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and "
"sip_subscriptions.event='presence'", mod_sofia_globals.hostname, profile->name);
-
+
if (mod_sofia_globals.debug_presence > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
}
-
+
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-
+
sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
"sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
@@ -1196,9 +1196,9 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
"sip_subscriptions.event='presence'", switch_str_nil(status),
switch_str_nil(rpid), mod_sofia_globals.hostname, profile->name);
}
-
+
switch_assert(sql != NULL);
-
+
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s is passive, skipping\n", (char *) profile->name);
@@ -1216,7 +1216,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
}
switch_console_free_matches(&matches);
}
-
+
switch_safe_free(sql);
goto done;
}
@@ -1258,10 +1258,10 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
{
char *probe_type = switch_event_get_header(event, "probe-type");
- if (!probe_type || strcasecmp(probe_type, "dialog")) {
+ if (!probe_type || strcasecmp(probe_type, "dialog")) {
/* NORMAL PROBE */
do_normal_probe(event);
- } else {
+ } else {
/* DIALOG PROBE */
do_dialog_probe(event);
}
@@ -1270,7 +1270,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
default:
break;
- }
+ }
if (!mod_sofia_globals.profile_hash) {
goto done;
@@ -1299,8 +1299,8 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CHECK CALL_INFO [%s]\n", switch_str_nil(call_info));
}
- if (call_info) {
-
+ if (call_info) {
+
if (uuid) {
sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' where "
"hostname='%q' and profile_name='%q' and uuid='%q'",
@@ -1308,25 +1308,25 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
} else {
sql = switch_mprintf("update sip_dialogs set call_info='%q', call_info_state='%q' where hostname='%q' and profile_name='%q' and "
"((sip_dialogs.sip_from_user='%q' and sip_dialogs.sip_from_host='%q') or presence_id='%q@%q') and call_info='%q'",
-
+
call_info, call_info_state, mod_sofia_globals.hostname, profile->name, euser, host, euser, host, call_info);
-
+
}
-
+
if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STATE SQL %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-
+
if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PROCESS PRESENCE EVENT\n");
}
-
+
sync_sla(profile, euser, host, SWITCH_TRUE, SWITCH_TRUE, call_id);
}
-
+
if (!strcmp(proto, "dp")) {
sql = switch_mprintf("update sip_presence set rpid='%q',status='%q' where hostname='%q' and profile_name='%q' and "
"sip_user='%q' and sip_host='%q'",
@@ -1336,20 +1336,20 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
}
if (zstr(uuid)) {
-
+
sql = switch_mprintf("select state,status,rpid,presence_id,uuid from sip_dialogs "
"where call_info_state != 'seized' and hostname='%q' and profile_name='%q' and "
- "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
+ "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
mod_sofia_globals.hostname, profile->name, euser, host, euser, host);
} else {
sql = switch_mprintf("select state,status,rpid,presence_id,uuid from sip_dialogs "
"where uuid != '%q' and call_info_state != 'seized' and hostname='%q' and profile_name='%q' and "
- "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
+ "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
uuid, mod_sofia_globals.hostname, profile->name, euser, host, euser, host);
}
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_dialog_callback, &dh);
-
+
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "CHECK SQL: %s@%s [%s]\nhits: %d\n", euser, host, sql, dh.hits);
}
@@ -1366,29 +1366,29 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
if (rpid) {
rpid = sofia_presence_translate_rpid(rpid, status);
}
-
+
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "early");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", status);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", "EARLY");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "early");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "early");
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "early");
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "early");
} else {
status = "CS_EXECUTE";
if (rpid) {
rpid = sofia_presence_translate_rpid(rpid, status);
}
-
+
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "answered");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", status);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", "ACTIVE");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "confirmed");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "confirmed");
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "confirmed");
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "confirmed");
}
}
-
+
if (zstr(call_id) && (dh.hits && presence_source && (!strcasecmp(presence_source, "register") || switch_stristr("register", status)))) {
goto done;
@@ -1401,11 +1401,11 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
"and sip_subscriptions.proto='%q' and (event='%q' or event='%q') and sub_to_user='%q' and "
"(sub_to_host='%q' or sub_to_host='%q' or sub_to_host='%q' or "
"presence_hosts like '%%%q%%') and "
- "(sip_subscriptions.profile_name = '%q' or presence_hosts like '%%%q%%')",
+ "(sip_subscriptions.profile_name = '%q' or presence_hosts like '%%%q%%')",
mod_sofia_globals.hostname, profile->name,
proto, event_type, alt_event_type, euser, host, profile->sipip,
profile->extsipip ? profile->extsipip : "N/A", host, profile->name, host);
-
+
if (mod_sofia_globals.debug_presence > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
@@ -1414,7 +1414,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-
+
sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
"sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
@@ -1427,23 +1427,23 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
"left join sip_presence on "
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
"sip_subscriptions.profile_name=sip_presence.profile_name and sip_subscriptions.hostname=sip_presence.hostname) "
-
+
"where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and "
"sip_subscriptions.event != 'line-seize' and "
"sip_subscriptions.proto='%q' and "
"(event='%q' or event='%q') and sub_to_user='%q' "
"and (sub_to_host='%q' or sub_to_host='%q' or sub_to_host='%q' or presence_hosts like '%%%q%%') ",
-
-
+
+
switch_str_nil(status), switch_str_nil(rpid), host,
dh.status,dh.rpid,dh.presence_id, mod_sofia_globals.hostname, profile->name, proto,
- event_type, alt_event_type, euser, host, profile->sipip,
+ event_type, alt_event_type, euser, host, profile->sipip,
profile->extsipip ? profile->extsipip : "N/A", host);
} else {
sql = switch_mprintf("update sip_subscriptions set version=version+1 where sip_subscriptions.event != 'line-seize' and "
"sip_subscriptions.call_id='%q'", call_id);
-
+
if (mod_sofia_globals.debug_presence > 1) {
@@ -1465,23 +1465,23 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
"left join sip_presence on "
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
"sip_subscriptions.profile_name=sip_presence.profile_name and sip_subscriptions.hostname=sip_presence.hostname) "
-
+
"where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and "
"sip_subscriptions.event != 'line-seize' and "
"sip_subscriptions.call_id='%q'",
-
+
switch_str_nil(status), switch_str_nil(rpid), host,
dh.status,dh.rpid,dh.presence_id, mod_sofia_globals.hostname, profile->name, call_id);
}
-
+
helper.hup = hup;
helper.calls_up = dh.hits;
helper.profile = profile;
helper.event = event;
SWITCH_STANDARD_STREAM(helper.stream);
switch_assert(helper.stream.data);
-
+
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s START_PRESENCE_SQL (%s)\n",
event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name);
@@ -1501,14 +1501,14 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_sub_callback, &helper);
switch_safe_free(sql);
-
+
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s END_PRESENCE_SQL (%s)\n",
event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name);
}
#if 0
- if (hup && dh.hits < 1) {
+ if (hup && dh.hits < 1) {
/* so many phones get confused when whe hangup we have to reprobe to get them all to reset to absolute states so the lights stay correct */
if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
@@ -1520,13 +1520,13 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
sofia_event_fire(profile, &s_event);
}
}
-#endif
-
+#endif
+
if (!zstr((char *) helper.stream.data)) {
char *this_sql = (char *) helper.stream.data;
char *next = NULL;
char *last = NULL;
-
+
do {
if ((next = strchr(this_sql, ';'))) {
*next++ = '\0';
@@ -1534,7 +1534,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
*next++ = '\0';
}
}
-
+
if (!zstr(this_sql) && (!last || strcmp(last, this_sql))) {
sofia_glue_execute_sql(profile, &this_sql, SWITCH_FALSE);
last = this_sql;
@@ -1544,7 +1544,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event
}
switch_safe_free(helper.stream.data);
helper.stream.data = NULL;
-
+
sofia_glue_release_profile(profile);
}
}
@@ -2017,7 +2017,7 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char *
else if (proto && !strcasecmp(proto, "conf")) {
local_user = to_user;
local_user_param = switch_mprintf(";proto=%s", proto);
- if (skip_proto) {
+ if (skip_proto) {
buf_to_free = switch_mprintf("sip:%s@%s", to_user, host);
} else {
buf_to_free = switch_mprintf("sip:conf+%s@%s", to_user, host);
@@ -2082,9 +2082,9 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char *
#define send_presence_notify(_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l) \
_send_presence_notify(_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,__FILE__, __SWITCH_FUNC__, __LINE__)
-static void _send_presence_notify(sofia_profile_t *profile,
- const char *full_to,
- const char *full_from,
+static void _send_presence_notify(sofia_profile_t *profile,
+ const char *full_to,
+ const char *full_from,
const char *o_contact,
const char *expires,
const char *call_id,
@@ -2122,7 +2122,9 @@ static void _send_presence_notify(sofia_profile_t *profile,
cparams += 3;
}
- path = sofia_glue_get_path_from_contact((char *) o_contact);
+ if (!switch_stristr("fs_nat=yes", o_contact)) {
+ path = sofia_glue_get_path_from_contact((char *) o_contact);
+ }
tmp = (char *)o_contact;
o_contact_dup = sofia_glue_get_url_from_contact(tmp, 1);
@@ -2141,10 +2143,10 @@ static void _send_presence_notify(sofia_profile_t *profile,
our_contact = our_contact_dup;
}
-
+
if (!zstr(remote_ip) && sofia_glue_check_nat(profile, remote_ip)) {
char *ptr = NULL;
-
+
if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) {
sofia_transport_t transport = sofia_glue_str2transport(ptr);
@@ -2168,22 +2170,22 @@ static void _send_presence_notify(sofia_profile_t *profile,
} else {
contact_str = our_contact;
}
-
-
+
+
if ((to_uri = sofia_glue_get_url_from_contact((char *)full_to, 1))) {
char *p;
-
+
if ((p = strstr(to_uri, "sip:"))) {
char *q;
-
+
p += 4;
if ((q = strchr(p, '@'))) {
*q++ = '\0';
-
+
if ((dcs = switch_string_replace(contact_str, "mod_sofia", p))) {
contact_str = dcs;
}
-
+
}
}
@@ -2198,7 +2200,7 @@ static void _send_presence_notify(sofia_profile_t *profile,
} else {
contact = strdup(o_contact);
}
-
+
if (dst->route_uri) {
route_uri = sofia_glue_strip_uri(dst->route_uri);
} else {
@@ -2209,7 +2211,7 @@ static void _send_presence_notify(sofia_profile_t *profile,
if (expires) {
long ltmp = atol(expires);
-
+
if (ltmp > 0) {
exptime = (ltmp - now);
} else {
@@ -2248,14 +2250,14 @@ static void _send_presence_notify(sofia_profile_t *profile,
);
}
-
+
switch_mutex_lock(profile->ireg_mutex);
if (!profile->cseq_base) {
profile->cseq_base = (now - 1312693200) * 10;
}
callsequence = ++profile->cseq_base;
switch_mutex_unlock(profile->ireg_mutex);
-
+
if (cparams) {
send_contact = switch_mprintf("%s;%s", contact_str, cparams);
contact_str = send_contact;
@@ -2270,25 +2272,25 @@ static void _send_presence_notify(sofia_profile_t *profile,
nua_notify(nh,
NUTAG_NEWSUB(1),
- TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
+ TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
TAG_IF(path, SIPTAG_RECORD_ROUTE_STR(path)),
-
+
SIPTAG_FROM_STR(full_to),
SIPTAG_TO_STR(full_from),
-
+
SIPTAG_CALL_ID_STR(call_id),
TAG_IF(*expires_str, SIPTAG_EXPIRES_STR(expires_str)),
- SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
- SIPTAG_EVENT_STR(event),
+ SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
+ SIPTAG_EVENT_STR(event),
TAG_IF(!zstr(ct), SIPTAG_CONTENT_TYPE_STR(ct)),
TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)),
TAG_IF(!zstr(call_info), SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(!exptime, SIPTAG_EXPIRES_STR("0")),
SIPTAG_CSEQ(cseq),
TAG_END());
-
+
switch_safe_free(route_uri);
switch_safe_free(dcs);
@@ -2320,20 +2322,20 @@ static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv,
char *contact = argv[9];
char *remote_ip = argv[10];
char *remote_port = argv[11];
-
+
switch_stream_handle_t stream = { 0 };
char *to;
const char *pl = NULL;
const char *ct = "application/dialog-info+xml";
if (mod_sofia_globals.debug_presence > 0) {
- int i;
+ int i;
for(i = 0; i < argc; i++) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]);
}
}
-
+
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
"SEND DIALOG\nTo: \t%s@%s\nFrom: \t%s@%s\nCall-ID: \t%s\n",
@@ -2372,9 +2374,9 @@ static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv,
}
- send_presence_notify(sh->profile,
- full_to,
- full_from,
+ send_presence_notify(sh->profile,
+ full_to,
+ full_from,
contact,
expires,
call_id,
@@ -2460,13 +2462,13 @@ static char *gen_pidf(char *user_agent, char *id, char *url, char *open, char *r
" \n"
" \n"
" \n"
- " \n"
- " \n"
- " \n"
+ " \n"
+ " \n"
+ " \n"
"\n", status, id, id, url, open, prpid);
} else {
char *xml_rpid = NULL;
-
+
*ct = "application/pidf+xml";
if (!strcasecmp(open, "closed")) {
@@ -2477,7 +2479,7 @@ static char *gen_pidf(char *user_agent, char *id, char *url, char *open, char *r
if (!strncasecmp(status, "Registered", 10)) {
status = "Available";
}
-
+
if (!strcasecmp(status, "Available")) {
prpid = NULL;
}
@@ -2497,7 +2499,7 @@ static char *gen_pidf(char *user_agent, char *id, char *url, char *open, char *r
status = "Available";
prpid = NULL;
}
-
+
if (prpid) {
xml_rpid = switch_mprintf(" \r\n"
" \n"
@@ -2517,9 +2519,9 @@ static char *gen_pidf(char *user_agent, char *id, char *url, char *open, char *r
" \n"
"%s"
" %s\n"
- " \n"
+ " \n"
"", id, open, switch_str_nil(xml_rpid), status);
-
+
switch_safe_free(xml_rpid);
}
@@ -2582,7 +2584,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (mod_sofia_globals.debug_presence > 0) {
- int i;
+ int i;
for(i = 0; i < argc; i++) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]);
}
@@ -2613,7 +2615,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (!zstr(presence_id) && strchr(presence_id, '@')) {
char *p;
-
+
free_me = strdup(presence_id);
if ((p = strchr(free_me, '@'))) {
@@ -2622,7 +2624,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
user = free_me;
}
-
+
if (!zstr(orig_proto) && !strcmp(orig_proto, SOFIA_CHAT_PROTO)) {
skip_proto = 1;
@@ -2668,7 +2670,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (!rpid) {
rpid = "unknown";
}
-
+
// if (!strcasecmp(proto, SOFIA_CHAT_PROTO) || skip_proto) {
// clean_id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
//} else {
@@ -2736,7 +2738,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
//if (user_agent && switch_stristr("snom", user_agent) && uuid) {
// default_dialog = "full" ;
//}
-
+
if (call_state && !strcasecmp(call_state, "cs_hangup")) {
astate = "hangup";
holding = 0;
@@ -2758,7 +2760,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (!strcasecmp(direction, "inbound")) {
from_id = switch_str_nil(switch_event_get_header(helper->event, "Caller-Destination-Number"));
-
+
} else {
from_id = switch_str_nil(switch_event_get_header(helper->event, "Caller-Caller-ID-Number"));
from_name = switch_event_get_header(helper->event, "Caller-Caller-ID-Name");
@@ -2770,7 +2772,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (zstr(from_name)) {
from_name = switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Name");
}
-
+
}
#if 0
@@ -2784,7 +2786,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (is_dialog) {
SWITCH_STANDARD_STREAM(stream);
}
-
+
if (is_dialog) {
// Usually we report the dialogs FROM the probed user. The exception is when the monitored endpoint is internal,
// and its presence_id is set in the dialplan. Reverse the direction if this is not a registered entity.
@@ -2815,14 +2817,14 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
"\n"
"\n", version, default_dialog, clean_id);
-
+
}
if (!zstr(uuid)) {
if (!zstr(answer_state)) {
astate = answer_state;
}
-
+
if (zstr(astate)) {
if (is_dialog) {
astate = dft_state;
@@ -2834,8 +2836,8 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (!strcasecmp(astate, "answered")) {
astate = "confirmed";
}
-
-
+
+
if (is_dialog) {
if (!strcasecmp(astate, "ringing")) {
@@ -2860,7 +2862,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (!strcasecmp(astate, "hangup")) {
astate = "terminated";
}
-
+
stream.write_function(&stream, "