mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-24 05:02:10 +00:00
Merge branch 'smgmaster' into releases.3.4.experimental_head
Conflicts: libs/freetdm/mod_freetdm/mod_freetdm.c libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c src/mod/endpoints/mod_sofia/mod_sofia.c src/mod/endpoints/mod_sofia/sofia_glue.c
This commit is contained in:
+414
-658
File diff suppressed because it is too large
Load Diff
@@ -304,7 +304,8 @@ typedef enum {
|
||||
CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
|
||||
CURLE_FAILED_INIT, /* 2 */
|
||||
CURLE_URL_MALFORMAT, /* 3 */
|
||||
CURLE_URL_MALFORMAT_USER, /* 4 - NOT USED */
|
||||
CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for
|
||||
7.17.0, reused in April 2011 for 7.21.5] */
|
||||
CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
|
||||
CURLE_COULDNT_RESOLVE_HOST, /* 6 */
|
||||
CURLE_COULDNT_CONNECT, /* 7 */
|
||||
|
||||
@@ -1190,8 +1190,13 @@ Curl_ossl_connect_step1(struct connectdata *conn,
|
||||
req_method = TLSv1_client_method();
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv2:
|
||||
#ifdef OPENSSL_NO_SSL2
|
||||
failf(data, "OpenSSL was built without SSLv2 support");
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#else
|
||||
req_method = SSLv2_client_method();
|
||||
break;
|
||||
#endif
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
req_method = SSLv3_client_method();
|
||||
break;
|
||||
|
||||
@@ -69,6 +69,10 @@ curl_easy_strerror(CURLcode error)
|
||||
case CURLE_URL_MALFORMAT:
|
||||
return "URL using bad/illegal format or missing URL";
|
||||
|
||||
case CURLE_NOT_BUILT_IN:
|
||||
return "A requested feature, protocol or option was not found built-in in"
|
||||
" this libcurl due to a build-time decision.";
|
||||
|
||||
case CURLE_COULDNT_RESOLVE_PROXY:
|
||||
return "couldn't resolve proxy name";
|
||||
|
||||
@@ -278,7 +282,6 @@ curl_easy_strerror(CURLcode error)
|
||||
return "caller must register CURLOPT_CONV_ callback options";
|
||||
|
||||
/* error codes not used by current libcurl */
|
||||
case CURLE_URL_MALFORMAT_USER:
|
||||
case CURLE_FTP_USER_PASSWORD_INCORRECT:
|
||||
case CURLE_MALFORMAT_USER:
|
||||
case CURLE_BAD_CALLING_ORDER:
|
||||
|
||||
+4
-4
@@ -3,11 +3,11 @@ INCS=-I$(PWD)/src/include
|
||||
LIBEDIT_DIR=../../libs/libedit
|
||||
DEBUG=-g -ggdb
|
||||
BASE_FLAGS=$(INCS) -DHAVE_EDITLINE $(DEBUG) -I$(LIBEDIT_DIR)/src/ -fPIC
|
||||
PICKY=-O2 -ffast-math -Wall -Werror -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes
|
||||
PICKY=-O2
|
||||
CFLAGS=$(BASE_FLAGS) $(PICKY)
|
||||
CXXFLAGS=$(BASE_FLAGS) -Wall -Werror -Wno-unused-variable
|
||||
CXXFLAGS=$(BASE_FLAGS)
|
||||
MYLIB=libesl.a
|
||||
LIBS=-lncurses -lpthread -lesl -lm
|
||||
LIBS=-lncurses -lesl -lpthread -lm
|
||||
LDFLAGS=-L.
|
||||
OBJS=src/esl.o src/esl_event.o src/esl_threadmutex.o src/esl_config.o src/esl_json.o src/esl_buffer.o
|
||||
SRC=src/esl.c src/esl_json.c src/esl_event.c src/esl_threadmutex.c src/esl_config.c src/esl_oop.cpp src/esl_json.c src/esl_buffer.c
|
||||
@@ -32,7 +32,7 @@ testclient: $(MYLIB) testclient.c
|
||||
$(CC) $(CC_CFLAGS) $(CFLAGS) testclient.c -o testclient $(LDFLAGS) $(LIBS)
|
||||
|
||||
fs_cli: $(MYLIB) fs_cli.c
|
||||
$(CC) $(CC_CFLAGS) $(CFLAGS) fs_cli.c -o fs_cli $(LDFLAGS) -L$(LIBEDIT_DIR)/src/.libs $(LIBS) -ledit
|
||||
$(CC) $(CC_CFLAGS) $(CFLAGS) fs_cli.c -o fs_cli $(LDFLAGS) -L$(LIBEDIT_DIR)/src/.libs -ledit $(LIBS)
|
||||
|
||||
%.o: %.c $(HEADERS)
|
||||
$(CC) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@
|
||||
|
||||
+507
-494
File diff suppressed because it is too large
Load Diff
+1
-8
@@ -42,11 +42,6 @@ static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struc
|
||||
char path_buffer[1024] = { 0 };
|
||||
const char *path;
|
||||
|
||||
if (fork()) {
|
||||
close(client_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (esl_attach_handle(&handle, client_sock, addr) != ESL_SUCCESS || !handle.info_event) {
|
||||
esl_log(ESL_LOG_ERROR, "Socket Error\n");
|
||||
exit(0);
|
||||
@@ -95,9 +90,7 @@ int main(int argc, char *argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
|
||||
esl_listen(ip, port, mycallback);
|
||||
esl_listen(ip, port, mycallback, 100000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -904,6 +904,31 @@ SWIGEXPORT jlong JNICALL Java_org_freeswitch_esl_eslJNI_ESLconnection_1sendEvent
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT jint JNICALL Java_org_freeswitch_esl_eslJNI_ESLconnection_1sendMSG(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jstring jarg3) {
|
||||
jint jresult = 0 ;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
|
||||
(void)jenv;
|
||||
(void)jcls;
|
||||
(void)jarg1_;
|
||||
(void)jarg2_;
|
||||
arg1 = *(ESLconnection **)&jarg1;
|
||||
arg2 = *(ESLevent **)&jarg2;
|
||||
arg3 = 0;
|
||||
if (jarg3) {
|
||||
arg3 = (char *)jenv->GetStringUTFChars(jarg3, 0);
|
||||
if (!arg3) return 0;
|
||||
}
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
jresult = (jint)result;
|
||||
if (arg3) jenv->ReleaseStringUTFChars(jarg3, (const char *)arg3);
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT jlong JNICALL Java_org_freeswitch_esl_eslJNI_ESLconnection_1recvEvent(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) {
|
||||
jlong jresult = 0 ;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
|
||||
@@ -82,6 +82,10 @@ public class ESLconnection {
|
||||
return (cPtr == 0) ? null : new ESLevent(cPtr, true);
|
||||
}
|
||||
|
||||
public int sendMSG(ESLevent send_me, String uuid) {
|
||||
return eslJNI.ESLconnection_sendMSG(swigCPtr, this, ESLevent.getCPtr(send_me), send_me, uuid);
|
||||
}
|
||||
|
||||
public ESLevent recvEvent() {
|
||||
long cPtr = eslJNI.ESLconnection_recvEvent(swigCPtr, this);
|
||||
return (cPtr == 0) ? null : new ESLevent(cPtr, true);
|
||||
|
||||
@@ -43,6 +43,7 @@ class eslJNI {
|
||||
public final static native long ESLconnection_api(long jarg1, ESLconnection jarg1_, String jarg2, String jarg3);
|
||||
public final static native long ESLconnection_bgapi(long jarg1, ESLconnection jarg1_, String jarg2, String jarg3, String jarg4);
|
||||
public final static native long ESLconnection_sendEvent(long jarg1, ESLconnection jarg1_, long jarg2, ESLevent jarg2_);
|
||||
public final static native int ESLconnection_sendMSG(long jarg1, ESLconnection jarg1_, long jarg2, ESLevent jarg2_, String jarg3);
|
||||
public final static native long ESLconnection_recvEvent(long jarg1, ESLconnection jarg1_);
|
||||
public final static native long ESLconnection_recvEventTimed(long jarg1, ESLconnection jarg1_, int jarg2);
|
||||
public final static native long ESLconnection_filter(long jarg1, ESLconnection jarg1_, String jarg2, String jarg3);
|
||||
|
||||
@@ -2632,6 +2632,43 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
static int _wrap_ESLconnection_sendMSG(lua_State* L) {
|
||||
int SWIG_arg = -1;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
|
||||
SWIG_check_num_args("sendMSG",2,3)
|
||||
if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("sendMSG",1,"ESLconnection *");
|
||||
if(!SWIG_isptrtype(L,2)) SWIG_fail_arg("sendMSG",2,"ESLevent *");
|
||||
if(lua_gettop(L)>=3 && !lua_isstring(L,3)) SWIG_fail_arg("sendMSG",3,"char const *");
|
||||
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){
|
||||
SWIG_fail_ptr("ESLconnection_sendMSG",1,SWIGTYPE_p_ESLconnection);
|
||||
}
|
||||
|
||||
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr(L,2,(void**)&arg2,SWIGTYPE_p_ESLevent,0))){
|
||||
SWIG_fail_ptr("ESLconnection_sendMSG",2,SWIGTYPE_p_ESLevent);
|
||||
}
|
||||
|
||||
if(lua_gettop(L)>=3){
|
||||
arg3 = (char *)lua_tostring(L, 3);
|
||||
}
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
SWIG_arg=0;
|
||||
lua_pushnumber(L, (lua_Number) result); SWIG_arg++;
|
||||
return SWIG_arg;
|
||||
|
||||
if(0) SWIG_fail;
|
||||
|
||||
fail:
|
||||
lua_error(L);
|
||||
return SWIG_arg;
|
||||
}
|
||||
|
||||
|
||||
static int _wrap_ESLconnection_recvEvent(lua_State* L) {
|
||||
int SWIG_arg = -1;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
@@ -2917,6 +2954,7 @@ static swig_lua_method swig_ESLconnection_methods[] = {
|
||||
{"api", _wrap_ESLconnection_api},
|
||||
{"bgapi", _wrap_ESLconnection_bgapi},
|
||||
{"sendEvent", _wrap_ESLconnection_sendEvent},
|
||||
{"sendMSG", _wrap_ESLconnection_sendMSG},
|
||||
{"recvEvent", _wrap_ESLconnection_recvEvent},
|
||||
{"recvEventTimed", _wrap_ESLconnection_recvEventTimed},
|
||||
{"filter", _wrap_ESLconnection_filter},
|
||||
|
||||
@@ -286,6 +286,9 @@ class ESLPINVOKE {
|
||||
[DllImport("ESL", EntryPoint="CSharp_ESLconnection_SendEvent")]
|
||||
public static extern IntPtr ESLconnection_SendEvent(HandleRef jarg1, HandleRef jarg2);
|
||||
|
||||
[DllImport("ESL", EntryPoint="CSharp_ESLconnection_sendMSG")]
|
||||
public static extern int ESLconnection_sendMSG(HandleRef jarg1, HandleRef jarg2, string jarg3);
|
||||
|
||||
[DllImport("ESL", EntryPoint="CSharp_ESLconnection_RecvEvent")]
|
||||
public static extern IntPtr ESLconnection_RecvEvent(HandleRef jarg1);
|
||||
|
||||
|
||||
@@ -92,6 +92,11 @@ public class ESLconnection : IDisposable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int sendMSG(ESLevent send_me, string uuid) {
|
||||
int ret = ESLPINVOKE.ESLconnection_sendMSG(swigCPtr, ESLevent.getCPtr(send_me), uuid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ESLevent RecvEvent() {
|
||||
IntPtr cPtr = ESLPINVOKE.ESLconnection_RecvEvent(swigCPtr);
|
||||
ESLevent ret = (cPtr == IntPtr.Zero) ? null : new ESLevent(cPtr, true);
|
||||
|
||||
@@ -743,6 +743,22 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_ESLconnection_SendEvent(void * jarg1, void
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_ESLconnection_sendMSG(void * jarg1, void * jarg2, char * jarg3) {
|
||||
int jresult ;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
|
||||
arg1 = (ESLconnection *)jarg1;
|
||||
arg2 = (ESLevent *)jarg2;
|
||||
arg3 = (char *)jarg3;
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
jresult = result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void * SWIGSTDCALL CSharp_ESLconnection_RecvEvent(void * jarg1) {
|
||||
void * jresult ;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
|
||||
@@ -138,6 +138,7 @@ sub DESTROY {
|
||||
*api = *ESLc::ESLconnection_api;
|
||||
*bgapi = *ESLc::ESLconnection_bgapi;
|
||||
*sendEvent = *ESLc::ESLconnection_sendEvent;
|
||||
*sendMSG = *ESLc::ESLconnection_sendMSG;
|
||||
*recvEvent = *ESLc::ESLconnection_recvEvent;
|
||||
*recvEventTimed = *ESLc::ESLconnection_recvEventTimed;
|
||||
*filter = *ESLc::ESLconnection_filter;
|
||||
|
||||
@@ -3282,6 +3282,57 @@ XS(_wrap_ESLconnection_sendEvent) {
|
||||
}
|
||||
|
||||
|
||||
XS(_wrap_ESLconnection_sendMSG) {
|
||||
{
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
void *argp1 = 0 ;
|
||||
int res1 = 0 ;
|
||||
void *argp2 = 0 ;
|
||||
int res2 = 0 ;
|
||||
int res3 ;
|
||||
char *buf3 = 0 ;
|
||||
int alloc3 = 0 ;
|
||||
int argvi = 0;
|
||||
dXSARGS;
|
||||
|
||||
if ((items < 2) || (items > 3)) {
|
||||
SWIG_croak("Usage: ESLconnection_sendMSG(self,send_me,uuid);");
|
||||
}
|
||||
res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_ESLconnection, 0 | 0 );
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ESLconnection_sendMSG" "', argument " "1"" of type '" "ESLconnection *""'");
|
||||
}
|
||||
arg1 = reinterpret_cast< ESLconnection * >(argp1);
|
||||
res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_ESLevent, 0 | 0 );
|
||||
if (!SWIG_IsOK(res2)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ESLconnection_sendMSG" "', argument " "2"" of type '" "ESLevent *""'");
|
||||
}
|
||||
arg2 = reinterpret_cast< ESLevent * >(argp2);
|
||||
if (items > 2) {
|
||||
res3 = SWIG_AsCharPtrAndSize(ST(2), &buf3, NULL, &alloc3);
|
||||
if (!SWIG_IsOK(res3)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ESLconnection_sendMSG" "', argument " "3"" of type '" "char const *""'");
|
||||
}
|
||||
arg3 = reinterpret_cast< char * >(buf3);
|
||||
}
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
ST(argvi) = SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ;
|
||||
|
||||
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
XSRETURN(argvi);
|
||||
fail:
|
||||
|
||||
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
SWIG_croak_null();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XS(_wrap_ESLconnection_recvEvent) {
|
||||
{
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
@@ -3785,6 +3836,7 @@ static swig_command_info swig_commands[] = {
|
||||
{"ESLc::ESLconnection_api", _wrap_ESLconnection_api},
|
||||
{"ESLc::ESLconnection_bgapi", _wrap_ESLconnection_bgapi},
|
||||
{"ESLc::ESLconnection_sendEvent", _wrap_ESLconnection_sendEvent},
|
||||
{"ESLc::ESLconnection_sendMSG", _wrap_ESLconnection_sendMSG},
|
||||
{"ESLc::ESLconnection_recvEvent", _wrap_ESLconnection_recvEvent},
|
||||
{"ESLc::ESLconnection_recvEventTimed", _wrap_ESLconnection_recvEventTimed},
|
||||
{"ESLc::ESLconnection_filter", _wrap_ESLconnection_filter},
|
||||
|
||||
@@ -174,6 +174,14 @@ class ESLconnection {
|
||||
return is_resource($r) ? new ESLevent($r) : $r;
|
||||
}
|
||||
|
||||
function sendMSG($send_me,$uuid=null) {
|
||||
switch (func_num_args()) {
|
||||
case 1: $r=ESLconnection_sendMSG($this->_cPtr,$send_me); break;
|
||||
default: $r=ESLconnection_sendMSG($this->_cPtr,$send_me,$uuid);
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
function recvEvent() {
|
||||
$r=ESLconnection_recvEvent($this->_cPtr);
|
||||
return is_resource($r) ? new ESLevent($r) : $r;
|
||||
|
||||
@@ -2244,6 +2244,48 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_sendMSG) {
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
zval **args[3];
|
||||
int arg_count;
|
||||
|
||||
SWIG_ResetError();
|
||||
arg_count = ZEND_NUM_ARGS();
|
||||
if(arg_count<2 || arg_count>3 ||
|
||||
zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)
|
||||
WRONG_PARAM_COUNT;
|
||||
|
||||
{
|
||||
if(SWIG_ConvertPtr(*args[0], (void **) &arg1, SWIGTYPE_p_ESLconnection, 0) < 0) {
|
||||
SWIG_PHP_Error(E_ERROR, "Type error in argument 1 of ESLconnection_sendMSG. Expected SWIGTYPE_p_ESLconnection");
|
||||
}
|
||||
}
|
||||
if(!arg1) SWIG_PHP_Error(E_ERROR, "this pointer is NULL");
|
||||
{
|
||||
if(SWIG_ConvertPtr(*args[1], (void **) &arg2, SWIGTYPE_p_ESLevent, 0) < 0) {
|
||||
SWIG_PHP_Error(E_ERROR, "Type error in argument 2 of ESLconnection_sendMSG. Expected SWIGTYPE_p_ESLevent");
|
||||
}
|
||||
}
|
||||
if(arg_count > 2) {
|
||||
/*@SWIG:/usr/local/share/swig/1.3.35/php4/utils.i,26,CONVERT_STRING_IN@*/
|
||||
convert_to_string_ex(args[2]);
|
||||
arg3 = (char *) Z_STRVAL_PP(args[2]);
|
||||
/*@SWIG@*/;
|
||||
|
||||
}
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
{
|
||||
ZVAL_LONG(return_value,result);
|
||||
}
|
||||
return;
|
||||
fail:
|
||||
zend_error(SWIG_ErrorCode(),SWIG_ErrorMsg());
|
||||
}
|
||||
|
||||
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_recvEvent) {
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *result = 0 ;
|
||||
@@ -2651,6 +2693,7 @@ static zend_function_entry ESL_functions[] = {
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_api,_wrap_ESLconnection_api,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_bgapi,_wrap_ESLconnection_bgapi,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_sendevent,_wrap_ESLconnection_sendEvent,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_sendmsg,_wrap_ESLconnection_sendMSG,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_recvevent,_wrap_ESLconnection_recvEvent,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_recveventtimed,_wrap_ESLconnection_recvEventTimed,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_filter,_wrap_ESLconnection_filter,NULL)
|
||||
|
||||
@@ -60,6 +60,7 @@ ZEND_NAMED_FUNCTION(_wrap_ESLconnection_sendRecv);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_api);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_bgapi);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_sendEvent);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_sendMSG);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_recvEvent);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_recvEventTimed);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_filter);
|
||||
|
||||
@@ -87,6 +87,7 @@ class ESLconnection:
|
||||
def api(*args): return apply(_ESL.ESLconnection_api, args)
|
||||
def bgapi(*args): return apply(_ESL.ESLconnection_bgapi, args)
|
||||
def sendEvent(*args): return apply(_ESL.ESLconnection_sendEvent, args)
|
||||
def sendMSG(*args): return apply(_ESL.ESLconnection_sendMSG, args)
|
||||
def recvEvent(*args): return apply(_ESL.ESLconnection_recvEvent, args)
|
||||
def recvEventTimed(*args): return apply(_ESL.ESLconnection_recvEventTimed, args)
|
||||
def filter(*args): return apply(_ESL.ESLconnection_filter, args)
|
||||
|
||||
@@ -4370,6 +4370,58 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN PyObject *_wrap_ESLconnection_sendMSG(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||
PyObject *resultobj = 0;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
void *argp1 = 0 ;
|
||||
int res1 = 0 ;
|
||||
void *argp2 = 0 ;
|
||||
int res2 = 0 ;
|
||||
int res3 ;
|
||||
char *buf3 = 0 ;
|
||||
int alloc3 = 0 ;
|
||||
PyObject * obj0 = 0 ;
|
||||
PyObject * obj1 = 0 ;
|
||||
PyObject * obj2 = 0 ;
|
||||
|
||||
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
|
||||
if (!PyArg_ParseTuple(args,(char *)"OO|O:ESLconnection_sendMSG",&obj0,&obj1,&obj2)) SWIG_fail;
|
||||
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ESLconnection, 0 | 0 );
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ESLconnection_sendMSG" "', argument " "1"" of type '" "ESLconnection *""'");
|
||||
}
|
||||
arg1 = reinterpret_cast< ESLconnection * >(argp1);
|
||||
res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ESLevent, 0 | 0 );
|
||||
if (!SWIG_IsOK(res2)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ESLconnection_sendMSG" "', argument " "2"" of type '" "ESLevent *""'");
|
||||
}
|
||||
arg2 = reinterpret_cast< ESLevent * >(argp2);
|
||||
if (obj2) {
|
||||
res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
|
||||
if (!SWIG_IsOK(res3)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ESLconnection_sendMSG" "', argument " "3"" of type '" "char const *""'");
|
||||
}
|
||||
arg3 = reinterpret_cast< char * >(buf3);
|
||||
}
|
||||
{
|
||||
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
SWIG_PYTHON_THREAD_END_ALLOW;
|
||||
}
|
||||
resultobj = SWIG_From_int(static_cast< int >(result));
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
SWIG_PYTHON_THREAD_END_BLOCK;
|
||||
return resultobj;
|
||||
fail:
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
SWIG_PYTHON_THREAD_END_BLOCK;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN PyObject *_wrap_ESLconnection_recvEvent(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||
PyObject *resultobj = 0;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
@@ -4859,6 +4911,7 @@ static PyMethodDef SwigMethods[] = {
|
||||
{ (char *)"ESLconnection_api", _wrap_ESLconnection_api, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_bgapi", _wrap_ESLconnection_bgapi, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_sendEvent", _wrap_ESLconnection_sendEvent, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_sendMSG", _wrap_ESLconnection_sendMSG, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_recvEvent", _wrap_ESLconnection_recvEvent, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_recvEventTimed", _wrap_ESLconnection_recvEventTimed, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_filter", _wrap_ESLconnection_filter, METH_VARARGS, NULL},
|
||||
|
||||
@@ -3245,6 +3245,51 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN VALUE
|
||||
_wrap_ESLconnection_sendMSG(int argc, VALUE *argv, VALUE self) {
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
void *argp1 = 0 ;
|
||||
int res1 = 0 ;
|
||||
void *argp2 = 0 ;
|
||||
int res2 = 0 ;
|
||||
int res3 ;
|
||||
char *buf3 = 0 ;
|
||||
int alloc3 = 0 ;
|
||||
VALUE vresult = Qnil;
|
||||
|
||||
if ((argc < 1) || (argc > 2)) {
|
||||
rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
|
||||
}
|
||||
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ESLconnection, 0 | 0 );
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "ESLconnection *","sendMSG", 1, self ));
|
||||
}
|
||||
arg1 = reinterpret_cast< ESLconnection * >(argp1);
|
||||
res2 = SWIG_ConvertPtr(argv[0], &argp2,SWIGTYPE_p_ESLevent, 0 | 0 );
|
||||
if (!SWIG_IsOK(res2)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "ESLevent *","sendMSG", 2, argv[0] ));
|
||||
}
|
||||
arg2 = reinterpret_cast< ESLevent * >(argp2);
|
||||
if (argc > 1) {
|
||||
res3 = SWIG_AsCharPtrAndSize(argv[1], &buf3, NULL, &alloc3);
|
||||
if (!SWIG_IsOK(res3)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res3), Ruby_Format_TypeError( "", "char const *","sendMSG", 3, argv[1] ));
|
||||
}
|
||||
arg3 = reinterpret_cast< char * >(buf3);
|
||||
}
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
vresult = SWIG_From_int(static_cast< int >(result));
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
return vresult;
|
||||
fail:
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN VALUE
|
||||
_wrap_ESLconnection_recvEvent(int argc, VALUE *argv, VALUE self) {
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
@@ -3958,6 +4003,7 @@ SWIGEXPORT void Init_ESL(void) {
|
||||
rb_define_method(cESLconnection.klass, "api", VALUEFUNC(_wrap_ESLconnection_api), -1);
|
||||
rb_define_method(cESLconnection.klass, "bgapi", VALUEFUNC(_wrap_ESLconnection_bgapi), -1);
|
||||
rb_define_method(cESLconnection.klass, "sendEvent", VALUEFUNC(_wrap_ESLconnection_sendEvent), -1);
|
||||
rb_define_method(cESLconnection.klass, "sendMSG", VALUEFUNC(_wrap_ESLconnection_sendMSG), -1);
|
||||
rb_define_method(cESLconnection.klass, "recvEvent", VALUEFUNC(_wrap_ESLconnection_recvEvent), -1);
|
||||
rb_define_method(cESLconnection.klass, "recvEventTimed", VALUEFUNC(_wrap_ESLconnection_recvEventTimed), -1);
|
||||
rb_define_method(cESLconnection.klass, "filter", VALUEFUNC(_wrap_ESLconnection_filter), -1);
|
||||
|
||||
+88
-5
@@ -53,10 +53,18 @@
|
||||
#ifndef WIN32
|
||||
#define closesocket(x) close(x)
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#else
|
||||
#pragma warning (disable:6386)
|
||||
/* These warnings need to be ignored warning in sdk header */
|
||||
#include <Ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#ifndef errno
|
||||
#define errno WSAGetLastError()
|
||||
#endif
|
||||
#ifndef EINTR
|
||||
#define EINTR WSAEINTR
|
||||
#endif
|
||||
#pragma warning (default:6386)
|
||||
#endif
|
||||
|
||||
@@ -534,6 +542,39 @@ ESL_DECLARE(esl_status_t) esl_execute(esl_handle_t *handle, const char *app, con
|
||||
}
|
||||
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_sendmsg(esl_handle_t *handle, esl_event_t *event, const char *uuid)
|
||||
{
|
||||
char cmd_buf[128] = "sendmsg\n";
|
||||
char *txt;
|
||||
|
||||
if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
|
||||
return ESL_FAIL;
|
||||
}
|
||||
|
||||
if (uuid) {
|
||||
snprintf(cmd_buf, sizeof(cmd_buf), "sendmsg %s\n", uuid);
|
||||
}
|
||||
|
||||
esl_event_serialize(event, &txt, ESL_FALSE);
|
||||
esl_log(ESL_LOG_DEBUG, "%s%s\n", cmd_buf, txt);
|
||||
|
||||
if (send(handle->sock, cmd_buf, strlen(cmd_buf), 0) <= 0) goto fail;
|
||||
if (send(handle->sock, txt, strlen(txt), 0) <= 0) goto fail;
|
||||
|
||||
free(txt);
|
||||
|
||||
return esl_recv(handle);
|
||||
|
||||
fail:
|
||||
|
||||
handle->connected = 0;
|
||||
|
||||
free(txt);
|
||||
|
||||
return ESL_FAIL;
|
||||
}
|
||||
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_filter(esl_handle_t *handle, const char *header, const char *value)
|
||||
{
|
||||
char send_buf[1024] = "";
|
||||
@@ -579,12 +620,31 @@ static int esl_socket_reuseaddr(esl_socket_t socket)
|
||||
#endif
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback)
|
||||
struct thread_handler {
|
||||
esl_listen_callback_t callback;
|
||||
esl_socket_t server_sock;
|
||||
esl_socket_t client_sock;
|
||||
struct sockaddr_in addr;
|
||||
};
|
||||
|
||||
static void *client_thread(esl_thread_t *me, void *obj)
|
||||
{
|
||||
struct thread_handler *handler = (struct thread_handler *) obj;
|
||||
|
||||
handler->callback(handler->server_sock, handler->client_sock, &handler->addr);
|
||||
free(handler);
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback, int max)
|
||||
{
|
||||
esl_socket_t server_sock = ESL_SOCK_INVALID;
|
||||
struct sockaddr_in addr;
|
||||
esl_status_t status = ESL_SUCCESS;
|
||||
|
||||
struct thread_handler *handler = NULL;
|
||||
|
||||
if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
|
||||
return ESL_FAIL;
|
||||
}
|
||||
@@ -601,7 +661,7 @@ ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_list
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (listen(server_sock, 10000) < 0) {
|
||||
if (listen(server_sock, max) < 0) {
|
||||
status = ESL_FAIL;
|
||||
goto end;
|
||||
}
|
||||
@@ -622,7 +682,16 @@ ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_list
|
||||
goto end;
|
||||
}
|
||||
|
||||
callback(server_sock, client_sock, &echoClntAddr);
|
||||
handler = malloc(sizeof(*handler));
|
||||
esl_assert(handler);
|
||||
|
||||
memset(handler, 0, sizeof(*handler));
|
||||
handler->callback = callback;
|
||||
handler->server_sock = server_sock;
|
||||
handler->client_sock = client_sock;
|
||||
handler->addr = echoClntAddr;
|
||||
|
||||
esl_thread_create_detached(client_thread, handler);
|
||||
}
|
||||
|
||||
end:
|
||||
@@ -1022,7 +1091,21 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
|
||||
|
||||
static esl_ssize_t handle_recv(esl_handle_t *handle, void *data, esl_size_t datalen)
|
||||
{
|
||||
return recv(handle->sock, data, datalen, 0);
|
||||
int activity;
|
||||
|
||||
while (handle->connected) {
|
||||
activity = esl_wait_sock(handle->sock, 1000, ESL_POLL_READ|ESL_POLL_ERROR);
|
||||
|
||||
if (activity > 0 && (activity & ESL_POLL_READ)) {
|
||||
return recv(handle->sock, data, datalen, 0);
|
||||
}
|
||||
|
||||
if (activity < 0) {
|
||||
return errno == EINTR ? 0 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event)
|
||||
|
||||
@@ -270,8 +270,9 @@ ESL_DECLARE(char *) esl_event_get_header_idx(esl_event_t *event, const char *hea
|
||||
}
|
||||
|
||||
return hp->value;
|
||||
|
||||
}
|
||||
} else if (!strcmp(header_name, "_body")) {
|
||||
return event->body;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -414,6 +415,10 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st
|
||||
int index = 0;
|
||||
char *real_header_name = NULL;
|
||||
|
||||
if (!strcmp(header_name, "_body")) {
|
||||
esl_event_set_body(event, data);
|
||||
}
|
||||
|
||||
if ((index_ptr = strchr(header_name, '['))) {
|
||||
index_ptr++;
|
||||
index = atoi(index_ptr);
|
||||
@@ -604,6 +609,17 @@ ESL_DECLARE(esl_status_t) esl_event_add_header_string(esl_event_t *event, esl_st
|
||||
return ESL_FAIL;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_event_set_body(esl_event_t *event, const char *body)
|
||||
{
|
||||
esl_safe_free(event->body);
|
||||
|
||||
if (body) {
|
||||
event->body = DUP(body);
|
||||
}
|
||||
|
||||
return ESL_SUCCESS;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_event_add_body(esl_event_t *event, const char *fmt, ...)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -791,7 +807,7 @@ ESL_DECLARE(esl_status_t) esl_event_serialize(esl_event_t *event, char **str, es
|
||||
if (encode) {
|
||||
esl_url_encode(hp->value, encode_buf, encode_len);
|
||||
} else {
|
||||
esl_snprintf(encode_buf, encode_len, "[%s]", hp->value);
|
||||
esl_snprintf(encode_buf, encode_len, "%s", hp->value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -205,6 +205,15 @@ ESLevent *ESLconnection::sendEvent(ESLevent *send_me)
|
||||
return new ESLevent("server_disconnected");
|
||||
}
|
||||
|
||||
int ESLconnection::sendMSG(ESLevent *send_me, const char *uuid)
|
||||
{
|
||||
if (esl_sendmsg(&handle, send_me->event, uuid) == ESL_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ESLevent *ESLconnection::recvEvent()
|
||||
{
|
||||
if (esl_recv_event(&handle, 1, NULL) == ESL_SUCCESS) {
|
||||
|
||||
@@ -61,12 +61,22 @@ typedef enum {
|
||||
|
||||
#ifdef WIN32
|
||||
#define ESL_SEQ_FWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||
#define ESL_SEQ_FRED FOREGROUND_RED | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_FMAGEN FOREGROUND_BLUE | FOREGROUND_RED
|
||||
#define ESL_SEQ_FCYAN FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||
#define ESL_SEQ_FGREEN FOREGROUND_GREEN
|
||||
#define ESL_SEQ_BRED FOREGROUND_RED
|
||||
#define ESL_SEQ_FMAGEN FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BMAGEN FOREGROUND_BLUE | FOREGROUND_RED
|
||||
#define ESL_SEQ_FCYAN FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BCYAN FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||
#define ESL_SEQ_FGREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BGREEN FOREGROUND_GREEN
|
||||
#define ESL_SEQ_FYELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BYELLOW FOREGROUND_RED | FOREGROUND_GREEN
|
||||
#define ESL_SEQ_DEFAULT_COLOR ESL_SEQ_FWHITE
|
||||
#define ESL_SEQ_FBLUE FOREGROUND_BLUE | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BBLUE FOREGROUND_BLUE
|
||||
#define ESL_SEQ_FBLACK 0 | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BBLACK 0
|
||||
#else
|
||||
#define ESL_SEQ_ESC "\033["
|
||||
/* Ansi Control character suffixes */
|
||||
@@ -381,7 +391,7 @@ ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t s
|
||||
\param port Port to bind to
|
||||
\param callback Callback that will be called upon data received
|
||||
*/
|
||||
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback);
|
||||
ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback, int max);
|
||||
/*!
|
||||
\brief Executes application with sendmsg to a specific UUID. Used for outbound socket.
|
||||
\param handle Handle that the msg will be sent
|
||||
@@ -397,6 +407,14 @@ ESL_DECLARE(esl_status_t) esl_execute(esl_handle_t *handle, const char *app, con
|
||||
*/
|
||||
ESL_DECLARE(esl_status_t) esl_sendevent(esl_handle_t *handle, esl_event_t *event);
|
||||
|
||||
/*!
|
||||
\brief Send an event as a message to be parsed
|
||||
\param handle Handle to which the event should be sent
|
||||
\param event Event to be sent
|
||||
\param uuid a specific uuid if not the default
|
||||
*/
|
||||
ESL_DECLARE(esl_status_t) esl_sendmsg(esl_handle_t *handle, esl_event_t *event, const char *uuid);
|
||||
|
||||
/*!
|
||||
\brief Connect a handle to a host/port with a specific password. This will also authenticate against the server
|
||||
\param handle Handle to connect
|
||||
|
||||
@@ -298,6 +298,7 @@ ESL_DECLARE(esl_status_t) esl_event_create_json(esl_event_t **event, const char
|
||||
\note the body parameter can be shadowed by the esl_event_reserve_subclass_detailed function
|
||||
*/
|
||||
ESL_DECLARE(esl_status_t) esl_event_add_body(esl_event_t *event, const char *fmt, ...);
|
||||
ESL_DECLARE(esl_status_t) esl_event_set_body(esl_event_t *event, const char *body);
|
||||
|
||||
/*!
|
||||
\brief Create a new event assuming it will not be custom event and therefore hiding the unused parameters
|
||||
|
||||
@@ -86,6 +86,7 @@ class ESLconnection {
|
||||
ESLevent *api(const char *cmd, const char *arg = NULL);
|
||||
ESLevent *bgapi(const char *cmd, const char *arg = NULL, const char *job_uuid = NULL);
|
||||
ESLevent *sendEvent(ESLevent *send_me);
|
||||
int sendMSG(ESLevent *send_me, const char *uuid = NULL);
|
||||
ESLevent *recvEvent();
|
||||
ESLevent *recvEventTimed(int ms);
|
||||
ESLevent *filter(const char *header, const char *value);
|
||||
|
||||
@@ -9,11 +9,6 @@ static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struc
|
||||
esl_status_t status;
|
||||
time_t exp = 0;
|
||||
|
||||
if (fork()) {
|
||||
close(client_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
esl_attach_handle(&handle, client_sock, addr);
|
||||
|
||||
esl_log(ESL_LOG_INFO, "Connected! %d\n", handle.sock);
|
||||
@@ -53,7 +48,7 @@ static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struc
|
||||
int main(void)
|
||||
{
|
||||
esl_global_set_default_logger(7);
|
||||
esl_listen("localhost", 8084, mycallback);
|
||||
esl_listen("localhost", 8084, mycallback, 100000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -184,9 +184,9 @@ endif
|
||||
if HAVE_LIBPRI
|
||||
mod_LTLIBRARIES += ftmod_libpri.la
|
||||
ftmod_libpri_la_SOURCES = $(SRC)/ftmod/ftmod_libpri/ftmod_libpri.c $(SRC)/ftmod/ftmod_libpri/lpwrap_pri.c
|
||||
ftmod_libpri_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS)
|
||||
ftmod_libpri_la_LDFLAGS = -shared -module -avoid-version -lpri
|
||||
ftmod_libpri_la_LIBADD = libfreetdm.la
|
||||
ftmod_libpri_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) $(LIBPRI_CPPFLAGS)
|
||||
ftmod_libpri_la_LDFLAGS = -shared -module -avoid-version $(LIBPRI_LDFLAGS)
|
||||
ftmod_libpri_la_LIBADD = libfreetdm.la $(LIBPRI_LIBS)
|
||||
endif
|
||||
|
||||
if HAVE_PRITAP
|
||||
@@ -248,6 +248,14 @@ ftmod_r2_la_LDFLAGS = -shared -module -avoid-version -lopenr2
|
||||
ftmod_r2_la_LIBADD = libfreetdm.la
|
||||
endif
|
||||
|
||||
if HAVE_MISDN
|
||||
mod_LTLIBRARIES += ftmod_misdn.la
|
||||
ftmod_misdn_la_SOURCES = $(SRC)/ftmod/ftmod_misdn/ftmod_misdn.c
|
||||
ftmod_misdn_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) $(MISDN_CFLAGS) -D_GNU_SOURCE
|
||||
ftmod_misdn_la_LDFLAGS = -shared -module -avoid-version
|
||||
ftmod_misdn_la_LIBADD = libfreetdm.la
|
||||
endif
|
||||
|
||||
dox doxygen:
|
||||
doxygen $(FT_SRCDIR)/docs/Doxygen.conf
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
m4_include([build/ax_compiler_vendor.m4])
|
||||
m4_include([build/libpcap.m4])
|
||||
|
||||
@@ -75,6 +75,11 @@ with the signaling protocols that you can run on top of your I/O interfaces.
|
||||
<param name="polarity-delay" value="600"/>
|
||||
-->
|
||||
|
||||
<!-- Retrieve caller id on polarity reverse -->
|
||||
<!--
|
||||
<param name="polarity-callerid" value="true"/>
|
||||
-->
|
||||
|
||||
<!-- regex to stop dialing when it matches -->
|
||||
<!--<param name="dial-regex" value="5555"/>-->
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
; This file is used to generate telephony tones by FreeTDM
|
||||
|
||||
[us]
|
||||
generate-dial => v=-7;%(1000,0,350,440)
|
||||
detect-dial => 350,440
|
||||
@@ -47,19 +45,98 @@ detect-fail1 => 913.8
|
||||
detect-fail2 => 1370.6
|
||||
detect-fail3 => 1776.7
|
||||
|
||||
|
||||
[ru]
|
||||
generate-dial => v=-7;%(1000,425)
|
||||
detect-dial => 0
|
||||
|
||||
generate-ring => v=-7;%(800,5000,425,0)
|
||||
detect-ring => 425,0
|
||||
|
||||
generate-busy => v=-7;%(350,350,425,0)
|
||||
detect-busy => 425,0
|
||||
|
||||
generate-attn => v=0;%(100,100,1400,2060,2450,2600)
|
||||
detect-attn => 1400,2060,2450,2600
|
||||
|
||||
generate-callwaiting-sas => v=0;%(300,0,440)
|
||||
detect-callwaiting-sas => 440,480
|
||||
|
||||
generate-callwaiting-cas => v=0;%(80,0,2750,2130)
|
||||
detect-callwaiting-cas => 2750,2130
|
||||
|
||||
detect-fail1 => 913.8
|
||||
detect-fail2 => 1370.6
|
||||
detect-fail3 => 1776.7
|
||||
|
||||
|
||||
[in]
|
||||
generate-dial => v=-7;%(1000,0,375,425)
|
||||
detect-dial => 375,425
|
||||
|
||||
generate-ring => v=-7;%(2000,4000,440,480)
|
||||
detect-ring => 440,480
|
||||
|
||||
generate-busy => v=-7;%(500,500,480,620)
|
||||
detect-busy => 480,620
|
||||
|
||||
generate-attn => v=0;%(100,100,1400,2060,2450,2600)
|
||||
detect-attn => 1400,2060,2450,2600
|
||||
|
||||
generate-callwaiting-sas => v=0;%(300,0,440)
|
||||
detect-callwaiting-sas => 440
|
||||
|
||||
generate-callwaiting-cas => v=0;%(80,0,2750,2130)
|
||||
detect-callwaiting-cas => 2750,2130
|
||||
|
||||
detect-fail1 => 913.8
|
||||
detect-fail2 => 1370.6
|
||||
detect-fail3 => 776.7
|
||||
|
||||
|
||||
[th]
|
||||
generate-dial => v=-7;%(1000,0,400,400)
|
||||
detect-dial => 400,400
|
||||
|
||||
generate-ring => v=-7;%(2000,4000,400,400)
|
||||
detect-ring => 400,400
|
||||
|
||||
generate-busy => v=-7;%(500,500,480,620)
|
||||
detect-busy => 480,620
|
||||
|
||||
generate-attn => v=0;%(100,100,1400,2060,2450,2600)
|
||||
detect-attn => 1400,2060,2450,2600
|
||||
|
||||
generate-callwaiting-sas => v=0;%(300,0,440)
|
||||
detect-callwaiting-sas => 440
|
||||
|
||||
generate-callwaiting-cas => v=0;%(80,0,2750,2130)
|
||||
detect-callwaiting-cas => 2750,2130
|
||||
|
||||
detect-fail1 => 913.8
|
||||
detect-fail2 => 1370.6
|
||||
detect-fail3 => 1776.7
|
||||
|
||||
|
||||
[au]
|
||||
generate-dial => v=-7;%(1000,0,413,438)
|
||||
detect-dial => 413,438
|
||||
|
||||
generate-ring => v=-7;%(400,200,413,438);%(400,2000,413,438)
|
||||
detect-ring => 413,438
|
||||
|
||||
generate-busy => v=-7;%(375,375,425)
|
||||
detect-busy => 425
|
||||
|
||||
generate-attn => v=0;%(100,100,1400,2060,2450,2600)
|
||||
detect-attn => 1400,2060,2450,2600
|
||||
|
||||
generate-callwaiting-sas => v=0;%(300,0,440)
|
||||
detect-callwaiting-sas => 440
|
||||
|
||||
generate-callwaiting-cas => v=0;%(80,0,2750,2130)
|
||||
detect-callwaiting-cas => 2750,2130
|
||||
|
||||
detect-fail1 => 913.8
|
||||
detect-fail2 => 1370.6
|
||||
detect-fail3 => 776.7
|
||||
|
||||
+75
-10
@@ -54,6 +54,9 @@ fi
|
||||
|
||||
AC_SUBST([confdir])
|
||||
|
||||
DEFAULT_INCLUDES="-I. -I./src/include -I\$(srcdir)"
|
||||
AC_SUBST([DEFAULT_INCLUDES])
|
||||
|
||||
# Where to install the modules
|
||||
AC_ARG_WITH([modinstdir],
|
||||
[AS_HELP_STRING([--with-modinstdir=DIR], [Install modules into this location (default: ${prefix}/mod)])],
|
||||
@@ -191,28 +194,46 @@ AM_CONDITIONAL([HAVE_OPENR2], [test "${HAVE_OPENR2}" = "yes"])
|
||||
#
|
||||
HAVE_LIBPRI="no"
|
||||
AC_ARG_WITH([libpri],
|
||||
[AS_HELP_STRING([--with-libpri], [Install ftmod_libpri])],
|
||||
[AS_HELP_STRING([--with-libpri@<:@=PREFIX@:>@], [Install ftmod_libpri])],
|
||||
[case "${withval}" in
|
||||
no) enable_libpri="no" ;;
|
||||
*) enable_libpri="yes" ;;
|
||||
no|yes) with_libpri="${withval}" ;;
|
||||
*) AS_IF([test -d "${withval}"],
|
||||
[with_libpri="${withval}"],
|
||||
[AC_MSG_ERROR([Invalid argument for --with-libpri, \"${withval}\" is not a directory])]
|
||||
) ;;
|
||||
esac],
|
||||
[enable_libpri="no"]
|
||||
[with_libpri="no"]
|
||||
)
|
||||
if test "${enable_libpri}" != "no"
|
||||
if test "x${with_libpri}" != "xno"
|
||||
then
|
||||
save_LIBS="${LIBS}"
|
||||
save_CPPFLAGS="${CPPFLAGS}"
|
||||
save_LDFLAGS="${LDFLAGS}"
|
||||
|
||||
LIBPRI_CPPFLAGS=""
|
||||
LIBPRI_LDFLAGS=""
|
||||
|
||||
AC_MSG_RESULT([${as_nl}<<>> Digium libpri])
|
||||
|
||||
save_LIBS="${LIBS}"
|
||||
AS_IF([test "x${with_libpri}" != "xyes"],
|
||||
[LIBPRI_CPPFLAGS="-I${with_libpri}/include"
|
||||
LIBPRI_LDFLAGS="-L${with_libpri}/lib"],
|
||||
)
|
||||
|
||||
LDFLAGS="${save_LDFLAGS} ${LIBPRI_LDFLAGS}"
|
||||
CPPFLAGS="${save_CPPFLAGS} ${LIBPRI_CPPFLAGS}"
|
||||
LIBS="${LIBS} -lpri"
|
||||
|
||||
AC_MSG_CHECKING([whether libpri is usable])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[#include <libpri.h>],
|
||||
[const char *version = pri_get_version();]
|
||||
)],
|
||||
[AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
HAVE_LIBPRI="yes"],
|
||||
[AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([libpri is not installed or unusable (see config.log for details)])]
|
||||
AC_MSG_ERROR([libpri not found or unusable (see config.log for details)])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether libpri has BRI support])
|
||||
@@ -238,10 +259,17 @@ then
|
||||
[AC_MSG_RESULT([no])
|
||||
AC_MSG_NOTICE([You will need libpri-1.4.12_beta1 or newer for AOC event support])]
|
||||
)
|
||||
|
||||
# libpri is available, set variables for Makefile(.am)
|
||||
AC_SUBST([LIBPRI_LIBS], [-lpri])
|
||||
AC_SUBST([LIBPRI_LDFLAGS])
|
||||
AC_SUBST([LIBPRI_CPPFLAGS])
|
||||
|
||||
LIBS="${save_LIBS}"
|
||||
LDFLAGS="${save_LDFLAGS}"
|
||||
CPPFLAGS="${save_CPPFLAGS}"
|
||||
fi
|
||||
HAVE_LIBPRI="${enable_libpri}"
|
||||
AM_CONDITIONAL([HAVE_LIBPRI],[test "${enable_libpri}" = "yes"])
|
||||
AM_CONDITIONAL([HAVE_LIBPRI],[test "x${HAVE_LIBPRI}" = "xyes"])
|
||||
|
||||
##
|
||||
# Sangoma Wanpipe
|
||||
@@ -364,6 +392,42 @@ then
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_LIBISDN], [test "${HAVE_LIBISDN}" = "yes"])
|
||||
|
||||
|
||||
##
|
||||
# mISDN dependencies
|
||||
#
|
||||
HAVE_MISDN="no"
|
||||
AC_ARG_WITH([misdn],
|
||||
[AS_HELP_STRING([--with-misdn], [Install ftmod_misdn (mISDN I/O plugin)])],
|
||||
[case "${withval}" in
|
||||
no|yes) with_misdn="${withval}" ;;
|
||||
*) AC_MSG_ERROR([Invalid value \"${with_misdn}\" for --with-misdn option]) ;;
|
||||
esac],
|
||||
[with_misdn="auto"]
|
||||
)
|
||||
AS_IF([test "${with_misdn}" != "no"],
|
||||
[AC_MSG_RESULT([${as_nl}<<>> ftmod_misdn (Linux mISDN I/O plugin)])
|
||||
AC_CHECK_FUNCS([timerfd_create],,
|
||||
[AS_IF([test "${with_misdn}" = "yes"],
|
||||
[AC_MSG_ERROR([no timerfd support in libc])],
|
||||
[AC_MSG_NOTICE([no timerfd support in libc])]
|
||||
)]
|
||||
)
|
||||
AC_CHECK_HEADER([mISDN/mISDNif.h],,
|
||||
[AS_IF([test "${with_misdn}" = "yes"],
|
||||
[AC_MSG_ERROR([mISDN/mISDNif.h not found])],
|
||||
[AC_MSG_NOTICE([mISDN/mISDNif.h not found])]
|
||||
)],
|
||||
[#include <sys/socket.h>]
|
||||
)
|
||||
AS_IF([test "${ac_cv_func_timerfd_create}" = "yes" -a "${ac_cv_header_mISDN_mISDNif_h}" = "yes"],
|
||||
[HAVE_MISDN="yes"],
|
||||
[AC_MSG_NOTICE([Some required dependencies are missing, module disabled])]
|
||||
)]
|
||||
)
|
||||
AM_CONDITIONAL([HAVE_MISDN], [test "${HAVE_MISDN}" = "yes"])
|
||||
|
||||
|
||||
AC_MSG_RESULT([${as_nl}<<>> Creating output files])
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
@@ -389,6 +453,7 @@ AC_MSG_RESULT([
|
||||
ftmod_pritap....................... ${HAVE_PRITAP}
|
||||
I/O:
|
||||
ftmod_wanpipe...................... ${HAVE_LIBSANGOMA}
|
||||
ftmod_misdn........................ ${HAVE_MISDN}
|
||||
|
||||
===============================================================================
|
||||
])
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
== This is an email sent to stkn responding to his post http://stkn.techmage.de/archives/200 ==
|
||||
|
||||
1. FreeTDM open channels immediately.
|
||||
|
||||
Yes, this seems to come from the early days of OpenZAP where probably the analog modules were implemented first and was dragged incorrectly to ISDN.
|
||||
The open API also sets the flag in use so others cannot use it. We should decouple this open and reserve operations. Does not seem very hard to do,
|
||||
I'll take a look at it on my way back to Toronto this week or earlier if possible, I'll create a git branch for it and send you the url for peer review.
|
||||
Feel free to do the opposite if you are in a hurry.
|
||||
|
||||
2. FreeTDM does not completely close the channel on hangup.
|
||||
|
||||
As long as the signaling module calls ftdm_channel_close() the fio->close API will be called where the IO module is responsible
|
||||
for turning off ec or any other operations to leave the channel unused/idle (not really closed). There was indeed a bug where ftdm_zt module
|
||||
was not properly closing the channel, if that is what you mean, then it means that was already fixed by you with your audio mode turn off patch.
|
||||
|
||||
Now, a more lengthy response ...
|
||||
|
||||
When we, Sangoma, took over openzap and renamed it to freetdm, it was not just a name change, many API cleanups were done so API users cannot access
|
||||
|
||||
the internal data structures and cannot explicitly move between channel states. Also, some order on the state transitions has been put into place.
|
||||
|
||||
We've tried to keep backwards compatibility though, so old modules may not follow all of the conventions. Some unwritten conventions are:
|
||||
|
||||
1. Signaling modules are responsible for calling ftdm_channel_close() when done with the channel. In fact, signaling modules should not
|
||||
call ftdm_channel_done unless they really know what they're doing. ftdm_channel_close will call ftdm_channel_done anyways.
|
||||
|
||||
2. When remote end hangs up a call, signaling module should go to TERMINATING state and send SIGEVENT_STOP to the user. The signaling stack
|
||||
should not acknowledge the hangup until the user implicitly moves us to HANGUP (via ftdm_channel_call_hangup()). There is a core timer
|
||||
that will ensure we move from TERMINATING to HANGUP if the user does not moves us fast enough (arbitrarely 3000ms), although that is considered
|
||||
a bug in the user application (at some point we saw that in FreeSWITCH) and we complain loudly when that happens.
|
||||
|
||||
3. Signaling modules should leave the channel with NO pending states once they unlock it. This means, whenever you have a message to process
|
||||
you must lock the channel, check its current state (the user may have already changed the state to something else), process any pending
|
||||
state set by the user, then process your message and if required move the channel to a new state and process that state before releasing the lock.
|
||||
There is a chance of a deadlock due to the callbacks we use to notify users of messages if we call those callbacks with the channel lock held and
|
||||
that is why new signaling modules should use the FTDM_SPAN_USE_SIGNALS_QUEUE to defer the notification to the user when the ftdm_channel_t is not
|
||||
locked calling ftdm_span_trigger_signals() at the end of their processing loop which delivers the callback notifications to users.
|
||||
|
||||
Having said that, there is a major architectural change coming, probably early 2011, and I'd like to have your input.
|
||||
|
||||
== Decoupling calls from IO channels ==
|
||||
|
||||
We've also found that the concept of a channel and a call are unnecesarily coupled together in FreeTDM. I've never asked Anthony the reasoning
|
||||
for this, but it seems the API was meant to be used with, or without calls. That is, a user should be able to just 'open' a channel and start
|
||||
reading and writing raw data without ever launching one of the provided signaling stacks on top, may be just because the user is using their
|
||||
own signaling stack and just needs freetdm/openzap as an I/O API. In fact, signaling modules work like this (but there are defects there).
|
||||
The problem is, as you have noticed, the way ftdm_channel_open_xx APIs has been implemented is abusing this concept.
|
||||
|
||||
Problems with current implementation.
|
||||
|
||||
1. Exclusive channel is the only way we can request channels to the ISDN network. There is no room to change the channel later on easily.
|
||||
2. Multi-rate calls cannot be done. We need to associate multiple B-channels to a single call.
|
||||
3. Low-bit-rate calls (not sure what is the proper name for them) where a single B-channel can feed media to multiple calls with a low bit-rate
|
||||
codec (I know of at least one request from a big company for this to support some Q.SIG stuff for Eurocontrol).
|
||||
|
||||
|
||||
What do we need?
|
||||
|
||||
I think there should be only one open() API that wraps calls around fio->open(), the other current open_xx functions that do hunting, should
|
||||
be eliminated and some extra arguments provided to ftdm_channel_call_place to provide information about the channel where we would like to
|
||||
place the call or group hunting information and the API would return immediately providing a ftdm_call_t reference pointer that can be used
|
||||
to further track the status of that call, or in the case where a channel exclusivity was requested and we know for a fact is not available,
|
||||
just return failure. At that point there is no I/O channel involved yet. Eventually after the signaling stack hunts the channel and
|
||||
negotiaties its availability with the network, an I/O channel can be attached to that call, or even attach multiple channels (for the case
|
||||
of multi rate calls?).
|
||||
|
||||
This involves heavy changes. The state machine should be moved out of the ftdm_channel_t structure along with probably some other members
|
||||
and stuffed into a new ftdm_call_t structure. Signaling modules would have to be updated to run their state machines with this call
|
||||
structure and then at some point attach IO channels to the call. There would be 2 type of read/write APIs, one low level ftdm_channel_read
|
||||
which receives an ftdm_channel_t as parameter and an ftdm_call_read() which receives an ftdm_call_t as parameter, for the case of multi-rate
|
||||
calls or low-bit-rate multiplexed calls in the same B-channel this API would return just the media corresponding to that call already
|
||||
demultiplexed or concatenated, or whatever needs to be done with the media from the multiple low-level IO channels.
|
||||
|
||||
This is fairly disruptive, but I believe should be done sooner or later.
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../src/include;../src/include;../src/isdn/include"
|
||||
AdditionalIncludeDirectories="../../../src/include;../src/include;../../curl/include;../src/isdn/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
@@ -126,7 +126,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../src/include;../src/include;../src/isdn/include"
|
||||
AdditionalIncludeDirectories="../../../src/include;../src/include;../../curl/include;../src/isdn/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
@@ -210,7 +210,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../src/include;../src/include;../src/isdn/include"
|
||||
AdditionalIncludeDirectories="../../../src/include;../src/include;../../curl/include;../src/isdn/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
@@ -292,7 +292,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../src/include;../src/include;../src/isdn/include"
|
||||
AdditionalIncludeDirectories="../../../src/include;../src/include;../../curl/include;../src/isdn/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../src/include;../src/include;../../curl/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
@@ -117,7 +117,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../src/include;../src/include;../../curl/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
@@ -148,7 +148,7 @@
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../src/include;../src/include;../../curl/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
@@ -177,7 +177,7 @@
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../src/include;../src/include;../../curl/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
|
||||
@@ -34,6 +34,15 @@
|
||||
#include <switch.h>
|
||||
#include "freetdm.h"
|
||||
|
||||
//#define CUDATEL_DEBUG
|
||||
#ifdef CUDATEL_DEBUG
|
||||
#ifndef _BSD_SOURCE
|
||||
#define _BSD_SOURCE
|
||||
#endif
|
||||
#include <execinfo.h>
|
||||
#include <syscall.h>
|
||||
#endif
|
||||
|
||||
#ifndef __FUNCTION__
|
||||
#define __FUNCTION__ __SWITCH_FUNC__
|
||||
#endif
|
||||
@@ -495,15 +504,14 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
||||
switch_channel_t *channel = NULL;
|
||||
private_t *tech_pvt = NULL;
|
||||
ftdm_chan_type_t chantype;
|
||||
uint32_t tokencnt;
|
||||
char *uuid = NULL;
|
||||
uint8_t uuid_found = 0;
|
||||
uint32_t t = 0;
|
||||
const char *token = NULL;
|
||||
const char *name = NULL;
|
||||
int span_id = 0;
|
||||
int chan_id = 0;
|
||||
const char *name = NULL;
|
||||
|
||||
uint32_t t = 0;
|
||||
uint32_t tokencnt;
|
||||
char *uuid = NULL;
|
||||
const char *token = NULL;
|
||||
uint8_t uuid_found = 0;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
@@ -511,13 +519,60 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
/* ignore any further I/O requests, we're hanging up already! */
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||
/* ignore any further I/O requests, we're hanging up already! */
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||
|
||||
name = switch_channel_get_name(channel);
|
||||
|
||||
span_id = tech_pvt->ftdmchan ? ftdm_channel_get_span_id(tech_pvt->ftdmchan) : 0;
|
||||
chan_id = tech_pvt->ftdmchan ? ftdm_channel_get_id(tech_pvt->ftdmchan) : 0;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d] %s CHANNEL HANGUP ENTER\n", span_id, chan_id, name);
|
||||
|
||||
/* First verify this call has a device attached */
|
||||
if (!tech_pvt->ftdmchan) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s does not have any ftdmchan attached\n", name);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now verify the device is still attached to this call :-)
|
||||
* Sometimes the FS core takes too long (more than 3 seconds) in calling
|
||||
* channel_on_hangup() and the FreeTDM core decides to take the brute
|
||||
* force approach and hangup and detach themselves from the call. Later
|
||||
* when FS finally comes around, we might end up hanging up the device
|
||||
* attached to another call, this verification avoids that. */
|
||||
uuid = switch_core_session_get_uuid(session);
|
||||
tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan);
|
||||
for (t = 0; t < tokencnt; t++) {
|
||||
token = ftdm_channel_get_token(tech_pvt->ftdmchan, t);
|
||||
if (!zstr(token) && !strcasecmp(uuid, token)) {
|
||||
uuid_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!uuid_found) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Device [%d:%d] is no longer attached to %s. Nothing to do.\n", span_id, chan_id, name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifdef CUDATEL_DEBUG
|
||||
{
|
||||
pid_t tid = 0;
|
||||
size_t size = 0;
|
||||
char **symbols = NULL;
|
||||
void *stacktrace[50];
|
||||
int si = 0;
|
||||
size = backtrace(stacktrace, ftdm_array_len(stacktrace));
|
||||
symbols = backtrace_symbols(stacktrace, size);
|
||||
tid = syscall(SYS_gettid);
|
||||
for (si = 0; si < size; si++) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d][tid:%d] %s -> %s\n",
|
||||
span_id, chan_id, tid, name, symbols[si]);
|
||||
}
|
||||
free(symbols);
|
||||
}
|
||||
#endif
|
||||
|
||||
name = switch_channel_get_name(channel);
|
||||
|
||||
@@ -549,7 +604,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
||||
|
||||
ftdm_channel_clear_token(tech_pvt->ftdmchan, switch_core_session_get_uuid(session));
|
||||
|
||||
chantype = ftdm_channel_get_type(tech_pvt->ftdmchan);
|
||||
chantype = ftdm_channel_get_type(tech_pvt->ftdmchan);
|
||||
switch (chantype) {
|
||||
case FTDM_CHAN_TYPE_FXO:
|
||||
case FTDM_CHAN_TYPE_EM:
|
||||
@@ -560,7 +615,6 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
||||
case FTDM_CHAN_TYPE_FXS:
|
||||
{
|
||||
if (!ftdm_channel_call_check_busy(tech_pvt->ftdmchan) && !ftdm_channel_call_check_done(tech_pvt->ftdmchan)) {
|
||||
tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan);
|
||||
if (tokencnt) {
|
||||
cycle_foreground(tech_pvt->ftdmchan, 0, NULL);
|
||||
} else {
|
||||
@@ -588,9 +642,6 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
||||
|
||||
end:
|
||||
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel));
|
||||
switch_mutex_lock(globals.mutex);
|
||||
globals.calls--;
|
||||
if (globals.calls < 0) {
|
||||
@@ -598,6 +649,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
||||
}
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d] %s CHANNEL HANGUP EXIT\n", span_id, chan_id, name);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -669,6 +721,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
int total_to;
|
||||
int chunk, do_break = 0;
|
||||
uint32_t span_id, chan_id;
|
||||
const char *name = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
@@ -676,17 +729,18 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "TFLAG_DEAD is set\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
name = switch_channel_get_name(channel);
|
||||
if (!tech_pvt->ftdmchan) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
span_id = ftdm_channel_get_span_id(tech_pvt->ftdmchan);
|
||||
chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan);
|
||||
if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
/* Digium Cards sometimes timeout several times in a row here.
|
||||
Yes, we support digium cards, ain't we nice.......
|
||||
@@ -718,7 +772,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
}
|
||||
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "TFLAG_IO is not set\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -726,7 +780,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
status = ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, chunk);
|
||||
|
||||
if (status == FTDM_FAIL) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to wait for I/O\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -734,7 +788,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_HOLD)) {
|
||||
total_to -= chunk;
|
||||
if (total_to <= 0) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Too many timeouts while waiting for I/O\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Too many timeouts while waiting I/O in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
@@ -747,9 +801,9 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
|
||||
len = tech_pvt->read_frame.buflen;
|
||||
if (ftdm_channel_read(tech_pvt->ftdmchan, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "failed to read from device %d:%d\n", span_id, chan_id);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
if (++tech_pvt->read_error > FTDM_MAX_READ_WRITE_ERRORS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "too many I/O read errors on device %d:%d!\n", span_id, chan_id);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "too many I/O read errors on channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
@@ -765,23 +819,23 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
}
|
||||
|
||||
while (ftdm_channel_dequeue_dtmf(tech_pvt->ftdmchan, dtmf, sizeof(dtmf))) {
|
||||
switch_dtmf_t _dtmf = { 0, SWITCH_DEFAULT_DTMF_DURATION };
|
||||
switch_dtmf_t _dtmf = { 0, switch_core_default_dtmf_duration(0) };
|
||||
char *p;
|
||||
for (p = dtmf; p && *p; p++) {
|
||||
if (is_dtmf(*p)) {
|
||||
_dtmf.digit = *p;
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Queuing DTMF [%c] in channel %s\n", *p, switch_channel_get_name(channel));
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Queuing DTMF [%c] in channel %s device %d:%d\n", *p, name, span_id, chan_id);
|
||||
switch_channel_queue_dtmf(channel, &_dtmf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "clearing IO in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
|
||||
@@ -790,8 +844,9 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
private_t *tech_pvt = NULL;
|
||||
ftdm_size_t len;
|
||||
unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
|
||||
const char *name = "(none)";
|
||||
ftdm_wait_flag_t wflags = FTDM_WRITE;
|
||||
uint32_t span_id, chan_id;
|
||||
uint32_t span_id = 0, chan_id = 0;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
@@ -799,7 +854,17 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
name = switch_channel_get_name(channel);
|
||||
if (!tech_pvt->ftdmchan) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
span_id = ftdm_channel_get_span_id(tech_pvt->ftdmchan);
|
||||
chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan);
|
||||
|
||||
if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
@@ -808,17 +873,10 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
}
|
||||
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!tech_pvt->ftdmchan) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
span_id = ftdm_channel_get_span_id(tech_pvt->ftdmchan);
|
||||
chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan);
|
||||
|
||||
|
||||
if (switch_test_flag(frame, SFF_CNG)) {
|
||||
frame->data = data;
|
||||
frame->buflen = sizeof(data);
|
||||
@@ -833,16 +891,16 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 10);
|
||||
|
||||
if (!(wflags & FTDM_WRITE)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready)\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write note ready) in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
len = frame->datalen;
|
||||
if (ftdm_channel_write(tech_pvt->ftdmchan, frame->data, frame->buflen, &len) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "failed to write to device %d:%d\n", span_id, chan_id);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to write to channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
if (++tech_pvt->write_error > FTDM_MAX_READ_WRITE_ERRORS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG,
|
||||
SWITCH_LOG_ERROR, "too many I/O write errors on device %d:%d!\n", span_id, chan_id);
|
||||
SWITCH_LOG_ERROR, "Too many I/O write errors on channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
@@ -852,7 +910,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error writing to channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
@@ -1854,11 +1912,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
|
||||
|
||||
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Screen", "%d", channel_caller_data->screen);
|
||||
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Presentation", "%d", channel_caller_data->pres);
|
||||
|
||||
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_callref");
|
||||
if (!ftdm_strlen_zero(var_value)) {
|
||||
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CallReference", "%s", var_value);
|
||||
}
|
||||
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CallReference", "%d", channel_caller_data->call_reference);
|
||||
|
||||
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_opc");
|
||||
if (!ftdm_strlen_zero(var_value)) {
|
||||
@@ -2361,7 +2415,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
|
||||
channel = switch_core_session_get_channel(session);
|
||||
switch_channel_hangup(channel, caller_data->hangup_cause);
|
||||
ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
|
||||
switch_core_session_rwunlock(session);
|
||||
}
|
||||
}
|
||||
@@ -3149,6 +3202,7 @@ static switch_status_t load_config(void)
|
||||
const char *enable_callerid = "true";
|
||||
const char *answer_polarity = "false";
|
||||
const char *hangup_polarity = "false";
|
||||
const char *polarity_callerid = "false";
|
||||
int polarity_delay = 600;
|
||||
int callwaiting = 1;
|
||||
int dialtone_timeout = 5000;
|
||||
@@ -3230,6 +3284,8 @@ static switch_status_t load_config(void)
|
||||
hangup_polarity = val;
|
||||
} else if (!strcasecmp(var, "polarity-delay")) {
|
||||
polarity_delay = atoi(val);
|
||||
} else if (!strcasecmp(var, "polarity-callerid")) {
|
||||
polarity_callerid = val;
|
||||
} else if (!strcasecmp(var, "fail-dial-regex")) {
|
||||
fail_dial_regex = val;
|
||||
} else if (!strcasecmp(var, "hold-music")) {
|
||||
@@ -3292,6 +3348,7 @@ static switch_status_t load_config(void)
|
||||
"enable_callerid", enable_callerid,
|
||||
"answer_polarity_reverse", answer_polarity,
|
||||
"hangup_polarity_reverse", hangup_polarity,
|
||||
"polarity_callerid", polarity_callerid,
|
||||
"polarity_delay", &polarity_delay,
|
||||
"callwaiting", &callwaiting,
|
||||
"wait_dialtone_timeout", &dialtone_timeout,
|
||||
@@ -3918,16 +3975,151 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *
|
||||
switch_channel_cause2str(caller_data->hangup_cause));
|
||||
}
|
||||
|
||||
typedef struct ftdm_cli_entry ftdm_cli_entry_t;
|
||||
typedef switch_status_t (*ftdm_cli_function_t)(ftdm_cli_entry_t *cli, const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[]);
|
||||
#define FTDM_CLI_DECLARE(name) static switch_status_t name(ftdm_cli_entry_t *cli, const char *cmd, \
|
||||
switch_core_session_t *session, switch_stream_handle_t *stream, \
|
||||
int argc, char *argv[])
|
||||
static void print_usage(switch_stream_handle_t *stream, ftdm_cli_entry_t *cli);
|
||||
|
||||
static switch_status_t ftdm_cmd_voice_detect(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
|
||||
typedef struct cmd_ioread_data {
|
||||
int num_times;
|
||||
uint32_t interval;
|
||||
ftdm_span_t *span;
|
||||
ftdm_channel_t *fchan;
|
||||
switch_memory_pool_t *pool;
|
||||
int already_open;
|
||||
} cmd_ioread_data_t;
|
||||
|
||||
static void *SWITCH_THREAD_FUNC ioread_thread(switch_thread_t *thread, void *obj)
|
||||
{
|
||||
stream->write_function(stream, "IMPLEMENT ME!\n");
|
||||
ftdm_wait_flag_t wflags = FTDM_READ;
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
unsigned char iobuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
|
||||
cmd_ioread_data_t *data = obj;
|
||||
int span_id = ftdm_span_get_id(data->span);
|
||||
int chan_id = ftdm_channel_get_id(data->fchan);
|
||||
ftdm_size_t len = ftdm_channel_get_io_packet_len(data->fchan);
|
||||
ftdm_size_t origlen = len;
|
||||
unsigned int pbuf[5];
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
||||
"Started ioread thread (times = %d, interval = %ums, len = %"FTDM_SIZE_FMT", span = %d, chan = %d\n",
|
||||
data->num_times, data->interval, len, span_id, chan_id);
|
||||
|
||||
while (ftdm_running() && data->num_times > 0) {
|
||||
data->num_times--;
|
||||
|
||||
wflags = FTDM_READ;
|
||||
|
||||
status = ftdm_channel_wait(data->fchan, &wflags, (data->interval * 10));
|
||||
|
||||
if (status == FTDM_FAIL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to wait for IO in device %d:%d!\n", span_id, chan_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (status == FTDM_TIMEOUT) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Timed out while waiting I/O in device %d:%d!\n", span_id, chan_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
len = origlen;
|
||||
if (ftdm_channel_read(data->fchan, iobuf, &len) != FTDM_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from device %d:%d!\n", span_id, chan_id);
|
||||
continue;
|
||||
}
|
||||
pbuf[0] = iobuf[0];
|
||||
pbuf[1] = iobuf[1];
|
||||
pbuf[2] = iobuf[2];
|
||||
pbuf[3] = iobuf[3];
|
||||
pbuf[4] = iobuf[4];
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Read 0x%1X 0x%1X 0x%1X 0x%1X 0x%1X\n",
|
||||
pbuf[0], pbuf[1], pbuf[2], pbuf[3], pbuf[4]);
|
||||
}
|
||||
|
||||
if (!data->already_open) {
|
||||
ftdm_channel_close(&data->fchan);
|
||||
}
|
||||
|
||||
switch_core_destroy_memory_pool(&data->pool);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
||||
"Done ioread thread (times = %d, interval = %ums, len = %"FTDM_SIZE_FMT", span = %d, chan = %d\n",
|
||||
data->num_times, data->interval, origlen, span_id, chan_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_ioread)
|
||||
{
|
||||
char *span_name = NULL;
|
||||
int channo = 0;
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
switch_threadattr_t *attr = NULL;
|
||||
switch_thread_t *thread = NULL;
|
||||
|
||||
cmd_ioread_data_t *thdata;
|
||||
cmd_ioread_data_t data;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.num_times = 1;
|
||||
|
||||
if (argc < 3) {
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
|
||||
span_name = argv[1];
|
||||
|
||||
ftdm_span_find_by_name(span_name, &data.span);
|
||||
if (!data.span) {
|
||||
stream->write_function(stream, "-ERR span %s not found\n", span_name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
channo = atoi(argv[2]);
|
||||
|
||||
status = ftdm_channel_open(ftdm_span_get_id(data.span), channo, &data.fchan);
|
||||
if (!data.fchan || (status != FTDM_SUCCESS && status != FTDM_EBUSY)) {
|
||||
stream->write_function(stream, "-ERR Failed to open channel %d in span %s\n", channo, span_name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (status == FTDM_EBUSY) {
|
||||
data.already_open = 1;
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
data.num_times = atoi(argv[3]);
|
||||
if (data.num_times < 1) {
|
||||
data.num_times = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > 4) {
|
||||
data.interval = atoi(argv[4]);
|
||||
}
|
||||
|
||||
if (data.interval <= 0 || data.interval > 10000) {
|
||||
data.interval = ftdm_channel_get_io_interval(data.fchan);
|
||||
}
|
||||
|
||||
switch_core_new_memory_pool(&data.pool);
|
||||
|
||||
thdata = switch_core_alloc(data.pool, sizeof(data));
|
||||
memcpy(thdata, &data, sizeof(*thdata));
|
||||
|
||||
switch_threadattr_create(&attr, data.pool);
|
||||
switch_threadattr_detach_set(attr, 1);
|
||||
switch_threadattr_stacksize_set(attr, SWITCH_THREAD_STACKSIZE);
|
||||
switch_thread_create(&thread, attr, ioread_thread, thdata, data.pool);
|
||||
|
||||
end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_list(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_list)
|
||||
{
|
||||
int j;
|
||||
for (j = 0 ; j < FTDM_MAX_SPANS_INTERFACE; j++) {
|
||||
@@ -4004,19 +4196,20 @@ static switch_status_t ftdm_cmd_list(const char *cmd, switch_core_session_t *ses
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_start_stop(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_start_stop)
|
||||
{
|
||||
char *span_name = argv[1];
|
||||
ftdm_span_t *span = NULL;
|
||||
ftdm_status_t status;
|
||||
|
||||
if (span_name) {
|
||||
ftdm_span_find_by_name(span_name, &span);
|
||||
if (argc < 2) {
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ftdm_span_find_by_name(span_name, &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR no span\n");
|
||||
stream->write_function(stream, "-ERR span %s not found\n", span_name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -4031,34 +4224,36 @@ end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_reset(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_reset)
|
||||
{
|
||||
uint32_t chan_id = 0;
|
||||
uint32_t ccount = 0;
|
||||
ftdm_channel_t *chan;
|
||||
ftdm_span_t *span = NULL;
|
||||
|
||||
if (argc < 2) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm reset <span_id> [<chan_id>]\n");
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ftdm_span_find_by_name(argv[1], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
stream->write_function(stream, "-ERR span %s not found\n", argv[1]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
chan_id = atoi(argv[2]);
|
||||
if (chan_id > ftdm_span_get_chan_count(span)) {
|
||||
stream->write_function(stream, "-ERR invalid chan\n");
|
||||
stream->write_function(stream, "-ERR invalid channel %d\n", chan_id);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (chan_id) {
|
||||
chan = ftdm_span_get_channel(span, chan_id);
|
||||
if (!chan) {
|
||||
stream->write_function(stream, "-ERR Could not find chan\n");
|
||||
stream->write_function(stream, "-ERR Could not find channel %d\n", chan_id);
|
||||
goto end;
|
||||
}
|
||||
stream->write_function(stream, "Resetting channel %s:%s\n", argv[1], argv[2]);
|
||||
@@ -4078,8 +4273,7 @@ end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_dump(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_dump)
|
||||
{
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
@@ -4088,12 +4282,11 @@ static switch_status_t ftdm_cmd_dump(const char *cmd, switch_core_session_t *ses
|
||||
char *as = NULL;
|
||||
|
||||
if (argc < 2) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm dump <span_id> [<chan_id>]\n");
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ftdm_span_find_by_name(argv[1], &span);
|
||||
|
||||
if (argc > 2) {
|
||||
if (argv[3] && !strcasecmp(argv[2], "as")) {
|
||||
as = argv[3];
|
||||
@@ -4156,28 +4349,29 @@ end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_sigstatus(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_sigstatus)
|
||||
{
|
||||
ftdm_span_t *span = NULL;
|
||||
ftdm_signaling_status_t sigstatus;
|
||||
|
||||
if (argc < 3) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm sigstatus get|set [<span_id>] [<chan_id>] [<sigstatus>]\n");
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[1], "get") && argc < 3) {
|
||||
stream->write_function(stream, "-ERR sigstatus get usage: get <span_id>\n");
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[1], "set") && argc != 5) {
|
||||
stream->write_function(stream, "-ERR sigstatus set usage: set <span_id> <chan_id>|all <sigstatus>\n");
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ftdm_span_find_by_name(argv[2], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
stream->write_function(stream, "-ERR invalid span %s\n", argv[2]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -4186,21 +4380,21 @@ static switch_status_t ftdm_cmd_sigstatus(const char *cmd, switch_core_session_t
|
||||
uint32_t chan_id = atol(argv[3]);
|
||||
ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
|
||||
if (!fchan) {
|
||||
stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id);
|
||||
stream->write_function(stream, "-ERR invalid channel id '%d'\n", chan_id);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((FTDM_SUCCESS == ftdm_channel_get_sig_status(fchan, &sigstatus))) {
|
||||
stream->write_function(stream, "channel %d signaling status: %s\n", chan_id, ftdm_signaling_status2str(sigstatus));
|
||||
stream->write_function(stream, "Channel %d signaling status: %s\n", chan_id, ftdm_signaling_status2str(sigstatus));
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR failed to get channel sigstatus\n");
|
||||
stream->write_function(stream, "-ERR failed to get channel signaling status\n");
|
||||
}
|
||||
goto end;
|
||||
} else {
|
||||
if ((FTDM_SUCCESS == ftdm_span_get_sig_status(span, &sigstatus))) {
|
||||
stream->write_function(stream, "signaling_status: %s\n", ftdm_signaling_status2str(sigstatus));
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR failed to read span status: %s\n", ftdm_span_get_last_error(span));
|
||||
stream->write_function(stream, "-ERR failed to read span signaling status: %s\n", ftdm_span_get_last_error(span));
|
||||
}
|
||||
}
|
||||
goto end;
|
||||
@@ -4238,8 +4432,7 @@ end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_trace(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_trace)
|
||||
{
|
||||
char tracepath[255];
|
||||
unsigned i = 0;
|
||||
@@ -4249,19 +4442,19 @@ static switch_status_t ftdm_cmd_trace(const char *cmd, switch_core_session_t *se
|
||||
ftdm_span_t *span = NULL;
|
||||
ftdm_channel_t *chan = NULL;
|
||||
if (argc < 3) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm trace <path> <span_id> [<chan_id>]\n");
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
ftdm_span_find_by_name(argv[2], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]);
|
||||
goto end;
|
||||
}
|
||||
chan_count = ftdm_span_get_chan_count(span);
|
||||
if (argc > 3) {
|
||||
chan_id = atoi(argv[3]);
|
||||
if (chan_id > chan_count) {
|
||||
stream->write_function(stream, "-ERR invalid chan\n");
|
||||
stream->write_function(stream, "-ERR invalid channel\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
@@ -4286,31 +4479,33 @@ end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_notrace(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_notrace)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t chan_id = 0;
|
||||
uint32_t chan_count = 0;
|
||||
ftdm_channel_t *fchan = NULL;
|
||||
ftdm_span_t *span = NULL;
|
||||
|
||||
if (argc < 2) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm notrace <span_id> [<chan_id>]\n");
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
ftdm_span_find_by_name(argv[1], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
stream->write_function(stream, "-ERR failed to find span %s\n", argv[1]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
chan_count = ftdm_span_get_chan_count(span);
|
||||
if (argc > 2) {
|
||||
chan_id = atoi(argv[2]);
|
||||
if (chan_id > chan_count) {
|
||||
stream->write_function(stream, "-ERR invalid chan\n");
|
||||
stream->write_function(stream, "-ERR invalid channel\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (chan_id) {
|
||||
fchan = ftdm_span_get_channel(span, chan_id);
|
||||
ftdm_channel_command(fchan, FTDM_COMMAND_TRACE_END_ALL, NULL);
|
||||
@@ -4321,12 +4516,12 @@ static switch_status_t ftdm_cmd_notrace(const char *cmd, switch_core_session_t *
|
||||
}
|
||||
}
|
||||
stream->write_function(stream, "+OK trace disabled\n");
|
||||
|
||||
end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_gains(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_gains)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
float txgain = 0.0;
|
||||
@@ -4336,18 +4531,19 @@ static switch_status_t ftdm_cmd_gains(const char *cmd, switch_core_session_t *se
|
||||
ftdm_channel_t *chan;
|
||||
ftdm_span_t *span = NULL;
|
||||
if (argc < 4) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm gains <rxgain> <txgain> <span_id> [<chan_id>]\n");
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
ftdm_span_find_by_name(argv[3], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
stream->write_function(stream, "-ERR failed to find span %s\n", argv[3]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (argc > 4) {
|
||||
chan_id = atoi(argv[4]);
|
||||
if (chan_id > ftdm_span_get_chan_count(span)) {
|
||||
stream->write_function(stream, "-ERR invalid chan\n");
|
||||
stream->write_function(stream, "-ERR invalid channel\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
@@ -4375,8 +4571,7 @@ end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_dtmf(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_dtmf)
|
||||
{
|
||||
unsigned i = 0;
|
||||
uint32_t chan_id = 0;
|
||||
@@ -4384,8 +4579,9 @@ static switch_status_t ftdm_cmd_dtmf(const char *cmd, switch_core_session_t *ses
|
||||
ftdm_span_t *span = NULL;
|
||||
ftdm_command_t fcmd = FTDM_COMMAND_ENABLE_DTMF_DETECT;
|
||||
ftdm_channel_t *fchan;
|
||||
|
||||
if (argc < 3) {
|
||||
stream->write_function(stream, "-ERR Usage: dtmf on|off <span_id> [<chan_id>]\n");
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -4397,14 +4593,15 @@ static switch_status_t ftdm_cmd_dtmf(const char *cmd, switch_core_session_t *ses
|
||||
|
||||
ftdm_span_find_by_name(argv[2], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
schan_count = ftdm_span_get_chan_count(span);
|
||||
if (argc > 3) {
|
||||
chan_id = atoi(argv[3]);
|
||||
if (chan_id > schan_count) {
|
||||
stream->write_function(stream, "-ERR invalid chan\n");
|
||||
stream->write_function(stream, "-ERR invalid channel\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
@@ -4424,8 +4621,7 @@ end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_queuesize(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_queuesize)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
uint32_t rxsize = 10;
|
||||
@@ -4435,21 +4631,24 @@ static switch_status_t ftdm_cmd_queuesize(const char *cmd, switch_core_session_t
|
||||
ftdm_channel_t *chan;
|
||||
ftdm_span_t *span = NULL;
|
||||
if (argc < 4) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm queuesize <rxsize> <txsize> <span_id> [<chan_id>]\n");
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ftdm_span_find_by_name(argv[3], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
stream->write_function(stream, "-ERR failed to find span %s\n", argv[3]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (argc > 4) {
|
||||
chan_id = atoi(argv[4]);
|
||||
if (chan_id > ftdm_span_get_chan_count(span)) {
|
||||
stream->write_function(stream, "-ERR invalid chan\n");
|
||||
stream->write_function(stream, "-ERR invalid channel\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
i = sscanf(argv[1], "%u", &rxsize);
|
||||
i += sscanf(argv[2], "%u", &txsize);
|
||||
if (i != 2) {
|
||||
@@ -4503,8 +4702,7 @@ static void exec_io_command(const char *cmd, switch_stream_handle_t *stream, ftd
|
||||
}
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_iostats(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_iostats)
|
||||
{
|
||||
uint32_t chan_id = 0;
|
||||
ftdm_channel_t *chan;
|
||||
@@ -4513,20 +4711,20 @@ static switch_status_t ftdm_cmd_iostats(const char *cmd, switch_core_session_t *
|
||||
ftdm_span_t *span = NULL;
|
||||
|
||||
if (argc < 3) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm iostats enable|disable|flush|print <span_id> [<chan_id>]\n");
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ftdm_span_find_by_name(argv[2], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
chan_id = atoi(argv[3]);
|
||||
if (chan_id > ftdm_span_get_chan_count(span)) {
|
||||
stream->write_function(stream, "-ERR invalid chan\n");
|
||||
stream->write_function(stream, "-ERR invalid channel\n");
|
||||
goto end;
|
||||
}
|
||||
chan = ftdm_span_get_channel(span, chan_id);
|
||||
@@ -4544,14 +4742,12 @@ end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef switch_status_t (*ftdm_cli_function_t)(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[]);
|
||||
typedef struct ftdm_cli_entry {
|
||||
struct ftdm_cli_entry {
|
||||
const char *name;
|
||||
const char *args;
|
||||
const char *complete;
|
||||
ftdm_cli_function_t execute;
|
||||
} ftdm_cli_entry_t;
|
||||
};
|
||||
|
||||
static ftdm_cli_entry_t ftdm_cli_options[] =
|
||||
{
|
||||
@@ -4567,7 +4763,7 @@ static ftdm_cli_entry_t ftdm_cli_options[] =
|
||||
{ "dtmf", "on|off <span_id|span_name> [<chan_id>]", "::[on:off", ftdm_cmd_dtmf },
|
||||
{ "queuesize", "<rxsize> <txsize> <span_id|span_name> [<chan_id>]", "", ftdm_cmd_queuesize },
|
||||
{ "iostats", "enable|disable|flush|print <span_id|span_name> <chan_id>", "::[enable:disable:flush:print", ftdm_cmd_iostats },
|
||||
{ "voice_detect", "[on|off] <span_id|span_name> [<chan_id>]", "::[on:off", ftdm_cmd_voice_detect },
|
||||
{ "ioread", "<span_id|span_name> <chan_id> [num_times] [interval]", "", ftdm_cmd_ioread },
|
||||
|
||||
/* Fake handlers as they are handled within freetdm library,
|
||||
* we should provide a way inside freetdm to query for completions from signaling modules */
|
||||
@@ -4576,6 +4772,11 @@ static ftdm_cli_entry_t ftdm_cli_options[] =
|
||||
{ "core calls", "", "", NULL },
|
||||
};
|
||||
|
||||
static void print_usage(switch_stream_handle_t *stream, ftdm_cli_entry_t *cli)
|
||||
{
|
||||
stream->write_function(stream, "-ERR Usage: ftdm %s %s\n", cli->name, cli->args);
|
||||
}
|
||||
|
||||
static void print_full_usage(switch_stream_handle_t *stream)
|
||||
{
|
||||
int i = 0;
|
||||
@@ -4608,7 +4809,7 @@ SWITCH_STANDARD_API(ft_function)
|
||||
for (i = 0 ; i < ftdm_array_len(ftdm_cli_options); i++) {
|
||||
entry = &ftdm_cli_options[i];
|
||||
if (!strcasecmp(argv[0], entry->name) && entry->execute) {
|
||||
entry->execute(cmd, session, stream, argc, argv);
|
||||
entry->execute(entry, cmd, session, stream, argc, argv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ int main(int argc, char *argv[])
|
||||
int fd, b;
|
||||
short sln[512] = {0};
|
||||
teletone_dtmf_detect_state_t dtmf_detect = {0};
|
||||
char digit_str[128] = "";
|
||||
teletone_hit_type_t hit;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Arg Error!\n");
|
||||
@@ -21,10 +21,31 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
while((b = read(fd, sln, 320)) > 0) {
|
||||
char digit_char;
|
||||
unsigned int dur;
|
||||
|
||||
teletone_dtmf_detect(&dtmf_detect, sln, b / 2);
|
||||
teletone_dtmf_get(&dtmf_detect, digit_str, sizeof(digit_str));
|
||||
if (*digit_str) {
|
||||
printf("digit: %s\n", digit_str);
|
||||
if ((hit = teletone_dtmf_get(&dtmf_detect, &digit_char, &dur))) {
|
||||
const char *hs = NULL;
|
||||
|
||||
|
||||
switch(hit) {
|
||||
case TT_HIT_BEGIN:
|
||||
hs = "begin";
|
||||
break;
|
||||
|
||||
case TT_HIT_MIDDLE:
|
||||
hs = "middle";
|
||||
break;
|
||||
|
||||
case TT_HIT_END:
|
||||
hs = "end";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("%s digit: %c\n", hs, digit_char);
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
|
||||
+30
-15
@@ -649,9 +649,6 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span)
|
||||
if (span->fio->span_destroy(span) != FTDM_SUCCESS) {
|
||||
status = FTDM_FAIL;
|
||||
}
|
||||
ftdm_safe_free(span->type);
|
||||
ftdm_safe_free(span->name);
|
||||
ftdm_safe_free(span->dtmf_hangup);
|
||||
}
|
||||
|
||||
/* destroy final basic resources of the span data structure */
|
||||
@@ -1858,7 +1855,14 @@ static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm
|
||||
goto done;
|
||||
}
|
||||
|
||||
ftdm_mutex_lock(check->mutex);
|
||||
ftdm_channel_lock(check);
|
||||
|
||||
if (ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) {
|
||||
/* let them know is already open, but return the channel anyway */
|
||||
status = FTDM_EBUSY;
|
||||
*ftdmchan = check;
|
||||
goto unlockchan;
|
||||
}
|
||||
|
||||
/* The following if's and gotos replace a big if (this || this || this || this) else { nothing; } */
|
||||
|
||||
@@ -1905,7 +1909,7 @@ openchan:
|
||||
goto done;
|
||||
|
||||
unlockchan:
|
||||
ftdm_mutex_unlock(check->mutex);
|
||||
ftdm_channel_unlock(check);
|
||||
|
||||
done:
|
||||
ftdm_mutex_unlock(globals.mutex);
|
||||
@@ -3855,7 +3859,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, v
|
||||
uint8_t sln_buf[1024] = {0};
|
||||
int16_t *sln;
|
||||
ftdm_size_t slen = 0;
|
||||
char digit_str[80] = "";
|
||||
|
||||
if (ftdmchan->effective_codec == FTDM_CODEC_SLIN) {
|
||||
sln = data;
|
||||
@@ -3956,13 +3959,20 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, v
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT) && !ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
|
||||
teletone_dtmf_detect(&ftdmchan->dtmf_detect, sln, (int)slen);
|
||||
teletone_dtmf_get(&ftdmchan->dtmf_detect, digit_str, sizeof(digit_str));
|
||||
teletone_hit_type_t hit;
|
||||
char digit_char;
|
||||
uint32_t dur;
|
||||
|
||||
if(*digit_str) {
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_CALLWAITING && (*digit_str == 'D' || *digit_str == 'A')) {
|
||||
if ((hit = teletone_dtmf_detect(&ftdmchan->dtmf_detect, sln, (int)slen)) == TT_HIT_END) {
|
||||
teletone_dtmf_get(&ftdmchan->dtmf_detect, &digit_char, &dur);
|
||||
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_CALLWAITING && (digit_char == 'D' || digit_char == 'A')) {
|
||||
ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]++;
|
||||
} else {
|
||||
char digit_str[2] = { 0 };
|
||||
|
||||
digit_str[0] = digit_char;
|
||||
|
||||
if (!ftdmchan->span->sig_dtmf || (ftdmchan->span->sig_dtmf(ftdmchan, (const char*)digit_str) != FTDM_BREAK)) {
|
||||
ftdm_channel_queue_dtmf(ftdmchan, digit_str);
|
||||
}
|
||||
@@ -4568,7 +4578,7 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, const
|
||||
*configured = 0;
|
||||
*configured = span->fio->configure_span(span, str, chan_config->type, chan_config->name, chan_config->number);
|
||||
if (!*configured) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%d:Failed to configure span", span->span_id);
|
||||
ftdm_log(FTDM_LOG_ERROR, "%d:Failed to configure span\n", span->span_id);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
@@ -5469,10 +5479,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
||||
if (sigmsg->channel) {
|
||||
fchan = sigmsg->channel;
|
||||
ftdm_channel_lock(fchan);
|
||||
sigmsg->chan_id = fchan->chan_id;
|
||||
sigmsg->span_id = fchan->span_id;
|
||||
sigmsg->call_id = fchan->caller_data.call_id;
|
||||
sigmsg->call_priv = fchan->caller_data.priv;
|
||||
}
|
||||
|
||||
/* some core things to do on special events */
|
||||
@@ -5562,6 +5568,14 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
||||
|
||||
}
|
||||
|
||||
if (fchan) {
|
||||
/* set members of the sigmsg that must be present for all events */
|
||||
sigmsg->chan_id = fchan->chan_id;
|
||||
sigmsg->span_id = fchan->span_id;
|
||||
sigmsg->call_id = fchan->caller_data.call_id;
|
||||
sigmsg->call_priv = fchan->caller_data.priv;
|
||||
}
|
||||
|
||||
/* if the signaling module uses a queue for signaling notifications, then enqueue it */
|
||||
if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) {
|
||||
ftdm_span_queue_signal(span, sigmsg);
|
||||
@@ -5783,6 +5797,7 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
|
||||
}
|
||||
|
||||
hashtable_remove(globals.span_hash, (void *)cur_span->name);
|
||||
ftdm_safe_free(cur_span->dtmf_hangup);
|
||||
ftdm_safe_free(cur_span->type);
|
||||
ftdm_safe_free(cur_span->name);
|
||||
ftdm_safe_free(cur_span);
|
||||
|
||||
@@ -39,7 +39,8 @@ typedef enum {
|
||||
FTDM_ANALOG_RUNNING = (1 << 0),
|
||||
FTDM_ANALOG_CALLERID = (1 << 1),
|
||||
FTDM_ANALOG_ANSWER_POLARITY_REVERSE = (1 << 2),
|
||||
FTDM_ANALOG_HANGUP_POLARITY_REVERSE = (1 << 3)
|
||||
FTDM_ANALOG_HANGUP_POLARITY_REVERSE = (1 << 3),
|
||||
FTDM_ANALOG_POLARITY_CALLERID = (1 << 4)
|
||||
} ftdm_analog_flag_t;
|
||||
|
||||
#define FTDM_MAX_HOTLINE_STR 20
|
||||
|
||||
@@ -275,6 +275,15 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
|
||||
break;
|
||||
}
|
||||
hotline = val;
|
||||
} else if (!strcasecmp(var, "polarity_callerid")) {
|
||||
if (!(val = va_arg(ap, char *))) {
|
||||
break;
|
||||
}
|
||||
if (ftdm_true(val)) {
|
||||
flags |= FTDM_ANALOG_POLARITY_CALLERID;
|
||||
} else {
|
||||
flags &= ~FTDM_ANALOG_POLARITY_CALLERID;
|
||||
}
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Unknown parameter %s in span %s\n", var, span->name);
|
||||
}
|
||||
@@ -1130,8 +1139,18 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
||||
break;
|
||||
}
|
||||
if (event->channel->state == FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG,
|
||||
"Ignoring polarity reversal because this channel is down\n");
|
||||
if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID)
|
||||
&& ftdm_test_flag(analog_data, FTDM_ANALOG_POLARITY_CALLERID)) {
|
||||
ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG, "Polarity reversal detected while down, getting caller id now\n");
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID);
|
||||
event->channel->ring_count = 1;
|
||||
ftdm_mutex_unlock(event->channel->mutex);
|
||||
locked = 0;
|
||||
ftdm_thread_create_detached(ftdm_analog_channel_run, event->channel);
|
||||
} else {
|
||||
ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG,
|
||||
"Ignoring polarity reversal because this channel is down\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* we have a good channel, set the polarity flag and let the channel thread deal with it */
|
||||
|
||||
@@ -204,6 +204,32 @@ static int parse_debug(const char *in, uint32_t *flags)
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Parses a change status string to flags
|
||||
* \param in change status string to parse for
|
||||
* \return Flags
|
||||
*/
|
||||
static int parse_change_status(const char *in)
|
||||
{
|
||||
int flags = 0;
|
||||
if (!in) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(in, "in_service") || strstr(in, "in")) {
|
||||
flags = SERVICE_CHANGE_STATUS_INSERVICE;
|
||||
}
|
||||
if (strstr(in, "maintenance") || strstr(in, "maint")) {
|
||||
flags = SERVICE_CHANGE_STATUS_MAINTENANCE;
|
||||
}
|
||||
if (strstr(in, "out_of_service") || strstr(in, "out")) {
|
||||
flags = SERVICE_CHANGE_STATUS_OUTOFSERVICE;
|
||||
}
|
||||
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static int print_debug(uint32_t flags, char *tmp, const int size)
|
||||
{
|
||||
int offset = 0;
|
||||
@@ -240,6 +266,9 @@ static ftdm_io_interface_t ftdm_libpri_interface;
|
||||
static const char *ftdm_libpri_usage =
|
||||
"Usage:\n"
|
||||
"libpri kill <span>\n"
|
||||
"libpri reset <span>\n"
|
||||
"libpri restart <span> <channel/all>\n"
|
||||
"libpri maintenance <span> <channel/all> <in/maint/out>\n"
|
||||
"libpri debug <span> [all|none|flag,...flagN]\n"
|
||||
"\n"
|
||||
"Possible debug flags:\n"
|
||||
@@ -281,9 +310,7 @@ static FIO_API_FUNCTION(ftdm_libpri_api)
|
||||
stream->write_function(stream, ftdm_libpri_usage);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
} else if (argc == 2) {
|
||||
if (!strcasecmp(argv[0], "kill")) {
|
||||
int span_id = atoi(argv[1]);
|
||||
ftdm_span_t *span = NULL;
|
||||
@@ -292,7 +319,8 @@ static FIO_API_FUNCTION(ftdm_libpri_api)
|
||||
ftdm_libpri_data_t *isdn_data = span->signal_data;
|
||||
|
||||
if (span->start != ftdm_libpri_start) {
|
||||
stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
|
||||
stream->write_function(stream, "%s: -ERR '%s' is not a libpri span.\n",
|
||||
__FILE__, ftdm_span_get_name(span));
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -300,13 +328,12 @@ static FIO_API_FUNCTION(ftdm_libpri_api)
|
||||
stream->write_function(stream, "%s: +OK killed.\n", __FILE__);
|
||||
goto done;
|
||||
} else {
|
||||
stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
|
||||
stream->write_function(stream, "%s: -ERR span '%s' not found.\n",
|
||||
__FILE__, argv[0]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argc >= 2) {
|
||||
} else if (argc >= 2) {
|
||||
if (!strcasecmp(argv[0], "debug")) {
|
||||
ftdm_span_t *span = NULL;
|
||||
|
||||
@@ -315,7 +342,8 @@ static FIO_API_FUNCTION(ftdm_libpri_api)
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (span->start != ftdm_libpri_start) {
|
||||
stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
|
||||
stream->write_function(stream, "%s: -ERR '%s' is not a libpri span.\n",
|
||||
__FILE__, ftdm_span_get_name(span));
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -335,12 +363,95 @@ static FIO_API_FUNCTION(ftdm_libpri_api)
|
||||
stream->write_function(stream, "%s: +OK debug %s.\n", __FILE__, (flags) ? "enabled" : "disabled");
|
||||
goto done;
|
||||
} else {
|
||||
stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
|
||||
stream->write_function(stream, "%s: -ERR span '%s' not found.\n",
|
||||
__FILE__, argv[0]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (!strcasecmp(argv[0], "reset")) {
|
||||
ftdm_span_t *span = NULL;
|
||||
if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) {
|
||||
ftdm_libpri_data_t *isdn_data = span->signal_data;
|
||||
|
||||
if (span->start != ftdm_libpri_start) {
|
||||
stream->write_function(stream, "%s: -ERR '%s' is not a libpri span.\n",
|
||||
__FILE__, ftdm_span_get_name(span));
|
||||
goto done;
|
||||
}
|
||||
|
||||
pri_restart(isdn_data->spri.pri);
|
||||
stream->write_function(stream, "%s: +OK reset.\n", __FILE__);
|
||||
goto done;
|
||||
} else {
|
||||
stream->write_function(stream, "%s: -ERR span '%s' not found.\n",
|
||||
__FILE__, argv[0]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (!strcasecmp(argv[0], "restart") && argc == 3) {
|
||||
ftdm_span_t *span = NULL;
|
||||
if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) {
|
||||
ftdm_libpri_data_t *isdn_data = span->signal_data;
|
||||
|
||||
if (span->start != ftdm_libpri_start) {
|
||||
stream->write_function(stream, "%s: -ERR '%s' is not a libpri span.\n",
|
||||
__FILE__, ftdm_span_get_name(span));
|
||||
goto done;
|
||||
}
|
||||
if (!strcasecmp(argv[2], "all")) {
|
||||
int j;
|
||||
for(j = 1; j <= span->chan_count; j++) {
|
||||
pri_reset(isdn_data->spri.pri, j);
|
||||
ftdm_sleep(50);
|
||||
}
|
||||
} else {
|
||||
pri_reset(isdn_data->spri.pri, atoi(argv[2]));
|
||||
}
|
||||
stream->write_function(stream, "%s: +OK restart set.\n", __FILE__);
|
||||
goto done;
|
||||
} else {
|
||||
stream->write_function(stream, "%s: -ERR span '%s' not found.\n",
|
||||
__FILE__, argv[0]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (!strcasecmp(argv[0], "maintenance") && argc > 3) {
|
||||
ftdm_span_t *span = NULL;
|
||||
if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) {
|
||||
ftdm_libpri_data_t *isdn_data = span->signal_data;
|
||||
|
||||
if (span->start != ftdm_libpri_start) {
|
||||
stream->write_function(stream, "%s: -ERR '%s' is not a libpri span.\n",
|
||||
__FILE__, ftdm_span_get_name(span));
|
||||
goto done;
|
||||
}
|
||||
if (!isdn_data->service_message_support) {
|
||||
stream->write_function(stream, "%s: -ERR service message support is disabled\n", __FILE__);
|
||||
goto done;
|
||||
}
|
||||
if (!strcasecmp(argv[2], "all")) {
|
||||
int j;
|
||||
for(j = 1; j <= span->chan_count; j++) {
|
||||
pri_maintenance_service(isdn_data->spri.pri, atoi(argv[1]), j, parse_change_status(argv[3]));
|
||||
ftdm_sleep(50);
|
||||
}
|
||||
} else {
|
||||
pri_maintenance_service(isdn_data->spri.pri, atoi(argv[1]), atoi(argv[2]), parse_change_status(argv[3]));
|
||||
}
|
||||
stream->write_function(stream, "%s: +OK change status set.\n", __FILE__);
|
||||
goto done;
|
||||
} else {
|
||||
stream->write_function(stream, "%s: -ERR span '%s' not found.\n",
|
||||
__FILE__, argv[0]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* zero args print usage */
|
||||
stream->write_function(stream, ftdm_libpri_usage);
|
||||
goto done;
|
||||
}
|
||||
|
||||
stream->write_function(stream, "%s: -ERR invalid command.\n", __FILE__);
|
||||
|
||||
done:
|
||||
@@ -1066,7 +1177,7 @@ static int on_proceeding(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_
|
||||
|
||||
if (chan) {
|
||||
/* Open channel if inband information is available */
|
||||
if (pevent->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
|
||||
if (pevent->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE || pevent->proceeding.progressmask & PRI_PROG_CALL_NOT_E2E_ISDN) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- In-band information available, B-Channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
@@ -1108,7 +1219,7 @@ static int on_progress(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev
|
||||
|
||||
if (chan) {
|
||||
/* Open channel if inband information is available */
|
||||
if (pevent->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
|
||||
if (pevent->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE || pevent->proceeding.progressmask & PRI_PROG_CALL_NOT_E2E_ISDN) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- In-band information available, B-Channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
@@ -1780,6 +1891,10 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
|
||||
pri_facility_enable(isdn_data->spri.pri);
|
||||
}
|
||||
#endif
|
||||
/* Support the different switch of service status */
|
||||
if (isdn_data->service_message_support) {
|
||||
pri_set_service_message_support(isdn_data->spri.pri, 1 /* True */);
|
||||
}
|
||||
|
||||
if (res == 0) {
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_ANY, on_anything);
|
||||
@@ -1835,6 +1950,14 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
|
||||
ftdm_sleep(5000);
|
||||
}
|
||||
out:
|
||||
/* close d-channel, if set */
|
||||
if (isdn_data->dchan) {
|
||||
if (ftdm_channel_close(&isdn_data->dchan) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to close D-Channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(isdn_data->dchan), ftdm_channel_get_id(isdn_data->dchan));
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "PRI thread ended on span %d\n", ftdm_span_get_id(span));
|
||||
|
||||
ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
|
||||
@@ -2159,6 +2282,11 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
|
||||
isdn_data->debug_mask = 0;
|
||||
}
|
||||
}
|
||||
else if (!strcasecmp(var, "service_message_support")) {
|
||||
if (ftdm_true(val)) {
|
||||
isdn_data->service_message_support = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Unknown parameter '%s', aborting configuration\n", var);
|
||||
snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var);
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
SERVICE_CHANGE_STATUS_INSERVICE = 0,
|
||||
SERVICE_CHANGE_STATUS_MAINTENANCE = 1,
|
||||
SERVICE_CHANGE_STATUS_OUTOFSERVICE = 2
|
||||
} service_change_status_t;
|
||||
|
||||
#ifndef FTMOD_LIBPRI_H
|
||||
#define FTMOD_LIBPRI_H
|
||||
@@ -69,6 +74,7 @@ struct ftdm_libpri_data {
|
||||
int overlap; /*!< Overlap dial flags */
|
||||
unsigned int layer1;
|
||||
unsigned int ton;
|
||||
unsigned int service_message_support;
|
||||
|
||||
lpwrap_pri_t spri;
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -547,7 +547,7 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e)
|
||||
break;
|
||||
|
||||
case PRI_EVENT_PROGRESS:
|
||||
crv = tap_pri_get_crv(pritap->pri, e->ring.call);
|
||||
crv = tap_pri_get_crv(pritap->pri, e->proceeding.call);
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Progress on channel %s:%d:%d with callref %d\n",
|
||||
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
|
||||
break;
|
||||
|
||||
@@ -1155,6 +1155,77 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (span_data->cid_name_method == SNGISDN_CID_NAME_AUTO) {
|
||||
switch (span_data->switchtype) {
|
||||
case SNGISDN_SWITCH_EUROISDN:
|
||||
if (FTDM_SPAN_IS_BRI(span)) {
|
||||
span_data->cid_name_method = SNGISDN_CID_NAME_USR_USR_IE;
|
||||
} else {
|
||||
span_data->cid_name_method = SNGISDN_CID_NAME_DISPLAY_IE;
|
||||
}
|
||||
break;
|
||||
case SNGISDN_SWITCH_DMS100:
|
||||
span_data->cid_name_method = SNGISDN_CID_NAME_DISPLAY_IE;
|
||||
break;
|
||||
case SNGISDN_SWITCH_NI2:
|
||||
case SNGISDN_SWITCH_5ESS:
|
||||
case SNGISDN_SWITCH_4ESS:
|
||||
span_data->cid_name_method = SNGISDN_CID_NAME_FACILITY_IE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (span_data->send_cid_name == SNGISDN_OPT_DEFAULT) {
|
||||
switch (span_data->switchtype) {
|
||||
case SNGISDN_SWITCH_EUROISDN:
|
||||
#ifdef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY
|
||||
case SNGISDN_SWITCH_NI2:
|
||||
case SNGISDN_SWITCH_5ESS:
|
||||
case SNGISDN_SWITCH_4ESS:
|
||||
#endif
|
||||
if (span_data->signalling == SNGISDN_SIGNALING_NET) {
|
||||
span_data->send_cid_name = SNGISDN_OPT_TRUE;
|
||||
} else {
|
||||
span_data->send_cid_name = SNGISDN_OPT_FALSE;
|
||||
}
|
||||
break;
|
||||
case SNGISDN_SWITCH_DMS100:
|
||||
span_data->send_cid_name = SNGISDN_OPT_TRUE;
|
||||
break;
|
||||
#ifndef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY
|
||||
case SNGISDN_SWITCH_NI2:
|
||||
case SNGISDN_SWITCH_5ESS:
|
||||
case SNGISDN_SWITCH_4ESS:
|
||||
span_data->send_cid_name = SNGISDN_OPT_FALSE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
span_data->send_cid_name = SNGISDN_OPT_FALSE;
|
||||
break;
|
||||
}
|
||||
} else if (span_data->send_cid_name == SNGISDN_OPT_TRUE) {
|
||||
switch (span_data->switchtype) {
|
||||
case SNGISDN_SWITCH_NI2:
|
||||
case SNGISDN_SWITCH_5ESS:
|
||||
case SNGISDN_SWITCH_4ESS:
|
||||
#ifndef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY
|
||||
ftdm_log(FTDM_LOG_WARNING, "Sending Calling Name in Facility IE not supported, please update your libsng_isdn library\n");
|
||||
span_data->send_cid_name = SNGISDN_OPT_FALSE;
|
||||
#endif
|
||||
break;
|
||||
case SNGISDN_SWITCH_INSNET: /* Don't know how to transmit caller ID name on INSNET */
|
||||
case SNGISDN_SWITCH_QSIG: /* It seems like QSIG does not support Caller ID */
|
||||
span_data->send_cid_name = SNGISDN_OPT_FALSE;
|
||||
break;
|
||||
case SNGISDN_SWITCH_EUROISDN:
|
||||
break;
|
||||
default:
|
||||
span_data->send_cid_name = SNGISDN_OPT_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
span->start = ftdm_sangoma_isdn_start;
|
||||
span->stop = ftdm_sangoma_isdn_stop;
|
||||
|
||||
@@ -132,6 +132,13 @@ typedef enum {
|
||||
SNGISDN_AVAIL_UP = 10,
|
||||
} sngisdn_avail_t;
|
||||
|
||||
typedef enum {
|
||||
SNGISDN_CID_NAME_AUTO,
|
||||
SNGISDN_CID_NAME_DISPLAY_IE,
|
||||
SNGISDN_CID_NAME_USR_USR_IE,
|
||||
SNGISDN_CID_NAME_FACILITY_IE,
|
||||
} sngisdn_cid_name_t;
|
||||
|
||||
typedef enum {
|
||||
SNGISDN_EVENT_CON_IND = 1,
|
||||
SNGISDN_EVENT_CON_CFM,
|
||||
@@ -264,6 +271,8 @@ typedef struct sngisdn_span_data {
|
||||
uint8_t restart_opt;
|
||||
uint8_t restart_timeout;
|
||||
uint8_t force_sending_complete;
|
||||
uint8_t cid_name_method;
|
||||
uint8_t send_cid_name;
|
||||
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
|
||||
ftdm_timer_id_t timers[SNGISDN_NUM_SPAN_TIMERS];
|
||||
ftdm_sched_t *sched;
|
||||
|
||||
@@ -289,6 +289,9 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
||||
signal_data->att_remove_dtmf = SNGISDN_OPT_DEFAULT;
|
||||
signal_data->force_sending_complete = SNGISDN_OPT_DEFAULT;
|
||||
|
||||
signal_data->cid_name_method = SNGISDN_CID_NAME_AUTO;
|
||||
signal_data->send_cid_name = SNGISDN_OPT_DEFAULT;
|
||||
|
||||
span->default_caller_data.dnis.plan = FTDM_NPI_INVALID;
|
||||
span->default_caller_data.dnis.type = FTDM_TON_INVALID;
|
||||
span->default_caller_data.cid_num.plan = FTDM_NPI_INVALID;
|
||||
@@ -361,7 +364,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
||||
parse_yesno(var, val, &signal_data->restart_opt);
|
||||
} else if (!strcasecmp(var, "channel-restart-timeout")) {
|
||||
signal_data->restart_timeout = atoi(val);
|
||||
} else if (!strcasecmp(var, "local-number")) {
|
||||
} else if (!strcasecmp(var, "local-number")) {
|
||||
if (add_local_number(val, span) != FTDM_SUCCESS) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
@@ -401,6 +404,30 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
||||
#else
|
||||
ftdm_log(FTDM_LOG_WARNING, "chan-id-invert-extend-bit is not supported in your version of libsng_isdn\n");
|
||||
#endif
|
||||
} else if (!strcasecmp(var, "cid-name-transmit-method")) {
|
||||
if (!strcasecmp(val, "display-ie")) {
|
||||
signal_data->cid_name_method = SNGISDN_CID_NAME_DISPLAY_IE;
|
||||
} else if (!strcasecmp(val, "user-user-ie")) {
|
||||
signal_data->cid_name_method = SNGISDN_CID_NAME_USR_USR_IE;
|
||||
} else if (!strcasecmp(val, "facility-ie")) {
|
||||
signal_data->cid_name_method = SNGISDN_CID_NAME_FACILITY_IE;
|
||||
} else if (!strcasecmp(val, "auto") || !strcasecmp(val, "automatic") || !strcasecmp(val, "default")) {
|
||||
signal_data->cid_name_method = SNGISDN_CID_NAME_AUTO;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid option %s for parameter %s\n", val, var);
|
||||
signal_data->cid_name_method = SNGISDN_CID_NAME_AUTO;
|
||||
}
|
||||
} else if (!strcasecmp(var, "send-cid-name")) {
|
||||
if (!strcasecmp(val, "yes")) {
|
||||
signal_data->send_cid_name = SNGISDN_OPT_TRUE;
|
||||
} else if (!strcasecmp(val, "no")) {
|
||||
signal_data->send_cid_name = SNGISDN_OPT_FALSE;
|
||||
} else if (!strcasecmp(val, "auto") || !strcasecmp(val, "automatic") || !strcasecmp(val, "default")) {
|
||||
signal_data->send_cid_name = SNGISDN_OPT_DEFAULT;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid option %s for parameter %s\n", val, var);
|
||||
signal_data->send_cid_name = SNGISDN_OPT_DEFAULT;
|
||||
}
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
|
||||
}
|
||||
|
||||
@@ -681,7 +681,11 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
||||
cfg.t.cfg.s.inDLSAP.clrGlr = FALSE; /* in case of glare, do not clear local call */
|
||||
cfg.t.cfg.s.inDLSAP.statEnqOpt = TRUE;
|
||||
|
||||
cfg.t.cfg.s.inDLSAP.rstOpt = TRUE;
|
||||
if (signal_data->ftdm_span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
cfg.t.cfg.s.inDLSAP.rstOpt = FALSE;
|
||||
} else {
|
||||
cfg.t.cfg.s.inDLSAP.rstOpt = TRUE;
|
||||
}
|
||||
} else {
|
||||
cfg.t.cfg.s.inDLSAP.ackOpt = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.intType = USER;
|
||||
@@ -772,15 +776,13 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t307.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t308.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t308.val = 4;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.val = 120;
|
||||
|
||||
if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.val = 10;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t312.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t312.val = cfg.t.cfg.s.inDLSAP.tmr.t303.val+2;
|
||||
} else {
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.val = 120;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t312.enb = FALSE;
|
||||
}
|
||||
|
||||
@@ -846,7 +848,7 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
||||
cfg.t.cfg.s.inDLSAP.dChannelNum = 0; /* Unused for BRI */
|
||||
cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_BRI_CHANNELS_PER_SPAN;
|
||||
cfg.t.cfg.s.inDLSAP.firstBChanNum = 1;
|
||||
cfg.t.cfg.s.inDLSAP.callRefLen = 1;
|
||||
cfg.t.cfg.s.inDLSAP.callRefLen = 1;
|
||||
cfg.t.cfg.s.inDLSAP.teiAlloc = IN_STATIC;
|
||||
cfg.t.cfg.s.inDLSAP.intCfg = IN_INTCFG_PTPT;
|
||||
break;
|
||||
@@ -902,7 +904,14 @@ ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span)
|
||||
|
||||
cfg.t.cfg.s.inLCe.sapId = signal_data->dchan_id;
|
||||
|
||||
cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE;
|
||||
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
/* Stack will send Restart CFM's each time link is established (TEI negotiated),
|
||||
and we do not want thi s event */
|
||||
cfg.t.cfg.s.inLCe.lnkUpDwnInd = FALSE;
|
||||
} else {
|
||||
cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE;
|
||||
}
|
||||
|
||||
cfg.t.cfg.s.inLCe.tCon.enb = TRUE;
|
||||
cfg.t.cfg.s.inLCe.tCon.val = 35;
|
||||
cfg.t.cfg.s.inLCe.tDisc.enb = TRUE;
|
||||
|
||||
@@ -1178,7 +1178,16 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received RESTART CFM on unconfigured span (suId:%d)\n", suId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s: Processing RESTART CFM (suId:%u dChan:%d ces:%d %s(%d))\n",
|
||||
signal_data->ftdm_span->name,
|
||||
suId, dChan, ces,
|
||||
(evntType == IN_LNK_DWN)?"LNK_DOWN":
|
||||
(evntType == IN_LNK_UP)?"LNK_UP":
|
||||
(evntType == IN_INDCHAN)?"b-channel":
|
||||
(evntType == IN_LNK_DWN_DM_RLS)?"NFAS service procedures":
|
||||
(evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown", evntType);
|
||||
|
||||
if (rstEvnt->rstInd.eh.pres == PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres == PRSNT_NODEF) {
|
||||
switch(rstEvnt->rstInd.rstClass.val) {
|
||||
case IN_CL_INDCHAN: /* Indicated b-channel */
|
||||
@@ -1212,19 +1221,29 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
|
||||
}
|
||||
|
||||
if (chan_no) { /* For a single channel */
|
||||
if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received RESTART on invalid channel:%d\n", chan_no);
|
||||
} else {
|
||||
ftdm_channel_t *ftdmchan = ftdm_span_get_channel(signal_data->ftdm_span, chan_no);
|
||||
sngisdn_bring_down(ftdmchan);
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
if (sngisdn_info->ces == ces && ftdmchan->physical_chan_id == chan_no) {
|
||||
sngisdn_bring_down(ftdmchan);
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
} else { /* for all channels */
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
sngisdn_bring_down((ftdm_channel_t*)ftdm_iterator_current(curr));
|
||||
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
if (sngisdn_info->ces == ces) {
|
||||
sngisdn_bring_down(ftdmchan);
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
@@ -1305,28 +1324,29 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
|
||||
}
|
||||
|
||||
if (chan_no) { /* For a single channel */
|
||||
if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received RESTART IND on invalid channel:%d\n", chan_no);
|
||||
} else {
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
|
||||
if (ftdmchan->physical_chan_id == chan_no) {
|
||||
sngisdn_bring_down(ftdmchan);
|
||||
}
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
if (sngisdn_info->ces == ces && ftdmchan->physical_chan_id == chan_no) {
|
||||
sngisdn_bring_down(ftdmchan);
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
} else { /* for all channels */
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
sngisdn_bring_down((ftdm_channel_t*)ftdm_iterator_current(curr));
|
||||
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
if (sngisdn_info->ces == ces) {
|
||||
sngisdn_bring_down(ftdmchan);
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
||||
set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad);
|
||||
set_redir_num(ftdmchan, &conEvnt.redirNmb);
|
||||
set_calling_name(ftdmchan, &conEvnt);
|
||||
|
||||
/* set_facility_ie will overwrite Calling Name for NI-2 if user specifies custom Facility IE */
|
||||
set_facility_ie(ftdmchan, &conEvnt.facilityStr);
|
||||
set_prog_ind_ie(ftdmchan, &conEvnt.progInd, prog_ind);
|
||||
|
||||
|
||||
@@ -897,12 +897,19 @@ int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame)
|
||||
do {
|
||||
flags = FTDM_WRITE;
|
||||
status = signal_data->dchan->fio->wait(signal_data->dchan, &flags, 1000);
|
||||
if (status != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_WARNING, "transmit timed-out\n");
|
||||
return -1;
|
||||
switch(status) {
|
||||
case FTDM_SUCCESS:
|
||||
break;
|
||||
case FTDM_TIMEOUT:
|
||||
continue;
|
||||
case FTDM_FAIL:
|
||||
default:
|
||||
ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_WARNING, "failed to poll for channel\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* status = FTDM_SUCCESS */
|
||||
if ((flags & FTDM_WRITE)) {
|
||||
#if 0
|
||||
int i;
|
||||
@@ -990,27 +997,29 @@ void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...)
|
||||
|
||||
switch (level) {
|
||||
case SNG_LOGLEVEL_DEBUG:
|
||||
ftdm_log(FTDM_LOG_DEBUG, "sng_isdn->%s", data);
|
||||
ftdm_log(FTDM_LOG_DEBUG, "sng_isdn->%s\n", data);
|
||||
break;
|
||||
case SNG_LOGLEVEL_WARN:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
if ( strncmp(data, "Invalid Q.921/Q.931 frame", 25) ) {
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
}
|
||||
break;
|
||||
case SNG_LOGLEVEL_INFO:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s\n", data);
|
||||
break;
|
||||
case SNG_LOGLEVEL_STATS:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s\n", data);
|
||||
break;
|
||||
case SNG_LOGLEVEL_ERROR:
|
||||
ftdm_log(FTDM_LOG_ERROR, "sng_isdn->%s", data);
|
||||
ftdm_log(FTDM_LOG_ERROR, "sng_isdn->%s\n", data);
|
||||
/*ftdm_assert(0, "Got an error from stack");*/
|
||||
break;
|
||||
case SNG_LOGLEVEL_CRIT:
|
||||
ftdm_log(FTDM_LOG_CRIT, "sng_isdn->%s", data);
|
||||
ftdm_log(FTDM_LOG_CRIT, "sng_isdn->%s\n", data);
|
||||
/* ftdm_assert(0, "Got an error from stack"); */
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s\n", data);
|
||||
break;
|
||||
}
|
||||
ftdm_safe_free(data);
|
||||
|
||||
@@ -567,7 +567,7 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
|
||||
string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.digits");
|
||||
if ((string == NULL) || !(*string)) {
|
||||
if (ftdm_strlen_zero(string)) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
@@ -696,63 +696,71 @@ ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
|
||||
ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt)
|
||||
{
|
||||
uint8_t len;
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
/* sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; */
|
||||
const char *string = NULL;
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_bool_t force_send_cid_name = FTDM_FALSE;
|
||||
|
||||
len = strlen(caller_data->cid_name);
|
||||
if (!len) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
conEvnt->usrUsr.eh.pres = PRSNT_NODEF;
|
||||
conEvnt->usrUsr.protocolDisc.pres = PRSNT_NODEF;
|
||||
conEvnt->usrUsr.protocolDisc.val = PD_IA5; /* IA5 chars */
|
||||
conEvnt->usrUsr.usrInfo.pres = PRSNT_NODEF;
|
||||
conEvnt->usrUsr.usrInfo.len = len;
|
||||
/* in sangoma_brid we used to send usr-usr info as <cid_name>!<calling_number>,
|
||||
change to previous style if current one does not work */
|
||||
memcpy(conEvnt->usrUsr.usrInfo.val, caller_data->cid_name, len);
|
||||
} else {
|
||||
switch (signal_data->switchtype) {
|
||||
case SNGISDN_SWITCH_NI2:
|
||||
/* TODO: Need to send the caller ID as a facility IE */
|
||||
|
||||
break;
|
||||
case SNGISDN_SWITCH_EUROISDN:
|
||||
if (signal_data->signalling != SNGISDN_SIGNALING_NET) {
|
||||
break;
|
||||
}
|
||||
/* follow through */
|
||||
case SNGISDN_SWITCH_5ESS:
|
||||
case SNGISDN_SWITCH_4ESS:
|
||||
conEvnt->display.dispInfo.pres = PRSNT_NODEF;
|
||||
conEvnt->display.dispInfo.len = len;
|
||||
memcpy(conEvnt->display.dispInfo.val, caller_data->cid_name, len);
|
||||
break;
|
||||
case SNGISDN_SWITCH_DMS100:
|
||||
conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].dispTypeNt.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].dispTypeNt.val = 0x01; /* Calling Party Name */
|
||||
conEvnt->ntDisplay[0].assocInfo.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].assocInfo.val = 0x03; /* Included */
|
||||
conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].dispInfo.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].dispInfo.len = len;
|
||||
memcpy(conEvnt->ntDisplay[0].dispInfo.val, caller_data->cid_name, len);
|
||||
break;
|
||||
case SNGISDN_SWITCH_QSIG:
|
||||
/* It seems like QSIG does not support Caller ID Name */
|
||||
break;
|
||||
case SNGISDN_SWITCH_INSNET:
|
||||
/* Don't know how to transmit caller ID name on INSNET */
|
||||
break;
|
||||
string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.send_cid_name");
|
||||
if (!ftdm_strlen_zero(string)) {
|
||||
if (!strcasecmp(string, "no")) {
|
||||
return FTDM_SUCCESS;
|
||||
} else if (!strcasecmp(string, "yes")) {
|
||||
force_send_cid_name = FTDM_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (force_send_cid_name == FTDM_FALSE && signal_data->send_cid_name == SNGISDN_OPT_FALSE) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
switch(signal_data->cid_name_method) {
|
||||
case SNGISDN_CID_NAME_FACILITY_IE:
|
||||
#ifdef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY
|
||||
/* Note: The Facility IE will be overwritten if user chose to transmit a Raw Facility IE */
|
||||
sng_isdn_encode_facility_caller_name(caller_data->cid_name, conEvnt->facilityStr.facilityStr.val, &conEvnt->facilityStr.facilityStr.len);
|
||||
conEvnt->facilityStr.eh.pres = PRSNT_NODEF;
|
||||
conEvnt->facilityStr.facilityStr.pres = PRSNT_NODEF;
|
||||
#endif
|
||||
break;
|
||||
case SNGISDN_CID_NAME_USR_USR_IE:
|
||||
conEvnt->usrUsr.eh.pres = PRSNT_NODEF;
|
||||
conEvnt->usrUsr.protocolDisc.pres = PRSNT_NODEF;
|
||||
conEvnt->usrUsr.protocolDisc.val = PD_IA5; /* IA5 chars */
|
||||
conEvnt->usrUsr.usrInfo.pres = PRSNT_NODEF;
|
||||
conEvnt->usrUsr.usrInfo.len = len;
|
||||
/* in sangoma_brid we used to send usr-usr info as <cid_name>!<calling_number>,
|
||||
change to previous style if current one does not work */
|
||||
memcpy(conEvnt->usrUsr.usrInfo.val, caller_data->cid_name, len);
|
||||
break;
|
||||
case SNGISDN_CID_NAME_DISPLAY_IE:
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_DMS100) {
|
||||
conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].dispTypeNt.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].dispTypeNt.val = 0x01; /* Calling Party Name */
|
||||
conEvnt->ntDisplay[0].assocInfo.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].assocInfo.val = 0x03; /* Included */
|
||||
conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].dispInfo.pres = PRSNT_NODEF;
|
||||
conEvnt->ntDisplay[0].dispInfo.len = len;
|
||||
memcpy(conEvnt->ntDisplay[0].dispInfo.val, caller_data->cid_name, len);
|
||||
} else {
|
||||
conEvnt->display.eh.pres = PRSNT_NODEF;
|
||||
conEvnt->display.dispInfo.pres = PRSNT_NODEF;
|
||||
conEvnt->display.dispInfo.len = len;
|
||||
memcpy(conEvnt->display.dispInfo.val, caller_data->cid_name, len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -760,7 +768,7 @@ ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
|
||||
{
|
||||
const char* clg_subaddr = NULL;
|
||||
clg_subaddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.calling_subaddr");
|
||||
if ((clg_subaddr != NULL) && (*clg_subaddr)) {
|
||||
if (!ftdm_strlen_zero(clg_subaddr)) {
|
||||
unsigned len = strlen (clg_subaddr);
|
||||
cgPtySad->eh.pres = PRSNT_NODEF;
|
||||
cgPtySad->typeSad.pres = 1;
|
||||
|
||||
@@ -249,6 +249,34 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
||||
SS7_DEBUG_CHAN(ftdmchan, "No Location Number information in IAM%s\n", " ");
|
||||
}
|
||||
|
||||
/* Retrieve the Location Number if present (see ITU Q.763, 3.30) */
|
||||
if (siConEvnt->cgPtyNum1.eh.pres) {
|
||||
if (siConEvnt->cgPtyNum1.addrSig.pres) {
|
||||
/* fill in the ss7 location address number */
|
||||
copy_tknStr_from_sngss7(siConEvnt->cgPtyNum1.addrSig, var, siConEvnt->cgPtyNum1.oddEven);
|
||||
sngss7_add_var(sngss7_info, "ss7_loc_digits", var);
|
||||
}
|
||||
|
||||
if (siConEvnt->cgPtyNum1.scrnInd.pres) {
|
||||
/* fill in the screening indication value */
|
||||
sprintf(var, "%d", siConEvnt->cgPtyNum1.scrnInd.val);
|
||||
sngss7_add_var(sngss7_info, "ss7_loc_screen_ind", var);
|
||||
}
|
||||
|
||||
if (siConEvnt->cgPtyNum1.presRest.pres) {
|
||||
/* fill in the presentation value */
|
||||
sprintf(var, "%d", siConEvnt->cgPtyNum1.presRest.val);
|
||||
sngss7_add_var(sngss7_info, "ss7_loc_pres_ind", var);
|
||||
}
|
||||
|
||||
if (siConEvnt->cgPtyNum1.natAddrInd.pres) {
|
||||
sprintf(var, "%d", siConEvnt->cgPtyNum1.natAddrInd.val);
|
||||
sngss7_add_var(sngss7_info, "ss7_loc_nadi", var);
|
||||
}
|
||||
} else {
|
||||
SS7_DEBUG_CHAN(ftdmchan, "No Location Number information in IAM%s\n", " ");
|
||||
}
|
||||
|
||||
sprintf(var, "%d", sngss7_info->circuit->cic);
|
||||
sngss7_add_var(sngss7_info, "ss7_cic", var);
|
||||
|
||||
@@ -256,11 +284,10 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
||||
sngss7_add_var(sngss7_info, "ss7_opc", var);
|
||||
|
||||
if (siConEvnt->callRef.callId.pres) {
|
||||
/* %x expect an unsigned int so as callId is a U32, casting to uint32_t
|
||||
* is safe */
|
||||
sprintf(var, "%x", (uint32_t)siConEvnt->callRef.callId.val);
|
||||
sngss7_add_var(sngss7_info, "ss7_callref", var);
|
||||
}
|
||||
ftdmchan->caller_data.call_reference = (unsigned int)siConEvnt->callRef.callId.val;
|
||||
} else {
|
||||
ftdmchan->caller_data.call_reference = 0;
|
||||
}
|
||||
|
||||
if (sngss7_info->circuit->transparent_iam) {
|
||||
sngss7_save_iam(ftdmchan, siConEvnt);
|
||||
|
||||
@@ -39,6 +39,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef WP_DEBUG_IO
|
||||
#define _BSD_SOURCE
|
||||
#include <syscall.h>
|
||||
#endif
|
||||
|
||||
#ifdef __sun
|
||||
#include <unistd.h>
|
||||
#include <stropts.h>
|
||||
@@ -99,6 +104,17 @@ static struct {
|
||||
uint32_t ring_off_ms;
|
||||
} wp_globals;
|
||||
|
||||
typedef struct {
|
||||
sangoma_wait_obj_t *waitobj;
|
||||
#ifdef WP_DEBUG_IO
|
||||
/* record the last reader threads */
|
||||
pid_t readers[10];
|
||||
int rindex;
|
||||
ftdm_time_t last_read;
|
||||
#endif
|
||||
} wp_channel_t;
|
||||
#define WP_GET_WAITABLE(fchan) ((wp_channel_t *)((fchan)->io_data))->waitobj
|
||||
|
||||
/* a bunch of this stuff should go into the wanpipe_tdm_api_iface.h */
|
||||
|
||||
FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event);
|
||||
@@ -123,7 +139,7 @@ static __inline__ int tdmv_api_wait_socket(ftdm_channel_t *ftdmchan, int timeout
|
||||
int err;
|
||||
uint32_t inflags = *flags;
|
||||
uint32_t outflags = 0;
|
||||
sangoma_wait_obj_t *sangoma_wait_obj = ftdmchan->io_data;
|
||||
sangoma_wait_obj_t *sangoma_wait_obj = WP_GET_WAITABLE(ftdmchan);
|
||||
|
||||
if (timeout == -1) {
|
||||
timeout = SANGOMA_WAIT_INFINITE;
|
||||
@@ -254,9 +270,13 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
|
||||
}
|
||||
|
||||
if (ftdm_span_add_channel(span, sockfd, type, &chan) == FTDM_SUCCESS) {
|
||||
wp_channel_t *wpchan = NULL;
|
||||
wanpipe_tdm_api_t tdm_api;
|
||||
memset(&tdm_api, 0, sizeof(tdm_api));
|
||||
#ifdef LIBSANGOMA_VERSION
|
||||
wpchan = ftdm_calloc(1, sizeof(*wpchan));
|
||||
ftdm_assert(wpchan != NULL, "wpchan alloc failed\n");
|
||||
chan->io_data = wpchan;
|
||||
/* we need SANGOMA_DEVICE_WAIT_OBJ_SIG and not SANGOMA_DEVICE_WAIT_OBJ alone because we need to call
|
||||
* sangoma_wait_obj_sig to wake up any I/O waiters when closing the channel (typically on ftdm shutdown)
|
||||
* this adds an extra pair of file descriptors to the waitable object
|
||||
@@ -266,7 +286,7 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
|
||||
ftdm_log(FTDM_LOG_ERROR, "failure create waitable object for s%dc%d\n", spanno, x);
|
||||
continue;
|
||||
}
|
||||
chan->io_data = sangoma_wait_obj;
|
||||
WP_GET_WAITABLE(chan) = sangoma_wait_obj;
|
||||
#endif
|
||||
|
||||
chan->physical_span_id = spanno;
|
||||
@@ -580,9 +600,16 @@ static FIO_OPEN_FUNCTION(wanpipe_open)
|
||||
static FIO_CLOSE_FUNCTION(wanpipe_close)
|
||||
{
|
||||
#ifdef LIBSANGOMA_VERSION
|
||||
sangoma_wait_obj_t *waitobj = ftdmchan->io_data;
|
||||
sangoma_wait_obj_t *waitobj = WP_GET_WAITABLE(ftdmchan);
|
||||
/* kick any I/O waiters */
|
||||
sangoma_wait_obj_signal(waitobj);
|
||||
#ifdef WP_DEBUG_IO
|
||||
{
|
||||
wp_channel_t *wchan = ftdmchan->io_data;
|
||||
memset(wchan->readers, 0, sizeof(wchan->readers));
|
||||
wchan->rindex = 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
@@ -944,10 +971,44 @@ static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx
|
||||
static FIO_READ_FUNCTION(wanpipe_read)
|
||||
{
|
||||
int rx_len = 0;
|
||||
int rq_len = (int)*datalen;
|
||||
wp_tdm_api_rx_hdr_t hdrframe;
|
||||
|
||||
memset(&hdrframe, 0, sizeof(hdrframe));
|
||||
#ifdef WP_DEBUG_IO
|
||||
wp_channel_t *wchan = ftdmchan->io_data;
|
||||
ftdm_time_t time_diff = 0;
|
||||
pid_t previous_thread = 1;
|
||||
pid_t current_thread = 0;
|
||||
int previous_thread_index = 0;
|
||||
|
||||
previous_thread_index = wchan->rindex == 0 ? (ftdm_array_len(wchan->readers) - 1) : wchan->rindex - 1;
|
||||
previous_thread = wchan->readers[previous_thread_index];
|
||||
current_thread = syscall(SYS_gettid);
|
||||
if (current_thread && current_thread != wchan->readers[wchan->rindex]) {
|
||||
if (!wchan->readers[wchan->rindex]) {
|
||||
wchan->readers[wchan->rindex] = current_thread;
|
||||
/* first read */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Initial reader thread is %d\n", current_thread);
|
||||
previous_thread = current_thread;
|
||||
} else {
|
||||
previous_thread = wchan->readers[wchan->rindex];
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Changed reader thread from %d to %d (rindex = %d)\n",
|
||||
previous_thread, current_thread, wchan->rindex);
|
||||
if (wchan->rindex == (ftdm_array_len(wchan->readers) - 1)) {
|
||||
wchan->rindex = 0;
|
||||
} else {
|
||||
wchan->rindex++;
|
||||
}
|
||||
wchan->readers[wchan->rindex] = current_thread;
|
||||
}
|
||||
}
|
||||
ftdm_time_t curr = ftdm_current_time_in_ms();
|
||||
if (wchan->last_read) {
|
||||
time_diff = curr - wchan->last_read;
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&hdrframe, 0, sizeof(hdrframe));
|
||||
rx_len = sangoma_readmsg_tdm(ftdmchan->sockfd, &hdrframe, (int)sizeof(hdrframe), data, (int)*datalen, 0);
|
||||
*datalen = rx_len;
|
||||
|
||||
@@ -957,14 +1018,20 @@ static FIO_READ_FUNCTION(wanpipe_read)
|
||||
}
|
||||
|
||||
if (rx_len < 0) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno));
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read from sangoma device: %s (%d)\n", strerror(errno), rx_len);
|
||||
#ifdef WP_DEBUG_IO
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read %d bytes from sangoma device: %s (%d) "
|
||||
"(read time diff = %llums, prev thread = %d, curr thread = %d)\n", rq_len, strerror(errno), rx_len,
|
||||
time_diff, previous_thread, current_thread);
|
||||
#else
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read %d bytes from sangoma device: %s (%d)\n", rq_len, strerror(errno), rx_len);
|
||||
#endif
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) {
|
||||
wanpipe_read_stats(ftdmchan, &hdrframe);
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1110,7 +1177,7 @@ FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event)
|
||||
if (!ftdmchan->io_data) {
|
||||
continue; /* should never happen but happens when shutting down */
|
||||
}
|
||||
pfds[j] = ftdmchan->io_data;
|
||||
pfds[j] = WP_GET_WAITABLE(ftdmchan);
|
||||
inflags[j] = chan_events;
|
||||
#else
|
||||
memset(&pfds[j], 0, sizeof(pfds[j]));
|
||||
@@ -1572,10 +1639,10 @@ static FIO_CHANNEL_DESTROY_FUNCTION(wanpipe_channel_destroy)
|
||||
{
|
||||
#ifdef LIBSANGOMA_VERSION
|
||||
if (ftdmchan->io_data) {
|
||||
sangoma_wait_obj_t *sangoma_wait_obj;
|
||||
sangoma_wait_obj = ftdmchan->io_data;
|
||||
ftdmchan->io_data = NULL;
|
||||
sangoma_wait_obj_t *sangoma_wait_obj = WP_GET_WAITABLE(ftdmchan);
|
||||
sangoma_wait_obj_delete(&sangoma_wait_obj);
|
||||
ftdm_safe_free(ftdmchan->io_data);
|
||||
ftdmchan->io_data = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1606,7 +1673,8 @@ static FIO_CHANNEL_DESTROY_FUNCTION(wanpipe_channel_destroy)
|
||||
*/
|
||||
static FIO_IO_LOAD_FUNCTION(wanpipe_init)
|
||||
{
|
||||
assert(fio != NULL);
|
||||
ftdm_assert(fio != NULL, "fio should not be null\n");
|
||||
|
||||
memset(&wanpipe_interface, 0, sizeof(wanpipe_interface));
|
||||
|
||||
wp_globals.codec_ms = 20;
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
* Moises Silva <moy@sangoma.com>
|
||||
* W McRoberts <fs@whmcr.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "private/ftdm_core.h"
|
||||
@@ -94,6 +100,7 @@ struct ioctl_codes {
|
||||
ioctlcmd ECHOTRAIN;
|
||||
ioctlcmd SETTXBITS;
|
||||
ioctlcmd GETRXBITS;
|
||||
ioctlcmd SETPOLARITY;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -169,7 +176,8 @@ static struct ioctl_codes dahdi_ioctl_codes = {
|
||||
.GETCONFMUTE = DAHDI_GETCONFMUTE,
|
||||
.ECHOTRAIN = DAHDI_ECHOTRAIN,
|
||||
.SETTXBITS = DAHDI_SETTXBITS,
|
||||
.GETRXBITS = DAHDI_GETRXBITS
|
||||
.GETRXBITS = DAHDI_GETRXBITS,
|
||||
.SETPOLARITY = DAHDI_SETPOLARITY
|
||||
};
|
||||
|
||||
#define ZT_INVALID_SOCKET -1
|
||||
@@ -248,7 +256,7 @@ static void zt_build_gains(struct zt_gains *g, float rxgain, float txgain, int c
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialises a range of ftdmtel channels
|
||||
* \brief Initialises a range of Zaptel/DAHDI channels
|
||||
* \param span FreeTDM span
|
||||
* \param start Initial wanpipe channel number
|
||||
* \param end Final wanpipe channel number
|
||||
@@ -341,7 +349,7 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f
|
||||
}
|
||||
|
||||
if (ioctl(CONTROL_FD, codes.CHANCONFIG, &cc)) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "this ioctl fails on older ftdmtel but is harmless if you used ztcfg\n[device %s chan %d fd %d (%s)]\n", chanpath, x, CONTROL_FD, strerror(errno));
|
||||
ftdm_log(FTDM_LOG_WARNING, "this ioctl fails in older zaptel but is harmless if you used ztcfg\n[device %s chan %d fd %d (%s)]\n", chanpath, x, CONTROL_FD, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,7 +453,7 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialises an freetdm ftdmtel span from a configuration string
|
||||
* \brief Initialises a freetdm Zaptel/DAHDI span from a configuration string
|
||||
* \param span FreeTDM span
|
||||
* \param str Configuration string
|
||||
* \param type FreeTDM span type
|
||||
@@ -515,7 +523,7 @@ static FIO_CONFIGURE_SPAN_FUNCTION(zt_configure_span)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Process configuration variable for a ftdmtel profile
|
||||
* \brief Process configuration variable for a Zaptel/DAHDI profile
|
||||
* \param category Wanpipe profile name
|
||||
* \param var Variable name
|
||||
* \param val Variable value
|
||||
@@ -593,7 +601,7 @@ static FIO_CONFIGURE_FUNCTION(zt_configure)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Opens a ftdmtel channel
|
||||
* \brief Opens a Zaptel/DAHDI channel
|
||||
* \param ftdmchan Channel to open
|
||||
* \return Success or failure
|
||||
*/
|
||||
@@ -663,7 +671,7 @@ static FIO_OPEN_FUNCTION(zt_open)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Closes ftdmtel channel
|
||||
* \brief Closes Zaptel/DAHDI channel
|
||||
* \param ftdmchan Channel to close
|
||||
* \return Success
|
||||
*/
|
||||
@@ -681,7 +689,7 @@ static FIO_CLOSE_FUNCTION(zt_close)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Executes an FreeTDM command on a ftdmtel channel
|
||||
* \brief Executes a FreeTDM command on a Zaptel/DAHDI channel
|
||||
* \param ftdmchan Channel to execute command on
|
||||
* \param command FreeTDM command to execute
|
||||
* \param obj Object (unused)
|
||||
@@ -826,6 +834,15 @@ static FIO_COMMAND_FUNCTION(zt_command)
|
||||
err = ioctl(ftdmchan->sockfd, codes.FLUSH, &flushmode);
|
||||
}
|
||||
break;
|
||||
case FTDM_COMMAND_SET_POLARITY:
|
||||
{
|
||||
ftdm_polarity_t polarity = FTDM_COMMAND_OBJ_INT;
|
||||
err = ioctl(ftdmchan->sockfd, codes.SETPOLARITY, polarity);
|
||||
if (!err) {
|
||||
ftdmchan->polarity = polarity;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_COMMAND_FLUSH_RX_BUFFERS:
|
||||
{
|
||||
int flushmode = ZT_FLUSH_READ;
|
||||
@@ -853,7 +870,7 @@ static FIO_COMMAND_FUNCTION(zt_command)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Gets alarms from a ftdmtel Channel
|
||||
* \brief Gets alarms from a Zaptel/DAHDI channel
|
||||
* \param ftdmchan Channel to get alarms from
|
||||
* \return Success or failure
|
||||
*/
|
||||
@@ -876,7 +893,7 @@ static FIO_GET_ALARMS_FUNCTION(zt_get_alarms)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Waits for an event on a ftdmtel channel
|
||||
* \brief Waits for an event on a Zaptel/DAHDI channel
|
||||
* \param ftdmchan Channel to open
|
||||
* \param flags Type of event to wait for
|
||||
* \param to Time to wait (in ms)
|
||||
@@ -950,7 +967,7 @@ pollagain:
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks for events on a ftdmtel span
|
||||
* \brief Checks for events on a Zaptel/DAHDI span
|
||||
* \param span Span to check for events
|
||||
* \param ms Time to wait for event
|
||||
* \return Success if event is waiting or failure if not
|
||||
@@ -1088,6 +1105,12 @@ static __inline__ ftdm_status_t zt_channel_process_event(ftdm_channel_t *fchan,
|
||||
*event_id = FTDM_OOB_NOOP; /* What else could we do? */
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_POLARITY:
|
||||
{
|
||||
ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "Got polarity reverse (ZT_EVENT_POLARITY)\n");
|
||||
*event_id = FTDM_OOB_POLARITY_REVERSE;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_NONE:
|
||||
{
|
||||
ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "No event\n");
|
||||
@@ -1141,7 +1164,7 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(zt_channel_next_event)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves an event from a ftdmtel span
|
||||
* \brief Retrieves an event from a Zaptel/DAHDI span
|
||||
* \param span Span to retrieve event from
|
||||
* \param event FreeTDM event to return
|
||||
* \return Success or failure
|
||||
@@ -1181,7 +1204,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads data from a ftdmtel channel
|
||||
* \brief Reads data from a Zaptel/DAHDI channel
|
||||
* \param ftdmchan Channel to read from
|
||||
* \param data Data buffer
|
||||
* \param datalen Size of data buffer
|
||||
@@ -1223,7 +1246,7 @@ static FIO_READ_FUNCTION(zt_read)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Writes data to a ftdmtel channel
|
||||
* \brief Writes data to a Zaptel/DAHDI channel
|
||||
* \param ftdmchan Channel to write to
|
||||
* \param data Data buffer
|
||||
* \param datalen Size of data buffer
|
||||
@@ -1262,7 +1285,7 @@ tryagain:
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Destroys a ftdmtel Channel
|
||||
* \brief Destroys a Zaptel/DAHDI Channel
|
||||
* \param ftdmchan Channel to destroy
|
||||
* \return Success
|
||||
*/
|
||||
@@ -1275,12 +1298,12 @@ static FIO_CHANNEL_DESTROY_FUNCTION(zt_channel_destroy)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Global FreeTDM IO interface for ftdmtel
|
||||
* \brief Global FreeTDM IO interface for Zaptel/DAHDI
|
||||
*/
|
||||
static ftdm_io_interface_t zt_interface;
|
||||
|
||||
/**
|
||||
* \brief Loads ftdmtel IO module
|
||||
* \brief Loads Zaptel/DAHDI IO module
|
||||
* \param fio FreeTDM IO interface
|
||||
* \return Success or failure
|
||||
*/
|
||||
@@ -1335,7 +1358,7 @@ static FIO_IO_LOAD_FUNCTION(zt_init)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Unloads ftdmtel IO module
|
||||
* \brief Unloads Zaptel/DAHDI IO module
|
||||
* \return Success
|
||||
*/
|
||||
static FIO_IO_UNLOAD_FUNCTION(zt_destroy)
|
||||
@@ -1346,7 +1369,7 @@ static FIO_IO_UNLOAD_FUNCTION(zt_destroy)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief FreeTDM ftdmtel IO module definition
|
||||
* \brief FreeTDM Zaptel/DAHDI IO module definition
|
||||
*/
|
||||
ftdm_module_t ftdm_module = {
|
||||
"zt",
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
* Moises Silva <moy@sangoma.com>
|
||||
* W McRoberts <fs@whmcr.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FTDM_ZT_H
|
||||
@@ -349,6 +355,7 @@ ZT_ABIT = 8
|
||||
#define DAHDI_SETTXBITS _IOW (DAHDI_CODE, 43, int)
|
||||
#define DAHDI_GETRXBITS _IOR (DAHDI_CODE, 43, int)
|
||||
|
||||
#define DAHDI_SETPOLARITY _IOW (DAHDI_CODE, 92, int) /* Polarity setting for FXO lines */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -928,20 +928,20 @@ typedef enum {
|
||||
/*! \brief IO statistics */
|
||||
typedef struct {
|
||||
struct {
|
||||
uint64_t packets;
|
||||
uint32_t errors;
|
||||
uint16_t flags;
|
||||
uint8_t queue_size; /*!< max queue size configured */
|
||||
uint8_t queue_len; /*!< Current number of elements in queue */
|
||||
uint64_t packets;
|
||||
} rx;
|
||||
|
||||
struct {
|
||||
uint64_t idle_packets;
|
||||
uint64_t packets;
|
||||
uint32_t errors;
|
||||
uint16_t flags;
|
||||
uint8_t idle_packets;
|
||||
uint8_t queue_size; /*!< max queue size configured */
|
||||
uint8_t queue_len; /*!< Current number of elements in queue */
|
||||
uint64_t packets;
|
||||
} tx;
|
||||
} ftdm_channel_iostats_t;
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mftilla Public License Version
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mftilla.org/MPL/
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
@@ -33,8 +33,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the freetdm library. Any use or distribution of this
|
||||
* source code outside the scope of the freetdm library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
|
||||
@@ -2,13 +2,60 @@
|
||||
* libteletone
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is tone_detect.c - General telephony tone detection, and specific detection of DTMF.
|
||||
*
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Stephen Underwood <steveu@coppice.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* The the original interface designed by Steve Underwood was preserved to retain
|
||||
*the optimizations when considering DTMF tones though the names were changed in the interest
|
||||
* of namespace.
|
||||
*
|
||||
* Much less efficient expansion interface was added to allow for the detection of
|
||||
* a single arbitrary tone combination which may also exceed 2 simultaneous tones.
|
||||
* (controlled by compile time constant TELETONE_MAX_TONES)
|
||||
*
|
||||
* Copyright (C) 2006 Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
*
|
||||
* libteletone_detect.c Tone Detection Code
|
||||
*
|
||||
*
|
||||
*********************************************************************************
|
||||
*
|
||||
* Derived from tone_detect.h - General telephony tone detection, and specific
|
||||
* detection of DTMF.
|
||||
*
|
||||
* Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Despite my general liking of the GPL, I place this code in the
|
||||
* public domain for the benefit of all mankind - even the slimy
|
||||
* ones who might try to proprietize my work and use it to my
|
||||
* detriment.
|
||||
*
|
||||
*
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the freetdm library. Any use or distribution of this
|
||||
* source code outside the scope of the freetdm library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
@@ -41,20 +88,6 @@
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*********************************************************************************
|
||||
*
|
||||
* Derived from tone_detect.h - General telephony tone detection, and specific
|
||||
* detection of DTMF.
|
||||
*
|
||||
* Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Despite my general liking of the GPL, I place this code in the
|
||||
* public domain for the benefit of all mankind - even the slimy
|
||||
* ones who might try to proprietize my work and use it to my
|
||||
* detriment.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBTELETONE_DETECT_H
|
||||
@@ -101,6 +134,14 @@ extern "C" {
|
||||
#define BLOCK_LEN 102
|
||||
#define M_TWO_PI 2.0*M_PI
|
||||
|
||||
typedef enum {
|
||||
TT_HIT_NONE = 0,
|
||||
TT_HIT_BEGIN = 1,
|
||||
TT_HIT_MIDDLE = 2,
|
||||
TT_HIT_END = 3
|
||||
} teletone_hit_type_t;
|
||||
|
||||
|
||||
/*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */
|
||||
typedef struct {
|
||||
float v2;
|
||||
@@ -114,16 +155,19 @@ extern "C" {
|
||||
int hit2;
|
||||
int hit3;
|
||||
int hit4;
|
||||
int mhit;
|
||||
int dur;
|
||||
int zc;
|
||||
|
||||
|
||||
teletone_goertzel_state_t row_out[GRID_FACTOR];
|
||||
teletone_goertzel_state_t col_out[GRID_FACTOR];
|
||||
teletone_goertzel_state_t row_out2nd[GRID_FACTOR];
|
||||
teletone_goertzel_state_t col_out2nd[GRID_FACTOR];
|
||||
float energy;
|
||||
float lenergy;
|
||||
|
||||
int current_sample;
|
||||
char digits[TELETONE_MAX_DTMF_DIGITS + 1];
|
||||
char digit;
|
||||
int current_digits;
|
||||
int detected_digits;
|
||||
int lost_digits;
|
||||
@@ -196,7 +240,7 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
|
||||
\param samples the number of samples present in sample_buffer
|
||||
\return true when DTMF was detected or false when it is not
|
||||
*/
|
||||
TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
int16_t sample_buffer[],
|
||||
int samples);
|
||||
/*!
|
||||
@@ -206,9 +250,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
\param max the maximum length of buf
|
||||
\return the number of characters written to buf
|
||||
*/
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
char *buf,
|
||||
int max);
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur);
|
||||
|
||||
/*!
|
||||
\brief Step through the Goertzel Algorithm for each sample in a buffer
|
||||
|
||||
@@ -2,6 +2,41 @@
|
||||
* libteletone
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is libteletone
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
*
|
||||
* libteletone.h -- Tone Generator
|
||||
*
|
||||
*
|
||||
*
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -2,14 +2,62 @@
|
||||
* libteletone
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is tone_detect.c - General telephony tone detection, and specific detection of DTMF.
|
||||
*
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Stephen Underwood <steveu@coppice.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* The the original interface designed by Steve Underwood was preserved to retain
|
||||
*the optimizations when considering DTMF tones though the names were changed in the interest
|
||||
* of namespace.
|
||||
*
|
||||
* Much less efficient expansion interface was added to allow for the detection of
|
||||
* a single arbitrary tone combination which may also exceed 2 simultaneous tones.
|
||||
* (controlled by compile time constant TELETONE_MAX_TONES)
|
||||
*
|
||||
* Copyright (C) 2006 Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
*
|
||||
* libteletone_detect.c Tone Detection Code
|
||||
*
|
||||
*
|
||||
*********************************************************************************
|
||||
*
|
||||
* Derived from tone_detect.c - General telephony tone detection, and specific
|
||||
* detection of DTMF.
|
||||
*
|
||||
* Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Despite my general liking of the GPL, I place this code in the
|
||||
* public domain for the benefit of all mankind - even the slimy
|
||||
* ones who might try to proprietize my work and use it to my
|
||||
* detriment.
|
||||
*
|
||||
*
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -40,21 +88,6 @@
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*********************************************************************************
|
||||
*
|
||||
* Derived from tone_detect.c - General telephony tone detection, and specific
|
||||
* detection of DTMF.
|
||||
*
|
||||
* Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Despite my general liking of the GPL, I place this code in the
|
||||
* public domain for the benefit of all mankind - even the slimy
|
||||
* ones who might try to proprietize my work and use it to my
|
||||
* detriment.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <libteletone_detect.h>
|
||||
@@ -67,7 +100,8 @@
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
#define LOW_ENG 10000000
|
||||
#define ZC 2
|
||||
static teletone_detection_descriptor_t dtmf_detect_row[GRID_FACTOR];
|
||||
static teletone_detection_descriptor_t dtmf_detect_col[GRID_FACTOR];
|
||||
static teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR];
|
||||
@@ -132,8 +166,8 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
dtmf_detect_state->detected_digits = 0;
|
||||
dtmf_detect_state->lost_digits = 0;
|
||||
dtmf_detect_state->digits[0] = '\0';
|
||||
dtmf_detect_state->mhit = 0;
|
||||
dtmf_detect_state->digit = 0;
|
||||
dtmf_detect_state->dur = 0;
|
||||
}
|
||||
|
||||
TELETONE_API(void) teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map)
|
||||
@@ -266,7 +300,7 @@ TELETONE_API(int) teletone_multi_tone_detect (teletone_multi_tone_t *mt,
|
||||
}
|
||||
|
||||
|
||||
TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
int16_t sample_buffer[],
|
||||
int samples)
|
||||
{
|
||||
@@ -281,6 +315,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
int best_col;
|
||||
char hit;
|
||||
int limit;
|
||||
teletone_hit_type_t r = 0;
|
||||
|
||||
hit = 0;
|
||||
for (sample = 0; sample < samples; sample = limit) {
|
||||
@@ -317,6 +352,32 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
|
||||
}
|
||||
|
||||
if (dtmf_detect_state->zc > 0) {
|
||||
if (dtmf_detect_state->energy < LOW_ENG && dtmf_detect_state->lenergy < LOW_ENG) {
|
||||
if (!--dtmf_detect_state->zc) {
|
||||
/* Reinitialise the detector for the next block */
|
||||
dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
|
||||
for (i = 0; i < GRID_FACTOR; i++) {
|
||||
goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
|
||||
goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
|
||||
}
|
||||
dtmf_detect_state->dur -= samples;
|
||||
return TT_HIT_END;
|
||||
}
|
||||
}
|
||||
|
||||
dtmf_detect_state->dur += samples;
|
||||
dtmf_detect_state->lenergy = dtmf_detect_state->energy;
|
||||
dtmf_detect_state->energy = 0.0;
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
return TT_HIT_MIDDLE;
|
||||
} else if (dtmf_detect_state->digit) {
|
||||
return TT_HIT_END;
|
||||
}
|
||||
|
||||
|
||||
dtmf_detect_state->current_sample += (limit - sample);
|
||||
if (dtmf_detect_state->current_sample < BLOCK_LEN) {
|
||||
continue;
|
||||
@@ -361,58 +422,55 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
back to back differing digits. More importantly, it
|
||||
can work with nasty phones that give a very wobbly start
|
||||
to a digit. */
|
||||
if (hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
|
||||
dtmf_detect_state->mhit = hit;
|
||||
if (! r && hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
|
||||
dtmf_detect_state->digit_hits[(best_row << 2) + best_col]++;
|
||||
dtmf_detect_state->detected_digits++;
|
||||
if (dtmf_detect_state->current_digits < TELETONE_MAX_DTMF_DIGITS) {
|
||||
dtmf_detect_state->digits[dtmf_detect_state->current_digits++] = hit;
|
||||
dtmf_detect_state->digits[dtmf_detect_state->current_digits] = '\0';
|
||||
dtmf_detect_state->digit = hit;
|
||||
} else {
|
||||
dtmf_detect_state->lost_digits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
dtmf_detect_state->lost_digits++;
|
||||
}
|
||||
|
||||
if (!dtmf_detect_state->zc) {
|
||||
dtmf_detect_state->zc = ZC;
|
||||
dtmf_detect_state->dur = 0;
|
||||
r = TT_HIT_BEGIN;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dtmf_detect_state->hit1 = dtmf_detect_state->hit2;
|
||||
dtmf_detect_state->hit2 = dtmf_detect_state->hit3;
|
||||
dtmf_detect_state->hit3 = hit;
|
||||
/* Reinitialise the detector for the next block */
|
||||
for (i = 0; i < GRID_FACTOR; i++) {
|
||||
goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
|
||||
goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
|
||||
}
|
||||
|
||||
dtmf_detect_state->energy = 0.0;
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
|
||||
}
|
||||
if ((!dtmf_detect_state->mhit) || (dtmf_detect_state->mhit != hit)) {
|
||||
dtmf_detect_state->mhit = 0;
|
||||
return(0);
|
||||
}
|
||||
return (hit);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
char *buf,
|
||||
int max)
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur)
|
||||
{
|
||||
teletone_assert(dtmf_detect_state->current_digits <= TELETONE_MAX_DTMF_DIGITS);
|
||||
if (!dtmf_detect_state->digit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max > dtmf_detect_state->current_digits) {
|
||||
max = dtmf_detect_state->current_digits;
|
||||
*buf = dtmf_detect_state->digit;
|
||||
|
||||
*dur = dtmf_detect_state->dur;
|
||||
|
||||
if (!dtmf_detect_state->zc) {
|
||||
dtmf_detect_state->dur = 0;
|
||||
dtmf_detect_state->digit = 0;
|
||||
}
|
||||
if (max > 0) {
|
||||
memcpy (buf, dtmf_detect_state->digits, max);
|
||||
memmove (dtmf_detect_state->digits, dtmf_detect_state->digits + max, dtmf_detect_state->current_digits - max);
|
||||
dtmf_detect_state->current_digits -= max;
|
||||
}
|
||||
buf[max] = '\0';
|
||||
return max;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
|
||||
@@ -1,5 +1,41 @@
|
||||
/*
|
||||
* libteletone_generate.c -- Tone Generator
|
||||
* libteletone
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is libteletone
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
*
|
||||
* libteletone.c -- Tone Generator
|
||||
*
|
||||
*
|
||||
*
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
@@ -34,7 +70,6 @@
|
||||
*/
|
||||
|
||||
#include <libteletone.h>
|
||||
#include "private/ftdm_core.h"
|
||||
|
||||
#define SMAX 32767
|
||||
#define SMIN -32768
|
||||
@@ -111,7 +146,7 @@ TELETONE_API(int) teletone_init_session(teletone_generation_session_t *ts, int b
|
||||
ts->decay_step = 0;
|
||||
ts->decay_factor = 1;
|
||||
if (buflen) {
|
||||
if ((ts->buffer = ftdm_calloc(buflen, sizeof(teletone_audio_t))) == 0) {
|
||||
if ((ts->buffer = calloc(buflen, sizeof(teletone_audio_t))) == 0) {
|
||||
return -1;
|
||||
}
|
||||
ts->datalen = buflen;
|
||||
@@ -142,7 +177,7 @@ TELETONE_API(int) teletone_init_session(teletone_generation_session_t *ts, int b
|
||||
TELETONE_API(int) teletone_destroy_session(teletone_generation_session_t *ts)
|
||||
{
|
||||
if (ts->buffer) {
|
||||
ftdm_safe_free(ts->buffer);
|
||||
free(ts->buffer);
|
||||
ts->buffer = NULL;
|
||||
ts->samples = 0;
|
||||
}
|
||||
@@ -270,6 +305,19 @@ TELETONE_API(int) teletone_mux_tones(teletone_generation_session_t *ts, teletone
|
||||
return ts->samples / ts->channels;
|
||||
}
|
||||
|
||||
/* don't ask */
|
||||
static char *my_strdup (const char *s)
|
||||
{
|
||||
size_t len = strlen (s) + 1;
|
||||
void *new = malloc (len);
|
||||
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (char *) memcpy (new, s, len);
|
||||
}
|
||||
|
||||
TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd)
|
||||
{
|
||||
char *data = NULL, *cur = NULL, *end = NULL;
|
||||
@@ -280,7 +328,7 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
|
||||
}
|
||||
|
||||
do {
|
||||
if (!(data = ftdm_strdup(cmd))) {
|
||||
if (!(data = my_strdup(cmd))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -363,6 +411,9 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
|
||||
*e++ = '\0';
|
||||
}
|
||||
do {
|
||||
if (!p) {
|
||||
break;
|
||||
}
|
||||
if ((next = strchr(p, ',')) != 0) {
|
||||
*next++ = '\0';
|
||||
}
|
||||
@@ -427,7 +478,7 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
|
||||
}
|
||||
}
|
||||
bottom:
|
||||
ftdm_safe_free(data);
|
||||
free(data);
|
||||
data = NULL;
|
||||
if (ts->LOOPS > 0) {
|
||||
ts->LOOPS--;
|
||||
|
||||
+185
-56
@@ -1,16 +1,25 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
|
||||
Software Foundation, Inc.
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. This file is offered as-is,
|
||||
without warranty of any kind.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package. Some packages provide this
|
||||
`INSTALL' file but do not implement all of the features documented
|
||||
below. The lack of an optional feature in a given package is not
|
||||
necessarily a bug. More recommendations for GNU packages can be found
|
||||
in *note Makefile Conventions: (standards)Makefile Conventions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
@@ -23,9 +32,9 @@ debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
the results of its tests to speed up reconfiguring. Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
@@ -35,30 +44,37 @@ some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
`./configure' to configure the package for your system.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
Running `configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
the package, generally using the just-built uninstalled binaries.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
documentation. When installing into a prefix owned by root, it is
|
||||
recommended that the package be configured and built as a regular
|
||||
user, and only the `make install' phase executed with root
|
||||
privileges.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
5. Optionally, type `make installcheck' to repeat any self-tests, but
|
||||
this time using the binaries in their final installed location.
|
||||
This target does not install anything. Running this target as a
|
||||
regular user, particularly if the prior `make install' required
|
||||
root privileges, verifies that the installation completed
|
||||
correctly.
|
||||
|
||||
6. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
@@ -67,45 +83,69 @@ The simplest way to compile this package is:
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
7. Often, you can also type `make uninstall' to remove the installed
|
||||
files again. In practice, not all packages have tested that
|
||||
uninstallation works correctly, even though it is required by the
|
||||
GNU Coding Standards.
|
||||
|
||||
8. Some packages, particularly those that use Automake, provide `make
|
||||
distcheck', which can by used by developers to test that all other
|
||||
targets like `make install' and `make uninstall' work correctly.
|
||||
This target is generally not run by end users.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
source code in the directory that `configure' is in and in `..'. This
|
||||
is known as a "VPATH" build.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
On MacOS X 10.5 and later systems, you can create libraries and
|
||||
executables that work on multiple system types--known as "fat" or
|
||||
"universal" binaries--by specifying multiple `-arch' options to the
|
||||
compiler but only a single `-arch' option to the preprocessor. Like
|
||||
this:
|
||||
|
||||
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CPP="gcc -E" CXXCPP="g++ -E"
|
||||
|
||||
This is not guaranteed to produce working output in all cases, you
|
||||
may have to build one architecture at a time and combine the results
|
||||
using the `lipo' tool if you have problems.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
`configure' the option `--prefix=PREFIX', where PREFIX must be an
|
||||
absolute file name.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
@@ -116,16 +156,47 @@ Documentation and other data files still use the regular prefix.
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
you can set and what kinds of files go in them. In general, the
|
||||
default for these options is expressed in terms of `${prefix}', so that
|
||||
specifying just `--prefix' will affect all of the other directory
|
||||
specifications that were not explicitly provided.
|
||||
|
||||
The most portable way to affect installation locations is to pass the
|
||||
correct locations to `configure'; however, many packages provide one or
|
||||
both of the following shortcuts of passing variable assignments to the
|
||||
`make install' command line to change installation locations without
|
||||
having to reconfigure or recompile.
|
||||
|
||||
The first method involves providing an override variable for each
|
||||
affected directory. For example, `make install
|
||||
prefix=/alternate/directory' will choose an alternate location for all
|
||||
directory configuration variables that were expressed in terms of
|
||||
`${prefix}'. Any directories that were specified during `configure',
|
||||
but not in terms of `${prefix}', must each be overridden at install
|
||||
time for the entire installation to be relocated. The approach of
|
||||
makefile variable overrides for each directory variable is required by
|
||||
the GNU Coding Standards, and ideally causes no recompilation.
|
||||
However, some platforms have known limitations with the semantics of
|
||||
shared libraries that end up requiring recompilation when using this
|
||||
method, particularly noticeable in packages that use GNU Libtool.
|
||||
|
||||
The second method involves providing the `DESTDIR' variable. For
|
||||
example, `make install DESTDIR=/alternate/directory' will prepend
|
||||
`/alternate/directory' before all installation names. The approach of
|
||||
`DESTDIR' overrides is not required by the GNU Coding Standards, and
|
||||
does not work on platforms that have drive letters. On the other hand,
|
||||
it does better at avoiding recompilation issues, and works well even
|
||||
when some directory options were not specified in terms of `${prefix}'
|
||||
at `configure' time.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
@@ -137,14 +208,53 @@ find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Some packages offer the ability to configure how verbose the
|
||||
execution of `make' will be. For these packages, running `./configure
|
||||
--enable-silent-rules' sets the default to minimal output, which can be
|
||||
overridden with `make V=1'; while running `./configure
|
||||
--disable-silent-rules' sets the default to verbose, which can be
|
||||
overridden with `make V=0'.
|
||||
|
||||
Particular systems
|
||||
==================
|
||||
|
||||
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
|
||||
CC is not installed, it is recommended to use the following options in
|
||||
order to use an ANSI C compiler:
|
||||
|
||||
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
|
||||
|
||||
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||
|
||||
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
|
||||
a workaround. If GNU CC is not installed, it is therefore recommended
|
||||
to try
|
||||
|
||||
./configure CC="cc"
|
||||
|
||||
and if that doesn't work, try
|
||||
|
||||
./configure CC="cc -nodtk"
|
||||
|
||||
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
|
||||
directory contains several dysfunctional programs; working variants of
|
||||
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
|
||||
in your `PATH', put it _after_ `/usr/bin'.
|
||||
|
||||
On Haiku, software installed for all users goes in `/boot/common',
|
||||
not `/usr/local'. It is recommended to use the following options:
|
||||
|
||||
./configure --prefix=/boot/common
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
@@ -152,7 +262,8 @@ type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
OS
|
||||
KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
@@ -170,9 +281,9 @@ eventually be run) with `--host=TYPE'.
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
@@ -181,7 +292,7 @@ A warning: not all `configure' scripts look for a site script.
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
@@ -190,21 +301,29 @@ them in the `configure' command line, using `VAR=value'. For example:
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script). Here is a another example:
|
||||
overridden in the site shell script).
|
||||
|
||||
/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
|
||||
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
|
||||
configuration-related scripts to be executed by `/bin/bash'.
|
||||
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
Print a summary of all of the options to `configure', and exit.
|
||||
|
||||
`--help=short'
|
||||
`--help=recursive'
|
||||
Print a summary of the options unique to this package's
|
||||
`configure', and exit. The `short' variant lists options used
|
||||
only in the top level, while the `recursive' variant lists options
|
||||
also present in any nested packages.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
@@ -231,6 +350,16 @@ configuration-related scripts to be executed by `/bin/bash'.
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--prefix=DIR'
|
||||
Use DIR as the installation prefix. *note Installation Names::
|
||||
for more details, including other options available for fine-tuning
|
||||
the installation locations.
|
||||
|
||||
`--no-create'
|
||||
`-n'
|
||||
Run the configure checks, but stop before creating any output
|
||||
files.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
|
||||
@@ -50,7 +50,10 @@ AC_SEARCH_LIBS(recv,socket)
|
||||
AC_CHECK_FUNCS(getopt_long)
|
||||
AC_CHECK_FUNCS(getaddrinfo)
|
||||
|
||||
AX_PATH_LIBGNUTLS(,AC_DEFINE(HAVE_GNUTLS,,"Use libgnutls"))
|
||||
#AX_PATH_LIBGNUTLS(,AC_DEFINE(HAVE_GNUTLS,,"Use libgnutls"))
|
||||
|
||||
m4_include([openssl.m4])
|
||||
SAC_OPENSSL
|
||||
|
||||
dnl Check -Wall flag of GCC
|
||||
if test "x$GCC" = "xyes"; then
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
dnl ======================================================================
|
||||
dnl SAC_OPENSSL
|
||||
dnl ======================================================================
|
||||
AC_DEFUN([SAC_OPENSSL], [
|
||||
|
||||
AC_ARG_WITH(openssl,
|
||||
[ --with-openssl use OpenSSL [[enabled]]],, with_openssl=pkg-config)
|
||||
|
||||
dnl SOSXXX:SAC_ASSERT_DEF([openssl libraries])
|
||||
|
||||
|
||||
if test "$with_openssl" = no ;then
|
||||
: # No openssl
|
||||
else
|
||||
|
||||
if test "$with_openssl" = "pkg-config" ; then
|
||||
PKG_CHECK_MODULES(openssl, openssl,
|
||||
[HAVE_TLS=1 HAVE_SSL=1 LIBS="$openssl_LIBS $LIBS"],
|
||||
[HAVE_SSL=0])
|
||||
fi
|
||||
|
||||
if test x$HAVE_SSL = x1 ; then
|
||||
AC_DEFINE([HAVE_LIBCRYPTO], 1, [Define to 1 if you have the `crypto' library (-lcrypto).])
|
||||
AC_DEFINE([HAVE_LIBSSL], 1, [Define to 1 if you have the `ssl' library (-lssl).])
|
||||
else
|
||||
AC_CHECK_HEADERS([openssl/tls1.h], [
|
||||
HAVE_SSL=1 HAVE_TLS=1
|
||||
|
||||
AC_CHECK_LIB(crypto, BIO_new,,
|
||||
HAVE_SSL=0
|
||||
AC_MSG_WARN(OpenSSL crypto library was not found))
|
||||
|
||||
AC_CHECK_LIB(ssl, TLSv1_method,,
|
||||
HAVE_TLS=0
|
||||
AC_MSG_WARN(OpenSSL protocol library was not found))
|
||||
],[AC_MSG_WARN(OpenSSL include files were not found)])
|
||||
fi
|
||||
|
||||
if test x$HAVE_SSL = x1; then
|
||||
AC_DEFINE([HAVE_SSL], 1, [Define to 1 if you have OpenSSL])
|
||||
fi
|
||||
|
||||
if test x$HAVE_TLS = x1; then
|
||||
AC_DEFINE([HAVE_TLS], 1, [Define to 1 if you have TLS])
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_TLS, test x$HAVE_TLS = x1)
|
||||
])
|
||||
@@ -19,6 +19,19 @@
|
||||
#include <gnutls/gnutls.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#ifdef WIN32
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#else
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#include <poll.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SF_FOREIGN 1
|
||||
#define SF_TRY_SECURE 2
|
||||
#define SF_SECURE 4
|
||||
@@ -41,9 +54,63 @@ struct stream_data {
|
||||
#ifdef HAVE_GNUTLS
|
||||
gnutls_session sess;
|
||||
gnutls_certificate_credentials cred;
|
||||
#elif HAVE_SSL
|
||||
SSL* ssl;
|
||||
SSL_CTX* ssl_ctx;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef WIN32
|
||||
static int sock_read_ready(struct stream_data *data, uint32_t ms)
|
||||
{
|
||||
int r = 0;
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4127 )
|
||||
FD_SET(SSL_get_fd(data->ssl), &fds);
|
||||
#pragma warning( pop )
|
||||
#else
|
||||
FD_SET(SSL_get_fd(data->ssl), &fds);
|
||||
#endif
|
||||
|
||||
tv.tv_sec = ms / 1000;
|
||||
tv.tv_usec = (ms % 1000) * ms;
|
||||
|
||||
r = select (SSL_get_fd(data->ssl) + 1, &fds, NULL, NULL, &tv);
|
||||
|
||||
return r;
|
||||
}
|
||||
#else
|
||||
static int sock_read_ready(struct stream_data *data, int ms)
|
||||
{
|
||||
struct pollfd pfds[2] = { { 0 } };
|
||||
int s = 0, r = 0;
|
||||
|
||||
pfds[0].fd = SSL_get_fd(data->ssl);
|
||||
pfds[0].events |= POLLIN;
|
||||
|
||||
s = poll(pfds, 1, ms);
|
||||
|
||||
|
||||
if (s < 0) {
|
||||
r = s;
|
||||
} else if (s > 0) {
|
||||
if ((pfds[0].revents & POLLIN)) {
|
||||
r = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
#ifndef WIN32
|
||||
#include <gcrypt.h>
|
||||
@@ -120,6 +187,86 @@ handshake (struct stream_data *data)
|
||||
iks_send_header (data->prs, data->server);
|
||||
|
||||
return IKS_OK;
|
||||
} // HAVE_GNUTLS
|
||||
#elif HAVE_SSL
|
||||
static int wait_for_data(struct stream_data *data, int ret, int timeout)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
int err;
|
||||
int retval = IKS_OK;
|
||||
|
||||
err = SSL_get_error(data->ssl, ret);
|
||||
|
||||
switch(err)
|
||||
{
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
ret = sock_read_ready(data, timeout*1000);
|
||||
|
||||
if (ret == -1) {
|
||||
retval = IKS_NET_TLSFAIL;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
if(data->logHook)
|
||||
data->logHook(data->user_data, ERR_error_string(err, NULL), strlen(ERR_error_string(err, NULL)), 1);
|
||||
retval = IKS_NET_TLSFAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
handshake (struct stream_data *data)
|
||||
{
|
||||
int ret;
|
||||
int finished;
|
||||
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
|
||||
data->ssl_ctx = SSL_CTX_new(TLSv1_method());
|
||||
if(!data->ssl_ctx) return IKS_NOMEM;
|
||||
|
||||
data->ssl = SSL_new(data->ssl_ctx);
|
||||
if(!data->ssl) return IKS_NOMEM;
|
||||
|
||||
if( SSL_set_fd(data->ssl, (int)data->sock) != 1 ) return IKS_NOMEM;
|
||||
|
||||
/* Set both the read and write BIO's to non-blocking mode */
|
||||
BIO_set_nbio(SSL_get_rbio(data->ssl), 1);
|
||||
BIO_set_nbio(SSL_get_wbio(data->ssl), 1);
|
||||
|
||||
finished = 0;
|
||||
|
||||
do
|
||||
{
|
||||
ret = SSL_connect(data->ssl);
|
||||
|
||||
if( ret != 1 )
|
||||
{
|
||||
if( wait_for_data(data, ret, 1) != IKS_OK )
|
||||
{
|
||||
finished = 1;
|
||||
SSL_free(data->ssl);
|
||||
}
|
||||
}
|
||||
} while( ret != 1 && finished != 1 );
|
||||
|
||||
if( ret == 1 )
|
||||
{
|
||||
data->flags &= (~SF_TRY_SECURE);
|
||||
data->flags |= SF_SECURE;
|
||||
|
||||
iks_send_header (data->prs, data->server);
|
||||
}
|
||||
|
||||
return ret == 1 ? IKS_OK : IKS_NET_TLSFAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -295,6 +442,15 @@ tagHook (struct stream_data *data, char *name, char **atts, int type)
|
||||
return IKS_NET_TLSFAIL;
|
||||
}
|
||||
}
|
||||
#elif HAVE_SSL
|
||||
if (data->flags & SF_TRY_SECURE) {
|
||||
if (strcmp (name, "proceed") == 0) {
|
||||
err = handshake (data);
|
||||
return err;
|
||||
} else if (strcmp (name, "failure") == 0){
|
||||
return IKS_NET_TLSFAIL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (data->current) {
|
||||
x = iks_insert (data->current, name);
|
||||
@@ -351,6 +507,11 @@ deleteHook (struct stream_data *data)
|
||||
gnutls_deinit (data->sess);
|
||||
gnutls_certificate_free_credentials (data->cred);
|
||||
}
|
||||
#elif HAVE_SSL
|
||||
if (data->flags & SF_SECURE) {
|
||||
if( SSL_shutdown(data->ssl) == 0 ) SSL_shutdown(data->ssl);
|
||||
SSL_free(data->ssl);
|
||||
}
|
||||
#endif
|
||||
if (data->trans) data->trans->close (data->sock);
|
||||
data->trans = NULL;
|
||||
@@ -507,6 +668,12 @@ iks_recv (iksparser *prs, int timeout)
|
||||
{
|
||||
struct stream_data *data = iks_user_data (prs);
|
||||
int len, ret;
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
int err;
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
#ifdef HAVE_GNUTLS
|
||||
@@ -514,6 +681,34 @@ iks_recv (iksparser *prs, int timeout)
|
||||
len = gnutls_record_recv (data->sess, data->buf, NET_IO_BUF_SIZE - 1);
|
||||
if (len == 0) len = -1;
|
||||
} else
|
||||
#elif HAVE_SSL
|
||||
if (data->flags & SF_SECURE) {
|
||||
ret = sock_read_ready(data, timeout*1000);
|
||||
|
||||
if (ret == -1) {
|
||||
return IKS_NET_TLSFAIL;
|
||||
} else if( ret == 0 ) {
|
||||
return IKS_OK;
|
||||
} else {
|
||||
len = SSL_read(data->ssl, data->buf, NET_IO_BUF_SIZE - 1);
|
||||
}
|
||||
|
||||
if( len <= 0 )
|
||||
{
|
||||
switch( err = SSL_get_error(data->ssl, len) )
|
||||
{
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
return IKS_OK;
|
||||
break;
|
||||
default:
|
||||
if(data->logHook)
|
||||
data->logHook(data->user_data, ERR_error_string(err, NULL), strlen(ERR_error_string(err, NULL)), 1);
|
||||
return IKS_NET_TLSFAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
len = data->trans->recv (data->sock, data->buf, NET_IO_BUF_SIZE - 1, timeout);
|
||||
@@ -523,6 +718,7 @@ iks_recv (iksparser *prs, int timeout)
|
||||
data->buf[len] = '\0';
|
||||
if (data->logHook) data->logHook (data->user_data, data->buf, len, 1);
|
||||
ret = iks_parse (prs, data->buf, len, 0);
|
||||
|
||||
if (ret != IKS_OK) return ret;
|
||||
if (!data->trans) {
|
||||
/* stream hook called iks_disconnect */
|
||||
@@ -569,6 +765,10 @@ iks_send_raw (iksparser *prs, const char *xmlstr)
|
||||
if (data->flags & SF_SECURE) {
|
||||
if (gnutls_record_send (data->sess, xmlstr, strlen (xmlstr)) < 0) return IKS_NET_RWERR;
|
||||
} else
|
||||
#elif HAVE_SSL
|
||||
if (data->flags & SF_SECURE) {
|
||||
if (SSL_write(data->ssl, xmlstr, strlen (xmlstr)) < 0) return IKS_NET_RWERR;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ret = data->trans->send (data->sock, xmlstr, strlen (xmlstr));
|
||||
@@ -591,6 +791,8 @@ iks_has_tls (void)
|
||||
{
|
||||
#ifdef HAVE_GNUTLS
|
||||
return 1;
|
||||
#elif HAVE_SSL
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
@@ -602,6 +804,10 @@ iks_is_secure (iksparser *prs)
|
||||
#ifdef HAVE_GNUTLS
|
||||
struct stream_data *data = iks_user_data (prs);
|
||||
|
||||
return data->flags & SF_SECURE;
|
||||
#elif HAVE_SSL
|
||||
struct stream_data *data = iks_user_data (prs);
|
||||
|
||||
return data->flags & SF_SECURE;
|
||||
#else
|
||||
return 0;
|
||||
@@ -641,6 +847,14 @@ iks_start_tls (iksparser *prs)
|
||||
int ret;
|
||||
struct stream_data *data = iks_user_data (prs);
|
||||
|
||||
ret = iks_send_raw (prs, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
|
||||
if (ret) return ret;
|
||||
data->flags |= SF_TRY_SECURE;
|
||||
return IKS_OK;
|
||||
#elif HAVE_SSL
|
||||
int ret;
|
||||
struct stream_data *data = iks_user_data (prs);
|
||||
|
||||
ret = iks_send_raw (prs, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
|
||||
if (ret) return ret;
|
||||
data->flags |= SF_TRY_SECURE;
|
||||
|
||||
Vendored
-1407
File diff suppressed because it is too large
Load Diff
Vendored
-1504
File diff suppressed because it is too large
Load Diff
Vendored
-17354
File diff suppressed because it is too large
Load Diff
Vendored
+1
-6
@@ -673,12 +673,7 @@ CFLAGS
|
||||
LDFLAGS
|
||||
LIBS
|
||||
CPPFLAGS
|
||||
CPP
|
||||
CPPFLAGS
|
||||
CC
|
||||
LDFLAGS
|
||||
LIBS
|
||||
CPPFLAGS'
|
||||
CPP'
|
||||
|
||||
|
||||
# Initialize some variables set by options.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2010-02-06.18; # UTC
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
@@ -200,11 +200,7 @@ if test $# -eq 0; then
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
|
||||
@@ -467,4 +467,10 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
#ifndef HAVE_STRTOUL
|
||||
#define strtoul (unsigned long)strtol
|
||||
#endif
|
||||
#ifdef HAVE_B64_PTON
|
||||
#define ldns_b64_pton b64_pton
|
||||
#endif
|
||||
#ifdef HAVE_B64_NTOP
|
||||
#define ldns_b64_ntop b64_ntop
|
||||
#endif
|
||||
|
||||
|
||||
-9687
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
AM_CFLAGS = -Isrc -Wall -lm
|
||||
AUTOMAKE_OPTS = gnu
|
||||
AUTOMAKE_OPTIONS = gnu
|
||||
NAME = libcodec2
|
||||
AM_CPPFLAGS = $(AM_CFLAGS)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
AM_CFLAGS = -I../src -Wall -DFLOATING_POINT -DVAR_ARRAYS
|
||||
AUTOMAKE_OPTS = gnu
|
||||
AUTOMAKE_OPTIONS = gnu
|
||||
NAME = libcodec2
|
||||
AM_CPPFLAGS = $(AM_CFLAGS)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
AM_CFLAGS = -I../src -g -DFLOATING_POINT -DVAR_ARRAYS
|
||||
AUTOMAKE_OPTS = gnu
|
||||
AUTOMAKE_OPTIONS = gnu
|
||||
NAME = libcodec2
|
||||
AM_CPPFLAGS = $(AM_CFLAGS)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
EXTRA_DIST =
|
||||
SUBDIRS =
|
||||
AUTOMAKE_OPTS=foreign
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
NAME=dingaling
|
||||
PREFIX=$(prefix)
|
||||
TOUCH_TARGET=@if test -f "$@" ; then touch "$@" ; fi ;
|
||||
|
||||
@@ -606,7 +606,7 @@ static int on_disco_default(void *user_data, ikspak *pak)
|
||||
if ((iq = iks_new("iq"))) {
|
||||
int all = 0;
|
||||
|
||||
iks_insert_attrib(iq, "from", handle->login);
|
||||
iks_insert_attrib(iq, "from", iks_find_attrib(pak->x, "to"));
|
||||
if (pak->from) {
|
||||
iks_insert_attrib(iq, "to", pak->from->full);
|
||||
}
|
||||
@@ -1431,12 +1431,14 @@ static void j_setup_filter(ldl_handle_t *handle)
|
||||
}
|
||||
}
|
||||
|
||||
static void ldl_flush_queue(ldl_handle_t *handle, int done)
|
||||
static ldl_queue_t ldl_flush_queue(ldl_handle_t *handle, int done)
|
||||
{
|
||||
iks *msg;
|
||||
void *pop = NULL;
|
||||
unsigned int len = 0, x = 0;
|
||||
|
||||
ldl_queue_t sent_data = LDL_QUEUE_NONE;
|
||||
|
||||
apr_thread_mutex_lock(handle->lock);
|
||||
|
||||
while(apr_queue_trypop(handle->queue, &pop) == APR_SUCCESS) {
|
||||
@@ -1445,6 +1447,7 @@ static void ldl_flush_queue(ldl_handle_t *handle, int done)
|
||||
if (!done) iks_send(handle->parser, msg);
|
||||
iks_delete(msg);
|
||||
pop = NULL;
|
||||
sent_data = LDL_QUEUE_SENT;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -1473,6 +1476,7 @@ static void ldl_flush_queue(ldl_handle_t *handle, int done)
|
||||
}
|
||||
iks_send(handle->parser, packet_node->xml);
|
||||
packet_node->next = now + 5000000;
|
||||
sent_data = LDL_QUEUE_SENT;
|
||||
}
|
||||
}
|
||||
if (packet_node->retries == 0 || done) {
|
||||
@@ -1490,51 +1494,15 @@ static void ldl_flush_queue(ldl_handle_t *handle, int done)
|
||||
}
|
||||
}
|
||||
apr_thread_mutex_unlock(handle->lock);
|
||||
}
|
||||
|
||||
|
||||
static void *APR_THREAD_FUNC queue_thread(apr_thread_t *thread, void *obj)
|
||||
{
|
||||
ldl_handle_t *handle = (ldl_handle_t *) obj;
|
||||
|
||||
ldl_set_flag_locked(handle, LDL_FLAG_QUEUE_RUNNING);
|
||||
|
||||
while (ldl_test_flag(handle, LDL_FLAG_RUNNING) && !ldl_test_flag(handle, LDL_FLAG_QUEUE_STOP)) {
|
||||
ldl_flush_queue(handle, 0);
|
||||
|
||||
if (handle->loop_callback(handle) != LDL_STATUS_SUCCESS || !ldl_test_flag((&globals), LDL_FLAG_READY)) {
|
||||
int fd;
|
||||
|
||||
if ((fd = iks_fd(handle->parser)) > -1) {
|
||||
shutdown(fd, 0x02);
|
||||
}
|
||||
ldl_set_flag_locked(handle, LDL_FLAG_BREAK);
|
||||
break;
|
||||
}
|
||||
microsleep(100);
|
||||
}
|
||||
|
||||
ldl_clear_flag_locked(handle, LDL_FLAG_QUEUE_RUNNING);
|
||||
ldl_clear_flag_locked(handle, LDL_FLAG_QUEUE_STOP);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void launch_queue_thread(ldl_handle_t *handle)
|
||||
{
|
||||
apr_thread_t *thread;
|
||||
apr_threadattr_t *thd_attr;;
|
||||
apr_threadattr_create(&thd_attr, handle->pool);
|
||||
apr_threadattr_detach_set(thd_attr, 1);
|
||||
|
||||
apr_threadattr_stacksize_set(thd_attr, 512 * 1024);
|
||||
apr_thread_create(&thread, thd_attr, queue_thread, handle, handle->pool);
|
||||
|
||||
return sent_data;
|
||||
}
|
||||
|
||||
|
||||
static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
|
||||
{
|
||||
int timeout_ka = LDL_KEEPALIVE_TIMEOUT;
|
||||
int count_ka = timeout_ka;
|
||||
|
||||
while (ldl_test_flag((&globals), LDL_FLAG_READY) && ldl_test_flag(handle, LDL_FLAG_RUNNING)) {
|
||||
int e;
|
||||
char tmp[512], *sl;
|
||||
@@ -1587,13 +1555,18 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
|
||||
}
|
||||
|
||||
handle->counter = opt_timeout;
|
||||
if (ldl_test_flag(handle, LDL_FLAG_TLS)) {
|
||||
launch_queue_thread(handle);
|
||||
}
|
||||
|
||||
while (ldl_test_flag((&globals), LDL_FLAG_READY) && ldl_test_flag(handle, LDL_FLAG_RUNNING)) {
|
||||
e = iks_recv(handle->parser, 1);
|
||||
if (!ldl_test_flag(handle, LDL_FLAG_TLS) && handle->loop_callback) {
|
||||
|
||||
if (count_ka-- <= 0) {
|
||||
if( iks_send_raw(handle->parser, " ") == IKS_OK) {
|
||||
count_ka = timeout_ka;
|
||||
globals.logger(DL_LOG_DEBUG, "Sent keep alive signal\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (handle->loop_callback) {
|
||||
if (handle->loop_callback(handle) != LDL_STATUS_SUCCESS) {
|
||||
ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING);
|
||||
break;
|
||||
@@ -1614,10 +1587,11 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!ldl_test_flag(handle, LDL_FLAG_TLS) && ldl_test_flag(handle, LDL_FLAG_RUNNING)) {
|
||||
if (ldl_test_flag(handle, LDL_FLAG_RUNNING)) {
|
||||
ldl_flush_queue(handle, 0);
|
||||
}
|
||||
|
||||
handle->counter--;
|
||||
if (!ldl_test_flag(handle, LDL_FLAG_CONNECTED)) {
|
||||
if (IKS_NET_TLSFAIL == e) {
|
||||
globals.logger(DL_LOG_DEBUG, "tls handshake failed\n");
|
||||
@@ -1631,11 +1605,12 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
microsleep(100);
|
||||
}
|
||||
|
||||
fail:
|
||||
|
||||
ldl_set_flag_locked(handle, LDL_FLAG_QUEUE_STOP);
|
||||
ldl_clear_flag_locked(handle, LDL_FLAG_CONNECTED);
|
||||
ldl_clear_flag_locked(handle, LDL_FLAG_AUTHORIZED);
|
||||
ldl_clear_flag_locked(handle, LDL_FLAG_BREAK);
|
||||
@@ -1645,23 +1620,12 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
|
||||
shutdown(fd, 0x02);
|
||||
}
|
||||
|
||||
|
||||
|
||||
while(ldl_test_flag(handle, LDL_FLAG_QUEUE_RUNNING)) {
|
||||
microsleep(100);
|
||||
}
|
||||
|
||||
iks_disconnect(handle->parser);
|
||||
iks_parser_delete(handle->parser);
|
||||
}
|
||||
ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING);
|
||||
if (!ldl_test_flag(handle, LDL_FLAG_TLS)) {
|
||||
ldl_flush_queue(handle, 1);
|
||||
}
|
||||
|
||||
while(ldl_test_flag(handle, LDL_FLAG_QUEUE_RUNNING)) {
|
||||
microsleep(100);
|
||||
}
|
||||
ldl_flush_queue(handle, 1);
|
||||
|
||||
ldl_set_flag_locked(handle, LDL_FLAG_STOPPED);
|
||||
|
||||
@@ -2512,13 +2476,15 @@ int ldl_handle_authorized(ldl_handle_t *handle)
|
||||
void ldl_handle_stop(ldl_handle_t *handle)
|
||||
{
|
||||
ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING);
|
||||
#if 0
|
||||
if (ldl_test_flag(handle, LDL_FLAG_TLS)) {
|
||||
int fd;
|
||||
if ((fd = iks_fd(handle->parser)) > -1) {
|
||||
shutdown(fd, 0x02);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
while(!ldl_test_flag(handle, LDL_FLAG_STOPPED)) {
|
||||
microsleep(100);
|
||||
}
|
||||
|
||||
@@ -64,6 +64,8 @@ extern "C" {
|
||||
#define LDL_MAX_PAYLOADS 50
|
||||
#define LDL_RETRY 3
|
||||
#define IKS_NS_COMPONENT "jabber:component:accept"
|
||||
/* period between keep alive signals in 0.1sec units*/
|
||||
#define LDL_KEEPALIVE_TIMEOUT 6000
|
||||
|
||||
/*! \brief A structure to store a jingle candidate */
|
||||
struct ldl_candidate {
|
||||
@@ -119,10 +121,8 @@ typedef enum {
|
||||
LDL_FLAG_AUTHORIZED = (1 << 2),
|
||||
LDL_FLAG_READY = (1 << 3),
|
||||
LDL_FLAG_CONNECTED = (1 << 4),
|
||||
LDL_FLAG_QUEUE_RUNNING = (1 << 5),
|
||||
LDL_FLAG_STOPPED = (1 << 6),
|
||||
LDL_FLAG_QUEUE_STOP = (1 << 7),
|
||||
LDL_FLAG_BREAK = (1 << 8)
|
||||
LDL_FLAG_STOPPED = (1 << 5),
|
||||
LDL_FLAG_BREAK = (1 << 6)
|
||||
} ldl_flag_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -173,6 +173,11 @@ typedef enum {
|
||||
LDL_DESCRIPTION_ACCEPT
|
||||
} ldl_description_t;
|
||||
|
||||
typedef enum {
|
||||
LDL_QUEUE_NONE,
|
||||
LDL_QUEUE_SENT
|
||||
} ldl_queue_t;
|
||||
|
||||
#define DL_PRE __FILE__, __LDL_FUNC__, __LINE__
|
||||
#define DL_LOG_DEBUG DL_PRE, 7
|
||||
#define DL_LOG_INFO DL_PRE, 6
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
EXTRA_DIST =
|
||||
SUBDIRS =
|
||||
AUTOMAKE_OPTS= gnu
|
||||
AUTOMAKE_OPTIONS = gnu
|
||||
NAME=teletone
|
||||
|
||||
AM_CFLAGS = $(new_AM_CFLAGS) -I./src
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the openzap library. Any use or distribution of this
|
||||
* source code outside the scope of the openzap library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the openzap library. Any use or distribution of this
|
||||
* source code outside the scope of the openzap library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
@@ -100,7 +100,8 @@
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
#define LOW_ENG 10000000
|
||||
#define ZC 2
|
||||
static teletone_detection_descriptor_t dtmf_detect_row[GRID_FACTOR];
|
||||
static teletone_detection_descriptor_t dtmf_detect_col[GRID_FACTOR];
|
||||
static teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR];
|
||||
@@ -165,8 +166,8 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
dtmf_detect_state->detected_digits = 0;
|
||||
dtmf_detect_state->lost_digits = 0;
|
||||
dtmf_detect_state->digits[0] = '\0';
|
||||
dtmf_detect_state->mhit = 0;
|
||||
dtmf_detect_state->digit = 0;
|
||||
dtmf_detect_state->dur = 0;
|
||||
}
|
||||
|
||||
TELETONE_API(void) teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map)
|
||||
@@ -299,7 +300,7 @@ TELETONE_API(int) teletone_multi_tone_detect (teletone_multi_tone_t *mt,
|
||||
}
|
||||
|
||||
|
||||
TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
int16_t sample_buffer[],
|
||||
int samples)
|
||||
{
|
||||
@@ -314,6 +315,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
int best_col;
|
||||
char hit;
|
||||
int limit;
|
||||
teletone_hit_type_t r = 0;
|
||||
|
||||
hit = 0;
|
||||
for (sample = 0; sample < samples; sample = limit) {
|
||||
@@ -350,6 +352,32 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
|
||||
}
|
||||
|
||||
if (dtmf_detect_state->zc > 0) {
|
||||
if (dtmf_detect_state->energy < LOW_ENG && dtmf_detect_state->lenergy < LOW_ENG) {
|
||||
if (!--dtmf_detect_state->zc) {
|
||||
/* Reinitialise the detector for the next block */
|
||||
dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
|
||||
for (i = 0; i < GRID_FACTOR; i++) {
|
||||
goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
|
||||
goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
|
||||
}
|
||||
dtmf_detect_state->dur -= samples;
|
||||
return TT_HIT_END;
|
||||
}
|
||||
}
|
||||
|
||||
dtmf_detect_state->dur += samples;
|
||||
dtmf_detect_state->lenergy = dtmf_detect_state->energy;
|
||||
dtmf_detect_state->energy = 0.0;
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
return TT_HIT_MIDDLE;
|
||||
} else if (dtmf_detect_state->digit) {
|
||||
return TT_HIT_END;
|
||||
}
|
||||
|
||||
|
||||
dtmf_detect_state->current_sample += (limit - sample);
|
||||
if (dtmf_detect_state->current_sample < BLOCK_LEN) {
|
||||
continue;
|
||||
@@ -394,58 +422,55 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
back to back differing digits. More importantly, it
|
||||
can work with nasty phones that give a very wobbly start
|
||||
to a digit. */
|
||||
if (hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
|
||||
dtmf_detect_state->mhit = hit;
|
||||
if (! r && hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
|
||||
dtmf_detect_state->digit_hits[(best_row << 2) + best_col]++;
|
||||
dtmf_detect_state->detected_digits++;
|
||||
if (dtmf_detect_state->current_digits < TELETONE_MAX_DTMF_DIGITS) {
|
||||
dtmf_detect_state->digits[dtmf_detect_state->current_digits++] = hit;
|
||||
dtmf_detect_state->digits[dtmf_detect_state->current_digits] = '\0';
|
||||
dtmf_detect_state->digit = hit;
|
||||
} else {
|
||||
dtmf_detect_state->lost_digits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
dtmf_detect_state->lost_digits++;
|
||||
}
|
||||
|
||||
if (!dtmf_detect_state->zc) {
|
||||
dtmf_detect_state->zc = ZC;
|
||||
dtmf_detect_state->dur = 0;
|
||||
r = TT_HIT_BEGIN;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dtmf_detect_state->hit1 = dtmf_detect_state->hit2;
|
||||
dtmf_detect_state->hit2 = dtmf_detect_state->hit3;
|
||||
dtmf_detect_state->hit3 = hit;
|
||||
/* Reinitialise the detector for the next block */
|
||||
for (i = 0; i < GRID_FACTOR; i++) {
|
||||
goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
|
||||
goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
|
||||
}
|
||||
|
||||
dtmf_detect_state->energy = 0.0;
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
|
||||
}
|
||||
if ((!dtmf_detect_state->mhit) || (dtmf_detect_state->mhit != hit)) {
|
||||
dtmf_detect_state->mhit = 0;
|
||||
return(0);
|
||||
}
|
||||
return (hit);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
char *buf,
|
||||
int max)
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur)
|
||||
{
|
||||
teletone_assert(dtmf_detect_state->current_digits <= TELETONE_MAX_DTMF_DIGITS);
|
||||
if (!dtmf_detect_state->digit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max > dtmf_detect_state->current_digits) {
|
||||
max = dtmf_detect_state->current_digits;
|
||||
*buf = dtmf_detect_state->digit;
|
||||
|
||||
*dur = dtmf_detect_state->dur;
|
||||
|
||||
if (!dtmf_detect_state->zc) {
|
||||
dtmf_detect_state->dur = 0;
|
||||
dtmf_detect_state->digit = 0;
|
||||
}
|
||||
if (max > 0) {
|
||||
memcpy (buf, dtmf_detect_state->digits, max);
|
||||
memmove (dtmf_detect_state->digits, dtmf_detect_state->digits + max, dtmf_detect_state->current_digits - max);
|
||||
dtmf_detect_state->current_digits -= max;
|
||||
}
|
||||
buf[max] = '\0';
|
||||
return max;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the openzap library. Any use or distribution of this
|
||||
* source code outside the scope of the openzap library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
@@ -134,6 +134,14 @@ extern "C" {
|
||||
#define BLOCK_LEN 102
|
||||
#define M_TWO_PI 2.0*M_PI
|
||||
|
||||
typedef enum {
|
||||
TT_HIT_NONE = 0,
|
||||
TT_HIT_BEGIN = 1,
|
||||
TT_HIT_MIDDLE = 2,
|
||||
TT_HIT_END = 3
|
||||
} teletone_hit_type_t;
|
||||
|
||||
|
||||
/*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */
|
||||
typedef struct {
|
||||
float v2;
|
||||
@@ -147,16 +155,19 @@ extern "C" {
|
||||
int hit2;
|
||||
int hit3;
|
||||
int hit4;
|
||||
int mhit;
|
||||
int dur;
|
||||
int zc;
|
||||
|
||||
|
||||
teletone_goertzel_state_t row_out[GRID_FACTOR];
|
||||
teletone_goertzel_state_t col_out[GRID_FACTOR];
|
||||
teletone_goertzel_state_t row_out2nd[GRID_FACTOR];
|
||||
teletone_goertzel_state_t col_out2nd[GRID_FACTOR];
|
||||
float energy;
|
||||
float lenergy;
|
||||
|
||||
int current_sample;
|
||||
char digits[TELETONE_MAX_DTMF_DIGITS + 1];
|
||||
char digit;
|
||||
int current_digits;
|
||||
int detected_digits;
|
||||
int lost_digits;
|
||||
@@ -229,7 +240,7 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
|
||||
\param samples the number of samples present in sample_buffer
|
||||
\return true when DTMF was detected or false when it is not
|
||||
*/
|
||||
TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
int16_t sample_buffer[],
|
||||
int samples);
|
||||
/*!
|
||||
@@ -239,9 +250,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
\param max the maximum length of buf
|
||||
\return the number of characters written to buf
|
||||
*/
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
char *buf,
|
||||
int max);
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur);
|
||||
|
||||
/*!
|
||||
\brief Step through the Goertzel Algorithm for each sample in a buffer
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the openzap library. Any use or distribution of this
|
||||
* source code outside the scope of the openzap library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the openzap library. Any use or distribution of this
|
||||
* source code outside the scope of the openzap library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
|
||||
@@ -107,7 +107,10 @@ case "$host" in
|
||||
;;
|
||||
esac
|
||||
|
||||
DEFAULT_INCLUDES="-I. -I./src/include -I$(srcdir)"
|
||||
|
||||
AC_SUBST(SOLINK)
|
||||
AC_SUBST(DEFAULT_INCLUDES)
|
||||
AC_SUBST(DYNAMIC_LIB_EXTEN)
|
||||
|
||||
AC_CHECK_LIB([dl], [dlopen])
|
||||
|
||||
@@ -155,12 +155,12 @@ for (;;)
|
||||
if (top <= bot) return -1;
|
||||
mid = (bot + top) >> 1;
|
||||
if (c == (ucp_table[mid].f0 & f0_charmask)) break;
|
||||
if (c < (ucp_table[mid].f0 & f0_charmask)) top = mid;
|
||||
if (c < (int)(ucp_table[mid].f0 & f0_charmask)) top = mid;
|
||||
else
|
||||
{
|
||||
if ((ucp_table[mid].f0 & f0_rangeflag) != 0 &&
|
||||
c <= (ucp_table[mid].f0 & f0_charmask) +
|
||||
(ucp_table[mid].f1 & f1_rangemask)) break;
|
||||
c <= (int)((ucp_table[mid].f0 & f0_charmask) +
|
||||
(ucp_table[mid].f1 & f1_rangemask))) break;
|
||||
bot = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
|
||||
#include "portaudio.h"
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
Wed Mar 17 11:21:56 CDT 2010
|
||||
Tue Nov 1 11:51:42 CDT 2011
|
||||
|
||||
+185
-56
@@ -1,16 +1,25 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
|
||||
Software Foundation, Inc.
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. This file is offered as-is,
|
||||
without warranty of any kind.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package. Some packages provide this
|
||||
`INSTALL' file but do not implement all of the features documented
|
||||
below. The lack of an optional feature in a given package is not
|
||||
necessarily a bug. More recommendations for GNU packages can be found
|
||||
in *note Makefile Conventions: (standards)Makefile Conventions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
@@ -23,9 +32,9 @@ debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
the results of its tests to speed up reconfiguring. Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
@@ -35,30 +44,37 @@ some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
`./configure' to configure the package for your system.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
Running `configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
the package, generally using the just-built uninstalled binaries.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
documentation. When installing into a prefix owned by root, it is
|
||||
recommended that the package be configured and built as a regular
|
||||
user, and only the `make install' phase executed with root
|
||||
privileges.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
5. Optionally, type `make installcheck' to repeat any self-tests, but
|
||||
this time using the binaries in their final installed location.
|
||||
This target does not install anything. Running this target as a
|
||||
regular user, particularly if the prior `make install' required
|
||||
root privileges, verifies that the installation completed
|
||||
correctly.
|
||||
|
||||
6. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
@@ -67,45 +83,69 @@ The simplest way to compile this package is:
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
7. Often, you can also type `make uninstall' to remove the installed
|
||||
files again. In practice, not all packages have tested that
|
||||
uninstallation works correctly, even though it is required by the
|
||||
GNU Coding Standards.
|
||||
|
||||
8. Some packages, particularly those that use Automake, provide `make
|
||||
distcheck', which can by used by developers to test that all other
|
||||
targets like `make install' and `make uninstall' work correctly.
|
||||
This target is generally not run by end users.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
source code in the directory that `configure' is in and in `..'. This
|
||||
is known as a "VPATH" build.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
On MacOS X 10.5 and later systems, you can create libraries and
|
||||
executables that work on multiple system types--known as "fat" or
|
||||
"universal" binaries--by specifying multiple `-arch' options to the
|
||||
compiler but only a single `-arch' option to the preprocessor. Like
|
||||
this:
|
||||
|
||||
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CPP="gcc -E" CXXCPP="g++ -E"
|
||||
|
||||
This is not guaranteed to produce working output in all cases, you
|
||||
may have to build one architecture at a time and combine the results
|
||||
using the `lipo' tool if you have problems.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
`configure' the option `--prefix=PREFIX', where PREFIX must be an
|
||||
absolute file name.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
@@ -116,16 +156,47 @@ Documentation and other data files still use the regular prefix.
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
you can set and what kinds of files go in them. In general, the
|
||||
default for these options is expressed in terms of `${prefix}', so that
|
||||
specifying just `--prefix' will affect all of the other directory
|
||||
specifications that were not explicitly provided.
|
||||
|
||||
The most portable way to affect installation locations is to pass the
|
||||
correct locations to `configure'; however, many packages provide one or
|
||||
both of the following shortcuts of passing variable assignments to the
|
||||
`make install' command line to change installation locations without
|
||||
having to reconfigure or recompile.
|
||||
|
||||
The first method involves providing an override variable for each
|
||||
affected directory. For example, `make install
|
||||
prefix=/alternate/directory' will choose an alternate location for all
|
||||
directory configuration variables that were expressed in terms of
|
||||
`${prefix}'. Any directories that were specified during `configure',
|
||||
but not in terms of `${prefix}', must each be overridden at install
|
||||
time for the entire installation to be relocated. The approach of
|
||||
makefile variable overrides for each directory variable is required by
|
||||
the GNU Coding Standards, and ideally causes no recompilation.
|
||||
However, some platforms have known limitations with the semantics of
|
||||
shared libraries that end up requiring recompilation when using this
|
||||
method, particularly noticeable in packages that use GNU Libtool.
|
||||
|
||||
The second method involves providing the `DESTDIR' variable. For
|
||||
example, `make install DESTDIR=/alternate/directory' will prepend
|
||||
`/alternate/directory' before all installation names. The approach of
|
||||
`DESTDIR' overrides is not required by the GNU Coding Standards, and
|
||||
does not work on platforms that have drive letters. On the other hand,
|
||||
it does better at avoiding recompilation issues, and works well even
|
||||
when some directory options were not specified in terms of `${prefix}'
|
||||
at `configure' time.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
@@ -137,14 +208,53 @@ find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Some packages offer the ability to configure how verbose the
|
||||
execution of `make' will be. For these packages, running `./configure
|
||||
--enable-silent-rules' sets the default to minimal output, which can be
|
||||
overridden with `make V=1'; while running `./configure
|
||||
--disable-silent-rules' sets the default to verbose, which can be
|
||||
overridden with `make V=0'.
|
||||
|
||||
Particular systems
|
||||
==================
|
||||
|
||||
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
|
||||
CC is not installed, it is recommended to use the following options in
|
||||
order to use an ANSI C compiler:
|
||||
|
||||
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
|
||||
|
||||
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||
|
||||
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
|
||||
a workaround. If GNU CC is not installed, it is therefore recommended
|
||||
to try
|
||||
|
||||
./configure CC="cc"
|
||||
|
||||
and if that doesn't work, try
|
||||
|
||||
./configure CC="cc -nodtk"
|
||||
|
||||
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
|
||||
directory contains several dysfunctional programs; working variants of
|
||||
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
|
||||
in your `PATH', put it _after_ `/usr/bin'.
|
||||
|
||||
On Haiku, software installed for all users goes in `/boot/common',
|
||||
not `/usr/local'. It is recommended to use the following options:
|
||||
|
||||
./configure --prefix=/boot/common
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
@@ -152,7 +262,8 @@ type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
OS
|
||||
KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
@@ -170,9 +281,9 @@ eventually be run) with `--host=TYPE'.
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
@@ -181,7 +292,7 @@ A warning: not all `configure' scripts look for a site script.
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
@@ -190,21 +301,29 @@ them in the `configure' command line, using `VAR=value'. For example:
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script). Here is a another example:
|
||||
overridden in the site shell script).
|
||||
|
||||
/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
|
||||
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
|
||||
configuration-related scripts to be executed by `/bin/bash'.
|
||||
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
Print a summary of all of the options to `configure', and exit.
|
||||
|
||||
`--help=short'
|
||||
`--help=recursive'
|
||||
Print a summary of the options unique to this package's
|
||||
`configure', and exit. The `short' variant lists options used
|
||||
only in the top level, while the `recursive' variant lists options
|
||||
also present in any nested packages.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
@@ -231,6 +350,16 @@ configuration-related scripts to be executed by `/bin/bash'.
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--prefix=DIR'
|
||||
Use DIR as the installation prefix. *note Installation Names::
|
||||
for more details, including other options available for fine-tuning
|
||||
the installation locations.
|
||||
|
||||
`--no-create'
|
||||
`-n'
|
||||
Run the configure checks, but stop before creating any output
|
||||
files.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
|
||||
+38
-42
@@ -1,6 +1,5 @@
|
||||
|
||||
AM_CFLAGS = -Isrc -Iinterface -fPIC -Wall -O3
|
||||
AUTOMAKE_OPTS = gnu
|
||||
AM_CFLAGS = -Isrc -Iinterface -fPIC -O3
|
||||
AUTOMAKE_OPTIONS = gnu
|
||||
NAME = libSKP_SILK_SDK
|
||||
AM_CPPFLAGS = $(AM_CFLAGS)
|
||||
|
||||
@@ -15,34 +14,32 @@ test/SignalCompare.vcproj
|
||||
|
||||
lib_LTLIBRARIES = libSKP_SILK_SDK.la
|
||||
libSKP_SILK_SDK_la_SOURCES = src/SKP_Silk_A2NLSF.c \
|
||||
src/SKP_Silk_allpass_int.c \
|
||||
src/SKP_Silk_ana_filt_bank_1.c \
|
||||
src/SKP_Silk_apply_sine_window.c \
|
||||
src/SKP_Silk_apply_sine_window_new.c \
|
||||
src/SKP_Silk_array_maxabs.c \
|
||||
src/SKP_Silk_autocorr.c \
|
||||
src/SKP_Silk_biquad_alt.c \
|
||||
src/SKP_Silk_biquad.c \
|
||||
src/SKP_Silk_biquad_alt.c \
|
||||
src/SKP_Silk_burg_modified.c \
|
||||
src/SKP_Silk_bwexpander_32.c \
|
||||
src/SKP_Silk_bwexpander.c \
|
||||
src/SKP_Silk_bwexpander_32.c \
|
||||
src/SKP_Silk_CNG.c \
|
||||
src/SKP_Silk_code_signs.c \
|
||||
src/SKP_Silk_control_audio_bandwidth.c \
|
||||
src/SKP_Silk_control_codec_FIX.c \
|
||||
src/SKP_Silk_corrMatrix_FIX.c \
|
||||
src/SKP_Silk_create_init_destroy.c \
|
||||
src/SKP_Silk_dec_API.c \
|
||||
src/SKP_Silk_decode_core.c \
|
||||
src/SKP_Silk_decode_frame.c \
|
||||
src/SKP_Silk_decode_indices_v4.c \
|
||||
src/SKP_Silk_decode_parameters.c \
|
||||
src/SKP_Silk_decode_parameters_v4.c \
|
||||
src/SKP_Silk_decode_pitch.c \
|
||||
src/SKP_Silk_decode_pulses.c \
|
||||
src/SKP_Silk_decoder_set_fs.c \
|
||||
src/SKP_Silk_detect_SWB_input.c \
|
||||
src/SKP_Silk_enc_API.c \
|
||||
src/SKP_Silk_encode_frame_FIX.c \
|
||||
src/SKP_Silk_encode_parameters.c \
|
||||
src/SKP_Silk_encode_parameters_v4.c \
|
||||
src/SKP_Silk_encode_pulses.c \
|
||||
src/SKP_Silk_find_LPC_FIX.c \
|
||||
src/SKP_Silk_find_LTP_FIX.c \
|
||||
@@ -56,78 +53,75 @@ src/SKP_Silk_interpolate.c \
|
||||
src/SKP_Silk_k2a.c \
|
||||
src/SKP_Silk_k2a_Q16.c \
|
||||
src/SKP_Silk_LBRR_reset.c \
|
||||
src/SKP_Silk_lin2log.c \
|
||||
src/SKP_Silk_log2lin.c \
|
||||
src/SKP_Silk_lowpass_int.c \
|
||||
src/SKP_Silk_lowpass_short.c \
|
||||
src/SKP_Silk_LPC_inv_pred_gain.c \
|
||||
src/SKP_Silk_LPC_stabilize.c \
|
||||
src/SKP_Silk_LPC_synthesis_filter.c \
|
||||
src/SKP_Silk_LPC_synthesis_order16.c \
|
||||
src/SKP_Silk_LP_variable_cutoff.c \
|
||||
src/SKP_Silk_LSF_cos_table.c \
|
||||
src/SKP_Silk_LTP_analysis_filter_FIX.c \
|
||||
src/SKP_Silk_LTP_scale_ctrl_FIX.c \
|
||||
src/SKP_Silk_lin2log.c \
|
||||
src/SKP_Silk_log2lin.c \
|
||||
src/SKP_Silk_MA.c \
|
||||
src/SKP_Silk_NLSF2A.c \
|
||||
src/SKP_Silk_NLSF2A_stable.c \
|
||||
src/SKP_Silk_NLSF_MSVQ_decode.c \
|
||||
src/SKP_Silk_NLSF_MSVQ_encode_FIX.c \
|
||||
src/SKP_Silk_NLSF_stabilize.c \
|
||||
src/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c \
|
||||
src/SKP_Silk_NLSF_VQ_sum_error_FIX.c \
|
||||
src/SKP_Silk_NLSF_VQ_weights_laroia.c \
|
||||
src/SKP_Silk_noise_shape_analysis_FIX.c \
|
||||
src/SKP_Silk_NLSF_stabilize.c \
|
||||
src/SKP_Silk_NSQ.c \
|
||||
src/SKP_Silk_NSQ_del_dec.c \
|
||||
src/SKP_Silk_noise_shape_analysis_FIX.c \
|
||||
src/SKP_Silk_PLC.c \
|
||||
src/SKP_Silk_pitch_analysis_core.c \
|
||||
src/SKP_Silk_pitch_est_tables.c \
|
||||
src/SKP_Silk_PLC.c \
|
||||
src/SKP_Silk_prefilter_FIX.c \
|
||||
src/SKP_Silk_process_gains_FIX.c \
|
||||
src/SKP_Silk_process_NLSFs_FIX.c \
|
||||
src/SKP_Silk_pulses_to_bytes.c \
|
||||
src/SKP_Silk_process_gains_FIX.c \
|
||||
src/SKP_Silk_quant_LTP_gains_FIX.c \
|
||||
src/SKP_Silk_range_coder.c \
|
||||
src/SKP_Silk_regularize_correlations_FIX.c \
|
||||
src/SKP_Silk_resample_1_2.c \
|
||||
src/SKP_Silk_resample_1_2_coarse.c \
|
||||
src/SKP_Silk_resample_1_2_coarsest.c \
|
||||
src/SKP_Silk_resample_1_3.c \
|
||||
src/SKP_Silk_resample_2_1_coarse.c \
|
||||
src/SKP_Silk_resample_2_3.c \
|
||||
src/SKP_Silk_resample_2_3_coarse.c \
|
||||
src/SKP_Silk_resample_2_3_coarsest.c \
|
||||
src/SKP_Silk_resample_2_3_rom.c \
|
||||
src/SKP_Silk_resample_3_1.c \
|
||||
src/SKP_Silk_resample_3_2.c \
|
||||
src/SKP_Silk_resample_3_2_rom.c \
|
||||
src/SKP_Silk_resample_3_4.c \
|
||||
src/SKP_Silk_resample_4_3.c \
|
||||
src/SKP_Silk_resampler.c \
|
||||
src/SKP_Silk_resampler_down2.c \
|
||||
src/SKP_Silk_resampler_down2_3.c \
|
||||
src/SKP_Silk_resampler_down3.c \
|
||||
src/SKP_Silk_resampler_private_AR2.c \
|
||||
src/SKP_Silk_resampler_private_ARMA4.c \
|
||||
src/SKP_Silk_resampler_private_IIR_FIR.c \
|
||||
src/SKP_Silk_resampler_private_copy.c \
|
||||
src/SKP_Silk_resampler_private_down4.c \
|
||||
src/SKP_Silk_resampler_private_down_FIR.c \
|
||||
src/SKP_Silk_resampler_private_up2_HQ.c \
|
||||
src/SKP_Silk_resampler_private_up4.c \
|
||||
src/SKP_Silk_resampler_rom.c \
|
||||
src/SKP_Silk_resampler_up2.c \
|
||||
src/SKP_Silk_residual_energy16_FIX.c \
|
||||
src/SKP_Silk_residual_energy_FIX.c \
|
||||
src/SKP_Silk_scale_copy_vector16.c \
|
||||
src/SKP_Silk_scale_vector.c \
|
||||
src/SKP_Silk_schur64.c \
|
||||
src/SKP_Silk_schur.c \
|
||||
src/SKP_Silk_schur64.c \
|
||||
src/SKP_Silk_shell_coder.c \
|
||||
src/SKP_Silk_sigm_Q15.c \
|
||||
src/SKP_Silk_solve_LS_FIX.c \
|
||||
src/SKP_Silk_sort.c \
|
||||
src/SKP_Silk_sum_sqr_shift.c \
|
||||
src/SKP_Silk_tables_gain.c \
|
||||
src/SKP_Silk_tables_LTP.c \
|
||||
src/SKP_Silk_tables_NLSF_CB0_10.c \
|
||||
src/SKP_Silk_tables_NLSF_CB0_16.c \
|
||||
src/SKP_Silk_tables_NLSF_CB1_10.c \
|
||||
src/SKP_Silk_tables_NLSF_CB1_16.c \
|
||||
src/SKP_Silk_tables_gain.c \
|
||||
src/SKP_Silk_tables_other.c \
|
||||
src/SKP_Silk_tables_pitch_lag.c \
|
||||
src/SKP_Silk_tables_pulses_per_block.c \
|
||||
src/SKP_Silk_tables_sign.c \
|
||||
src/SKP_Silk_tables_type_offset.c \
|
||||
src/SKP_Silk_VAD.c \
|
||||
src/SKP_Silk_VQ_nearest_neighbor_FIX.c
|
||||
src/SKP_Silk_VQ_nearest_neighbor_FIX.c \
|
||||
src/SKP_Silk_warped_autocorrelation_FIX.c
|
||||
|
||||
|
||||
libSKP_SILK_SDK_la_CFLAGS = $(AM_CFLAGS)
|
||||
@@ -135,24 +129,26 @@ libSKP_SILK_SDK_la_LDFLAGS = $(LIBS)
|
||||
|
||||
library_includedir = $(prefix)/include/silk
|
||||
library_include_HEADERS = src/SKP_Silk_common_pitch_est_defines.h \
|
||||
src/SKP_Silk_define_FIX.h \
|
||||
src/SKP_Silk_define.h \
|
||||
src/SKP_Silk_Inlines.h \
|
||||
src/SKP_Silk_macros.h \
|
||||
src/SKP_Silk_main_FIX.h \
|
||||
src/SKP_Silk_main.h \
|
||||
src/SKP_Silk_perceptual_parameters_FIX.h \
|
||||
src/SKP_Silk_main_FIX.h \
|
||||
src/SKP_Silk_pitch_est_defines.h \
|
||||
src/SKP_Silk_PLC.h \
|
||||
src/SKP_Silk_resample_rom.h \
|
||||
src/SKP_Silk_resampler_private.h \
|
||||
src/SKP_Silk_resampler_rom.h \
|
||||
src/SKP_Silk_resampler_structs.h \
|
||||
src/SKP_Silk_SigProc_FIX.h \
|
||||
src/SKP_Silk_structs_FIX.h \
|
||||
src/SKP_Silk_setup_complexity.h \
|
||||
src/SKP_Silk_structs.h \
|
||||
src/SKP_Silk_structs_FIX.h \
|
||||
src/SKP_Silk_tables.h \
|
||||
src/SKP_Silk_tables_NLSF_CB0_10.h \
|
||||
src/SKP_Silk_tables_NLSF_CB0_16.h \
|
||||
src/SKP_Silk_tables_NLSF_CB1_10.h \
|
||||
src/SKP_Silk_tables_NLSF_CB1_16.h \
|
||||
src/SKP_Silk_tuning_parameters.h \
|
||||
interface/SKP_Silk_control.h \
|
||||
interface/SKP_Silk_errors.h \
|
||||
interface/SKP_Silk_SDK_API.h \
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.59])
|
||||
AC_INIT(libSKP_SILK_SDK, 1.0.2, brian@freeswitch.org, libSKP_SILK_SDK)
|
||||
AM_INIT_AUTOMAKE(libSKP_SILK_SDK,1.0.2)
|
||||
AC_INIT(libSKP_SILK_SDK, 1.0.8, brian@freeswitch.org, libSKP_SILK_SDK)
|
||||
AM_INIT_AUTOMAKE(libSKP_SILK_SDK,1.0.8)
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2010, Skype Limited. All rights reserved.
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, (subject to the limitations in the disclaimer below)
|
||||
are permitted provided that the following conditions are met:
|
||||
@@ -39,7 +39,7 @@ extern "C"
|
||||
|
||||
#define SILK_MAX_FRAMES_PER_PACKET 5
|
||||
|
||||
/* Struct for TOC (Table Of Contents) */
|
||||
/* Struct for TOC (Table of Contents) */
|
||||
typedef struct {
|
||||
SKP_int framesInPacket; /* Number of 20 ms frames in packet */
|
||||
SKP_int fs_kHz; /* Sampling frequency in packet */
|
||||
@@ -85,7 +85,7 @@ SKP_int SKP_Silk_SDK_Encode(
|
||||
const SKP_int16 *samplesIn, /* I: Speech sample input vector */
|
||||
SKP_int nSamplesIn, /* I: Number of samples in input vector */
|
||||
SKP_uint8 *outData, /* O: Encoded output vector */
|
||||
SKP_int16 *nBytesOut /* I/O: Number of Bytes in outData (input: Max Bytes) */
|
||||
SKP_int16 *nBytesOut /* I/O: Number of bytes in outData (input: Max bytes) */
|
||||
);
|
||||
|
||||
/****************************************/
|
||||
@@ -114,7 +114,7 @@ SKP_int SKP_Silk_SDK_Decode(
|
||||
SKP_SILK_SDK_DecControlStruct* decControl, /* I/O: Control Structure */
|
||||
SKP_int lostFlag, /* I: 0: no loss, 1 loss */
|
||||
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||
const SKP_int nBytesIn, /* I: Number of input Bytes */
|
||||
const SKP_int nBytesIn, /* I: Number of input bytes */
|
||||
SKP_int16 *samplesOut, /* O: Decoded output speech vector */
|
||||
SKP_int16 *nSamplesOut /* I/O: Number of samples (vector/decoded) */
|
||||
);
|
||||
@@ -123,22 +123,20 @@ SKP_int SKP_Silk_SDK_Decode(
|
||||
/* Find Low Bit Rate Redundancy (LBRR) information in a packet */
|
||||
/***************************************************************/
|
||||
void SKP_Silk_SDK_search_for_LBRR(
|
||||
void *decState, /* I: Decoder state, to select bitstream version only */
|
||||
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||
const SKP_int16 nBytesIn, /* I: Number of input Bytes */
|
||||
const SKP_int nBytesIn, /* I: Number of input Bytes */
|
||||
SKP_int lost_offset, /* I: Offset from lost packet */
|
||||
SKP_uint8 *LBRRData, /* O: LBRR payload */
|
||||
SKP_int16 *nLBRRBytes /* O: Number of LBRR Bytes */
|
||||
);
|
||||
|
||||
/************************************/
|
||||
/* Get type of content for a packet */
|
||||
/************************************/
|
||||
/**************************************/
|
||||
/* Get table of contents for a packet */
|
||||
/**************************************/
|
||||
void SKP_Silk_SDK_get_TOC(
|
||||
void *decState, /* I: Decoder state, to select bitstream version only */
|
||||
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||
const SKP_int16 nBytesIn, /* I: Number of input bytes */
|
||||
SKP_Silk_TOC_struct *Silk_TOC /* O: Type of content */
|
||||
const SKP_int nBytesIn, /* I: Number of input bytes */
|
||||
SKP_Silk_TOC_struct *Silk_TOC /* O: Table of contents */
|
||||
);
|
||||
|
||||
/**************************/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2010, Skype Limited. All rights reserved.
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, (subject to the limitations in the disclaimer below)
|
||||
are permitted provided that the following conditions are met:
|
||||
@@ -39,8 +39,11 @@ extern "C"
|
||||
/* Structure for controlling encoder operation */
|
||||
/***********************************************/
|
||||
typedef struct {
|
||||
/* I: Sampling rate in Hertz; 8000/12000/16000/24000 */
|
||||
SKP_int32 sampleRate;
|
||||
/* I: Input signal sampling rate in Hertz; 8000/12000/16000/24000 */
|
||||
SKP_int32 API_sampleRate;
|
||||
|
||||
/* I: Maximum internal sampling rate in Hertz; 8000/12000/16000/24000 */
|
||||
SKP_int32 maxInternalSampleRate;
|
||||
|
||||
/* I: Number of samples per packet; must be equivalent of 20, 40, 60, 80 or 100 ms */
|
||||
SKP_int packetSize;
|
||||
@@ -48,7 +51,7 @@ typedef struct {
|
||||
/* I: Bitrate during active speech in bits/second; internally limited */
|
||||
SKP_int32 bitRate;
|
||||
|
||||
/* I: Uplink Packet loss in pct (0...100) */
|
||||
/* I: Uplink packet loss in percent (0-100) */
|
||||
SKP_int packetLossPercentage;
|
||||
|
||||
/* I: Complexity mode; 0 is lowest; 1 is medium and 2 is highest complexity */
|
||||
@@ -57,7 +60,7 @@ typedef struct {
|
||||
/* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */
|
||||
SKP_int useInBandFEC;
|
||||
|
||||
/* I: Flag to enable Discontinous Transmission; 0/1 */
|
||||
/* I: Flag to enable discontinuous transmission (DTX); 0/1 */
|
||||
SKP_int useDTX;
|
||||
} SKP_SILK_SDK_EncControlStruct;
|
||||
|
||||
@@ -65,8 +68,8 @@ typedef struct {
|
||||
/* Structure for controlling decoder operation and reading decoder status */
|
||||
/**************************************************************************/
|
||||
typedef struct {
|
||||
/* I: Sampling rate in Hertz; 8000/12000/16000/24000 */
|
||||
SKP_int32 sampleRate;
|
||||
/* I: Output signal sampling rate in Hertz; 8000/12000/16000/24000 */
|
||||
SKP_int32 API_sampleRate;
|
||||
|
||||
/* O: Number of samples per frame */
|
||||
SKP_int frameSize;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2010, Skype Limited. All rights reserved.
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, (subject to the limitations in the disclaimer below)
|
||||
are permitted provided that the following conditions are met:
|
||||
@@ -36,48 +36,45 @@ extern "C"
|
||||
/******************/
|
||||
/* Error messages */
|
||||
/******************/
|
||||
#define SKP_SILK_NO_ERROR 0
|
||||
#define SKP_SILK_NO_ERROR 0
|
||||
|
||||
/**************************/
|
||||
/* Encoder error messages */
|
||||
/**************************/
|
||||
|
||||
/* Input length is not a multiplum of 10 ms,
|
||||
or length is longer than the packet length */
|
||||
#define SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES -1
|
||||
/* Input length is not a multiplum of 10 ms, or length is longer than the packet length */
|
||||
#define SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES -1
|
||||
|
||||
/* Sampling frequency not 8000, 12000, 16000
|
||||
or 24000 Hertz */
|
||||
#define SKP_SILK_ENC_FS_NOT_SUPPORTED -2
|
||||
/* Sampling frequency not 8000, 12000, 16000 or 24000 Hertz */
|
||||
#define SKP_SILK_ENC_FS_NOT_SUPPORTED -2
|
||||
|
||||
/* Packet size not 20, 40, 60, 80 or 100 ms */
|
||||
#define SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED -3
|
||||
#define SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED -3
|
||||
|
||||
/* Allocated payload buffer too short */
|
||||
#define SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT -4
|
||||
#define SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT -4
|
||||
|
||||
/* Loss rate not between 0 and 100 percent */
|
||||
#define SKP_SILK_ENC_WRONG_LOSS_RATE -5
|
||||
#define SKP_SILK_ENC_INVALID_LOSS_RATE -5
|
||||
|
||||
/* Complexity setting not valid, use 0, 1 or 2 */
|
||||
#define SKP_SILK_ENC_WRONG_COMPLEXITY_SETTING -6
|
||||
#define SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING -6
|
||||
|
||||
/* Inband FEC setting not valid, use 0 or 1 */
|
||||
#define SKP_SILK_ENC_WRONG_INBAND_FEC_SETTING -7
|
||||
#define SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING -7
|
||||
|
||||
/* DTX setting not valid, use 0 or 1 */
|
||||
#define SKP_SILK_ENC_WRONG_DTX_SETTING -8
|
||||
#define SKP_SILK_ENC_INVALID_DTX_SETTING -8
|
||||
|
||||
/* Internal encoder error */
|
||||
#define SKP_SILK_ENC_INTERNAL_ERROR -9
|
||||
#define SKP_SILK_ENC_INTERNAL_ERROR -9
|
||||
|
||||
/**************************/
|
||||
/* Decoder error messages */
|
||||
/**************************/
|
||||
|
||||
/* Output sampling frequency lower than internal
|
||||
decoded sampling frequency */
|
||||
#define SKP_SILK_DEC_WRONG_SAMPLING_FREQUENCY -10
|
||||
/* Output sampling frequency lower than internal decoded sampling frequency */
|
||||
#define SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY -10
|
||||
|
||||
/* Payload size exceeded the maximum allowed 1024 bytes */
|
||||
#define SKP_SILK_DEC_PAYLOAD_TOO_LARGE -11
|
||||
@@ -85,7 +82,6 @@ extern "C"
|
||||
/* Payload has bit errors */
|
||||
#define SKP_SILK_DEC_PAYLOAD_ERROR -12
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2010, Skype Limited. All rights reserved.
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, (subject to the limitations in the disclaimer below)
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
+23
-7
@@ -1,14 +1,14 @@
|
||||
************************************************************************
|
||||
Fixed Point SILK SDK 1.0.2 beta source code package
|
||||
Fixed Point SILK SDK 1.0.8 beta source code package
|
||||
Copyright 2010 (c), Skype Limited
|
||||
https://developer.skype.com/silk/
|
||||
************************************************************************
|
||||
|
||||
Date: 09/03/2010 (Format: DD/MM/YYYY)
|
||||
Date: 15/06/2011 (Format: DD/MM/YYYY)
|
||||
|
||||
I. Description
|
||||
|
||||
This package contains files for compiling and testing the fixed
|
||||
This package contains files for compilation and evaluation of the fixed
|
||||
point SILK SDK library. The following is included in this package:
|
||||
|
||||
o Source code for the fixed point SILK SDK library
|
||||
@@ -51,22 +51,38 @@ III. How to use the Makefile
|
||||
|
||||
make clean all
|
||||
|
||||
6. How to use the comparison tool:
|
||||
|
||||
6. How to build for big endian CPU's
|
||||
|
||||
Make clean all ADDED_DEFINES+=_SYSTEM_IS_BIG_ENDIAN
|
||||
To be able to use the test vectors with big endian CPU's the test programs
|
||||
need to be compiled in a different way. Note that the 16 bit input and output
|
||||
from the test programs will have the upper and lower bytes swapped with this setting.
|
||||
|
||||
7. How to use the comparison tool:
|
||||
|
||||
See 'How to use the test vectors.txt' in the test_vectors folder.
|
||||
|
||||
IV. History
|
||||
|
||||
Version 1.0.8 - Improved noise shaping, various other improvements, and various bugfixes. Added a MIPS version
|
||||
Version 1.0.7 - Updated with bugfixes for LBRR and pitch estimator. SignalCompare updated
|
||||
Version 1.0.6 - Updated with bugfixes for ARM builds
|
||||
Version 1.0.5 - Updated with bugfixes for ARM builds
|
||||
Version 1.0.4 - Updated with various bugfixes and improvements, including some API changes
|
||||
Added support for big endian platforms
|
||||
Added resampler support for additional API sample rates
|
||||
Version 1.0.3 - Updated with various bugfixes and improvements
|
||||
Version 1.0.2 - Updated with various bugfixes and improvements
|
||||
Version 1.0.1 - First beta source code release
|
||||
|
||||
V. Compatibility
|
||||
|
||||
This package has been tested under the following platforms:
|
||||
This package has been tested on the following platforms:
|
||||
|
||||
Windows XP Home and Professional
|
||||
Windows Vista, 32-bit version
|
||||
Mac OS X Version 10.5.8
|
||||
Mac OSX intel
|
||||
Mac OSX ppc
|
||||
Ubuntu Linux 9.10, 64-bit version
|
||||
|
||||
VI. Known Issues
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2010, Skype Limited. All rights reserved.
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, (subject to the limitations in the disclaimer below)
|
||||
are permitted provided that the following conditions are met:
|
||||
@@ -33,10 +33,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "SKP_Silk_SigProc_FIX.h"
|
||||
|
||||
/* Number of binary divisions, when not in low complexity mode */
|
||||
#define BIN_DIV_STEPS_A2NLSF_FIX 2 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */
|
||||
/* Number of binary divisions */
|
||||
#define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */
|
||||
#define QPoly 16
|
||||
#define MAX_ITERATIONS_A2NLSF_FIX 50
|
||||
#define MAX_ITERATIONS_A2NLSF_FIX 30
|
||||
|
||||
/* Flag for using 2x as many cosine sampling points, reduces the risk of missing a root */
|
||||
#define OVERSAMPLE_COSINE_TABLE 0
|
||||
@@ -57,12 +57,11 @@ SKP_INLINE void SKP_Silk_A2NLSF_trans_poly(
|
||||
p[ k - 2 ] -= SKP_LSHIFT( p[ k ], 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper function for A2NLSF(..) */
|
||||
/* Polynomial evaluation */
|
||||
SKP_INLINE SKP_int32 SKP_Silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in QPoly */
|
||||
SKP_int32 *p, /* I Polynomial, QPoly */
|
||||
const SKP_int32 x, /* I Evaluation point, Q12 */
|
||||
const SKP_int32 x, /* I Evaluation point, Q12 */
|
||||
const SKP_int dd /* I Order */
|
||||
)
|
||||
{
|
||||
@@ -79,9 +78,9 @@ SKP_INLINE SKP_int32 SKP_Silk_A2NLSF_eval_poly( /* return the polynomial eval
|
||||
|
||||
SKP_INLINE void SKP_Silk_A2NLSF_init(
|
||||
const SKP_int32 *a_Q16,
|
||||
SKP_int32 *P,
|
||||
SKP_int32 *Q,
|
||||
const SKP_int dd
|
||||
SKP_int32 *P,
|
||||
SKP_int32 *Q,
|
||||
const SKP_int dd
|
||||
)
|
||||
{
|
||||
SKP_int k;
|
||||
@@ -127,8 +126,8 @@ void SKP_Silk_A2NLSF(
|
||||
SKP_int32 xlo, xhi, xmid;
|
||||
SKP_int32 ylo, yhi, ymid;
|
||||
SKP_int32 nom, den;
|
||||
SKP_int32 P[ SigProc_MAX_ORDER_LPC / 2 + 1 ];
|
||||
SKP_int32 Q[ SigProc_MAX_ORDER_LPC / 2 + 1 ];
|
||||
SKP_int32 P[ SKP_Silk_MAX_ORDER_LPC / 2 + 1 ];
|
||||
SKP_int32 Q[ SKP_Silk_MAX_ORDER_LPC / 2 + 1 ];
|
||||
SKP_int32 *PQ[ 2 ];
|
||||
SKP_int32 *p;
|
||||
|
||||
@@ -258,7 +257,7 @@ void SKP_Silk_A2NLSF(
|
||||
}
|
||||
|
||||
/* Error: Apply progressively more bandwidth expansion and run again */
|
||||
SKP_Silk_bwexpander_32( a_Q16, d, 65536 - SKP_SMULBB( 66, i ) ); // 66_Q16 = 0.001
|
||||
SKP_Silk_bwexpander_32( a_Q16, d, 65536 - SKP_SMULBB( 10 + i, i ) ); // 10_Q16 = 0.00015
|
||||
|
||||
SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd );
|
||||
p = P; /* Pointer to polynomial */
|
||||
@@ -269,9 +268,9 @@ void SKP_Silk_A2NLSF(
|
||||
NLSF[ 0 ] = 0;
|
||||
p = Q; /* Pointer to polynomial */
|
||||
ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
|
||||
root_ix = 1; /* Index of current root */
|
||||
root_ix = 1; /* Index of current root */
|
||||
} else {
|
||||
root_ix = 0; /* Index of current root */
|
||||
root_ix = 0; /* Index of current root */
|
||||
}
|
||||
k = 1; /* Reset loop counter */
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user