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:
Moises Silva
2011-12-17 17:42:34 -05:00
615 changed files with 41286 additions and 47127 deletions
+414 -658
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -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 */
+5
View File
@@ -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;
+4 -1
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1 -8
View File
@@ -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;
}
+25
View File
@@ -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);
+38
View File
@@ -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},
+3
View File
@@ -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);
+5
View File
@@ -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);
+16
View File
@@ -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 ;
+1
View File
@@ -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;
+52
View File
@@ -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},
+8
View File
@@ -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;
+43
View File
@@ -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)
+1
View File
@@ -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);
+1
View File
@@ -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)
+53
View File
@@ -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},
+46
View File
@@ -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
View File
@@ -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)
+19 -3
View File
@@ -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);
}
+9
View File
@@ -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) {
+22 -4
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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);
+1 -6
View File
@@ -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;
}
+11 -3
View File
@@ -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
View File
@@ -1 +1,2 @@
m4_include([build/ax_compiler_vendor.m4])
m4_include([build/libpcap.m4])
+5
View File
@@ -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"/>-->
+79 -2
View File
@@ -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
View File
@@ -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}
===============================================================================
])
+76
View File
@@ -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>
+316 -115
View File
@@ -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;
}
}
+25 -4
View File
@@ -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
View File
@@ -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;
+42 -19
View File
@@ -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
+3 -3
View File
@@ -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.
*
+110 -52
View File
@@ -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:
+57 -6
View File
@@ -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
View File
@@ -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.
+4 -1
View File
@@ -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
+49
View File
@@ -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)
])
+214
View File
@@ -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;
-1407
View File
File diff suppressed because it is too large Load Diff
-1504
View File
File diff suppressed because it is too large Load Diff
-17354
View File
File diff suppressed because it is too large Load Diff
+1 -6
View File
@@ -673,12 +673,7 @@ CFLAGS
LDFLAGS
LIBS
CPPFLAGS
CPP
CPPFLAGS
CC
LDFLAGS
LIBS
CPPFLAGS'
CPP'
# Initialize some variables set by options.
+2 -6
View File
@@ -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.
+6
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,5 +1,5 @@
AM_CFLAGS = -Isrc -Wall -lm
AUTOMAKE_OPTS = gnu
AUTOMAKE_OPTIONS = gnu
NAME = libcodec2
AM_CPPFLAGS = $(AM_CFLAGS)
+1 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 ;
+27 -61
View File
@@ -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);
}
+9 -4
View File
@@ -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 -1
View File
@@ -1,6 +1,6 @@
EXTRA_DIST =
SUBDIRS =
AUTOMAKE_OPTS= gnu
AUTOMAKE_OPTIONS = gnu
NAME=teletone
AM_CFLAGS = $(new_AM_CFLAGS) -I./src
+2 -2
View File
@@ -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
+64 -39
View File
@@ -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:
+17 -8
View File
@@ -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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+3
View File
@@ -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])
+3 -3
View File
@@ -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
View File
@@ -1 +1 @@
Wed Mar 17 11:21:56 CDT 2010
Tue Nov 1 11:51:42 CDT 2011
+185 -56
View File
@@ -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
View File
@@ -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 -2
View File
@@ -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
+10 -12
View File
@@ -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 */
);
/**************************/
+10 -7
View File
@@ -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;
+15 -19
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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
+13 -14
View File
@@ -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