summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile54
-rw-r--r--README4
-rw-r--r--action.cpp441
-rw-r--r--admin_server.c3
-rw-r--r--apppbx.cpp334
-rw-r--r--callpbx.cpp181
-rw-r--r--callpbx.h6
-rw-r--r--dss1.cpp11
-rw-r--r--extension.c22
-rw-r--r--interface.c25
-rw-r--r--mISDN.cpp38
-rw-r--r--mISDN.h4
-rw-r--r--main.c119
-rw-r--r--main.h68
-rw-r--r--message.c25
-rw-r--r--message.h7
-rw-r--r--options.c171
-rw-r--r--options.h22
-rw-r--r--port.cpp1113
-rw-r--r--port.h16
-rw-r--r--route.c37
-rw-r--r--route.h68
-rw-r--r--todo.txt5
-rw-r--r--tones.c84
-rw-r--r--vbox.cpp66
25 files changed, 401 insertions, 2523 deletions
diff --git a/Makefile b/Makefile
index d57816a..56f705a 100644
--- a/Makefile
+++ b/Makefile
@@ -9,9 +9,6 @@
#* **
#*****************************************************************************/
-WITH-PBX = 42 # MUST BE SET for now
-#WITH-H323 = 42 # comment this out, if no h323 should be compiled
-#WITH-OPAL = 42 # NOT SUPPORTED YET
WITH-CRYPTO = 42 # comment this out, if no libcrypto should be used
# note: check your location and the names of libraries.
@@ -19,12 +16,8 @@ WITH-CRYPTO = 42 # comment this out, if no libcrypto should be used
INSTALL_BIN = /usr/local/bin
INSTALL_DATA = /usr/local/pbx
-# give locations for the libraries (comment out H323_LIB and PWLIB_LIB, if they are installed on the system)
+# give locations for the libraries
LINUX_INCLUDE = -I/usr/src/linux/include
-H323_INCLUDE = -I/usr/local/include/openh323
-#H323_LIB = -L/usr/local/lib
-#PWLIB_INCLUDE = -I/usr/local/include/ptlib/unix
-#PWLIB_LIB = -L/usr/local/lib
# give location of the mISDN libraries
MISDNUSER_INCLUDE = -I../mISDNuser/include
@@ -46,28 +39,10 @@ GENRC = ./genrc
GENEXT = ./genextension
CFLAGS = -Wall -g -DINSTALL_DATA=\"$(INSTALL_DATA)\"
CFLAGS += $(LINUX_INCLUDE) $(MISDNUSER_INCLUDE)
-ifdef WITH-PBX
-CFLAGS += -DPBX
-endif
ifdef WITH-CRYPTO
CFLAGS += -DCRYPTO
endif
-CFLAGS_OPAL = $(CFLAGS)
-CFLAGS_H323 = $(CFLAGS)
LIBDIR += $(MISDNUSER_LIB)
-ifdef WITH-OPAL
-OPAL = opal.o opal_mgr.o opal_pbxep.o opal_pbxcon.o opal_pbxms.o
-CFLAGS += -DOPAL
-CFLAGS_OPAL += $(OPAL_INCLUDE) -DOPAL
-LIBDIR += $(OPAL_LIB)
-endif
-ifdef WITH-H323
-H323 = h323.o h323_ep.o h323_con.o h323_chan.o
-LIBS += -lh323_linux_x86_r -lpt_linux_x86_r -ldl
-CFLAGS += -DH323
-CFLAGS_H323 += $(H323_INCLUDE) $(PWLIB_INCLUDE) -DH323INCLUDE -DH323 -D_REENTRANT -DPBYTE_ORDER=PLITTLE_ENDIAN -DP_PTHREADS -DP_HAS_SEMAPHORES -DPHAS_TEMPLATES -DP_LINUX -DPTRACING
-LIBDIR += $(H323_LIB) $(PWLIB_LIB)
-endif
ifdef WITH-CRYPTO
LIBDIR += -L/usr/local/ssl/lib
CFLAGS += -I/usr/local/ssl/include
@@ -92,7 +67,7 @@ all: $(PBXADMIN) $(PBX) $(GEN) $(GENW) $(GENRC) $(GENEXT)
@exit
main.o: main.c *.h Makefile
- $(CC) -c $(CFLAGS_H323) main.c -o main.o
+ $(CC) -c $(CFLAGS) main.c -o main.o
message.o: message.c *.h Makefile
$(CC) -c $(CFLAGS) message.c -o message.o
@@ -103,9 +78,6 @@ options.o: options.c *.h Makefile
interface.o: interface.c *.h Makefile
$(CC) -c $(CFLAGS) interface.c -o interface.o
-h323conf.o: h323conf.c *.h Makefile
- $(CC) -c $(CFLAGS) h323conf.c -o h323conf.o
-
extension.o: extension.c *.h Makefile
$(CC) -c $(CFLAGS) extension.c -o extension.o
@@ -184,18 +156,6 @@ tones.o: tones.c *.h Makefile
crypt.o: crypt.cpp *.h Makefile
$(CC) -c $(CFLAGS) crypt.cpp -o crypt.o
-h323.o: h323.cpp *.h Makefile
- $(CC) -c $(CFLAGS_H323) h323.cpp -o h323.o
-
-h323_ep.o: h323_ep.cpp *.h Makefile
- $(CC) -c $(CFLAGS_H323) h323_ep.cpp -o h323_ep.o
-
-h323_chan.o: h323_chan.cpp *.h Makefile
- $(CC) -c $(CFLAGS_H323) h323_chan.cpp -o h323_chan.o
-
-h323_con.o: h323_con.cpp *.h Makefile
- $(CC) -c $(CFLAGS_H323) h323_con.cpp -o h323_con.o
-
genext.o: genext.c *.h Makefile
$(CC) -c $(CFLAGS) genext.c -o genext.o
@@ -210,11 +170,9 @@ admin_server.o: admin_server.c *.h Makefile
# $(CC) $(LIBDIR) $(CFLAGS) -lm wizzard.c \
# -o $(WIZZARD)
-$(PBX): $(H323) $(OPAL) \
- main.o \
+$(PBX): main.o \
options.o \
interface.o \
- h323conf.o \
extension.o \
cause.o \
alawulaw.o \
@@ -237,11 +195,10 @@ $(PBX): $(H323) $(OPAL) \
callpbx.o \
callchan.o \
admin_server.o
- $(LD) $(LIBDIR) $(H323) $(OPAL) \
+ $(LD) $(LIBDIR) \
main.o \
options.o \
interface.o \
- h323conf.o \
extension.o \
cause.o \
alawulaw.o \
@@ -318,9 +275,6 @@ install:
echo "NOTE: numbering_int.conf is obsolete, please use routing." ; fi
@if test -a $(INSTALL_DATA)/numbering_ext.conf ; then \
echo "NOTE: numbering_ext.conf is obsolete, please use routing." ; fi
- @if test -a $(INSTALL_DATA)/h323_gateway.conf ; then \
- echo "NOTE: h323_gateway.conf already exists, not changed." ; else \
- cp -v default/h323_gateway.conf $(INSTALL_DATA) ; fi
@if test -a $(INSTALL_DATA)/directory.list ; then \
echo "NOTE: directory.list already exists, not changed." ; else \
cp -v default/directory.list $(INSTALL_DATA) ; fi
diff --git a/README b/README
index 1a51fef..7210cee 100644
--- a/README
+++ b/README
@@ -334,8 +334,4 @@ Changes in Version 3.4
- Timeout condition seems to work now.
- Timeout action seems to work now.
-What you might expect in later versions
- -> ISDN over IP (proprietary solution)
- -> OPAL, with a new interface between user space audio and kernel space audio (SIP / H323)
- -> (maybe later) Kernel space RTP that makes VoIP reeeeeeeeeeeeally fast!
diff --git a/action.cpp b/action.cpp
index 51aa8db..003dcf4 100644
--- a/action.cpp
+++ b/action.cpp
@@ -67,7 +67,7 @@ char *numberrize_callerinfo(char *string, int ntype)
/*
- * process init 'internal' / 'external' / 'h323' / 'chan' / 'vbox-record' / 'partyline'...
+ * process init 'internal' / 'external' / 'chan' / 'vbox-record' / 'partyline'...
*/
void EndpointAppPBX::_action_init_call(int chan)
{
@@ -374,432 +374,6 @@ void EndpointAppPBX::action_dialing_external(void)
}
-#ifdef H323
-/*
- * process dialing h323
- */
-#define set_ip_macro \
- UNCPY(helpbuffer, address, sizeof(helpbuffer)); \
- helpbuffer[sizeof(helpbuffer)-1] = '\0'; \
- UNPRINT(helpbuffer + (int)(address - dial), sizeof(helpbuffer)-1 - (int)(address - dial), "%d.%d.%d.%d", ip_a, ip_b, ip_c, ip_d); \
- ii = strlen(helpbuffer); \
- UNCAT(helpbuffer, dial+i, sizeof(helpbuffer)-1); \
- dial = address + ii; \
- i = 0; \
- UCPY(address, helpbuffer);
-#define set_port_macro \
- UNCPY(helpbuffer, address, sizeof(helpbuffer)); \
- helpbuffer[sizeof(helpbuffer)-1] = '\0'; \
- UNPRINT(helpbuffer + (int)(address - dial), sizeof(helpbuffer)-1 - (int)(address - dial), "%d", port); \
- ii = strlen(helpbuffer); \
- UNCAT(helpbuffer, dial+i, sizeof(helpbuffer)-1); \
- dial = address + ii; \
- i = 0; \
- UCPY(address, helpbuffer);
-void EndpointAppPBX::action_dialing_h323(void)
-{
- struct message *message;
- struct dialing_info dialinginfo;
- int i,j, ii;
- struct port_list *portlist = ea_endpoint->ep_portlist;
- char *dial;
- char address_buffer[256], *address=address_buffer;
- char host[128] = "";
- int ip_a=0, ip_b=0, ip_c=0, ip_d=0, port=0;
- struct route_param *rparam;
- char helpbuffer[128];
-
- /* check if address parameter is given */
- if ((rparam = routeparam(e_action, PARAM_ADDRESS)))
- {
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): complete address is given by parameter: '%s'\n", ea_endpoint->ep_serial, rparam->string_value);
- SCPY(address_buffer, rparam->string_value);
- goto address_complete;
- }
-
- /* check for given host */
- if ((rparam = routeparam(e_action, PARAM_HOST)))
- if (rparam->string_value[0])
- {
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): host is given by parameter: '%s'\n", ea_endpoint->ep_serial, rparam->string_value);
- SCPY(host, rparam->string_value);
- if ((rparam = routeparam(e_action, PARAM_PORT)))
- {
- if (rparam->integer_value>0 && rparam->integer_value<65536)
- {
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): port is given with the host by parameter: %d\n", ea_endpoint->ep_serial, rparam->integer_value);
- if (strlen(host)+7 < sizeof(host))
- UPRINT(host, ":%d/", rparam->integer_value);
- } else
- {
- SCAT(host, "/");
- }
- } else
- {
- SCAT(host, "/");
- }
- }
-
- /* include prefix and put 'host'(port) in front */
- if ((rparam = routeparam(e_action, PARAM_PREFIX)))
- {
- SPRINT(address_buffer, "%s%s%s", host, rparam->string_value, e_extdialing);
- } else
- {
- if (host[0])
- {
- SPRINT(address_buffer, "%s%s", host, e_extdialing);
- printf("address:%s host %s extdialing %s\n",address,host, e_extdialing);
- } else {
- address = e_extdialing;
- }
- }
- dial = address;
-
- /* check dialing */
- /* check for ip-number only with numerical digits (can be dialed by any phone) */
- if (host[0])
- {
- dial = address + strlen(host);
- goto check_user; /* we have complete host (port) */
- }
- i = 0;
- while(i < 12)
- {
- if (dial[i] == '\0')
- return; /* unfinished */
- if (dial[i]<'0' || dial[i]>'9')
- goto check_complex;
- i++;
-
- if (i == 3)
- {
- ip_a = (dial[0]-'0')*100 + (dial[1]-'0')*10 + (dial[2]-'0');
- if (ip_a > 255)
- {
- invalid:
- printlog("%3d action H323 address '%s' is invalid.\n", ea_endpoint->ep_serial, address);
- message_disconnect_port(portlist, CAUSE_INVALID, LOCATION_PRIVATE_LOCAL, "");
- new_state(EPOINT_STATE_OUT_DISCONNECT);
- set_tone(portlist,"cause_1c");
- return;
- }
- }
- if (i == 6)
- {
- ip_b = (dial[3]-'0')*100 + (dial[4]-'0')*10 + (dial[5]-'0');
- if (ip_b > 255)
- goto invalid;
- }
- if (i == 9)
- {
- ip_c = (dial[6]-'0')*100 + (dial[7]-'0')*10 + (dial[8]-'0');
- if (ip_c > 255)
- goto invalid;
- }
- if (i == 12)
- {
- ip_d = (dial[9]-'0')*100 + (dial[10]-'0')*10 + (dial[11]-'0');
- if (ip_d > 255)
- goto invalid;
- }
- if (i==4 || i==7 || i==10)
- {
- if (dial[i-1] > '2')
- goto invalid;
- }
- if (i==5 || i==8 || i==11)
- {
- if (dial[i-2]=='2' && dial[i-1]>'5')
- goto invalid;
- }
- }
- UPRINT(address, "%d.%d.%d.%d", ip_a, ip_b, ip_c, ip_d);
- i = strlen(address);
- goto address_complete;
-
- /* there are three stages of dialing: 1. ip, 2. port, 3. user, let's find out where we at */
- check_complex:
- if (strchr(address, '@'))
- {
- dial = strchr(address, '\0');
- goto address_complete;
- }
- if (strchr(address, ':'))
- {
- dial = strchr(address, ':') + 1;
- goto check_port;
- }
- if (strchr(address, '/'))
- {
- dial = strchr(address, '/') + 1;
- goto check_user;
- }
-
- /* get ip from ip-number */
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): checking dialed for ip: %s\n", ea_endpoint->ep_serial, dial);
- ip_a = ip_b = ip_c = ip_d = 0;
- i = 0;
- j = 0;
- while(42)
- {
- if (j==4)
- goto invalid;
- if (ip_a > 255)
- goto invalid;
- if (dial[i]>='0' && dial[i]<='9')
- ip_a = (ip_a*10) + dial[i]-'0';
- else if (dial[i]=='.' || dial[i]=='*')
- {
- dial[i] = '.';
-// if (i && dial[i-1]=='.')
-// {
-// /* add 0 if two dots */
-// UCPY(dial+i+1, dial+i);
-// dial[i]='0';
-// i++;
-// }
- i++;
- break;
- }
- else if (dial[i]=='#')
- {
- ip_d = ip_a;
- ip_a = 0;
- set_ip_macro
- i++;
- dial+= i;
- goto address_complete;
- }
- else if (dial[i] == '\0')
- {
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): ip so far: %d*\n", ea_endpoint->ep_serial, ip_a);
- return;
- }
- else
- goto invalid;
- i++;
- j++;
- }
- j = 0;
- while(42)
- {
- if (j==4)
- goto invalid;
- if (ip_b > 255)
- goto invalid;
- if (dial[i]>='0' && dial[i]<='9')
- ip_b = (ip_b*10) + dial[i]-'0';
- else if (dial[i]=='.' || dial[i]=='*')
- {
- dial[i] = '.';
- i++;
- break;
- }
- else if (dial[i]=='#')
- {
- ip_d = ip_b;
- ip_b = 0;
- set_ip_macro
- i++;
- dial+= i;
- goto address_complete;
- }
- else if (dial[i] == '\0')
- {
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): ip so far: %d.%d*\n", ea_endpoint->ep_serial, ip_a, ip_b);
- return;
- }
- else
- goto invalid;
- i++;
- j++;
- }
- j = 0;
- while(42)
- {
- if (j==4)
- goto invalid;
- if (ip_c > 255)
- goto invalid;
- if (dial[i]>='0' && dial[i]<='9')
- ip_c = (ip_c*10) + dial[i]-'0';
- else if (dial[i]=='.' || dial[i]=='*')
- {
- dial[i] = '.';
- i++;
- break;
- }
- else if (dial[i]=='#')
- {
- ip_d = ip_c;
- ip_c = 0;
- set_ip_macro
- i++;
- dial+= i;
- goto address_complete;
- }
- else if (dial[i] == '\0')
- {
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): ip so far: %d.%d.%d\n", ea_endpoint->ep_serial, ip_a, ip_b, ip_c);
- return;
- }
- else
- goto invalid;
- i++;
- j++;
- }
- j = 0;
- while(42)
- {
- if (j==4)
- goto invalid;
- if (ip_d > 255)
- goto invalid;
- if (dial[i]>='0' && dial[i]<='9')
- ip_d = (ip_d*10) + dial[i]-'0';
- else if (dial[i]=='*' || dial[i]==':')
- {
- set_ip_macro
- dial[i] = ':';
- i++;
- dial+= i;
- goto check_port;
- }
- else if (dial[i]=='#')
- {
- set_ip_macro
- i++;
- dial+= i;
- goto address_complete;
- }
- else if (dial[i] == '\0')
- {
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): ip so far: %d.%d.%d.%d*\n", ea_endpoint->ep_serial, ip_a, ip_b, ip_c, ip_d);
- return;
- }
- else
- goto invalid;
- i++;
- j++;
- }
-
- /* get port */
- check_port:
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): checking dialed for port: %s\n", ea_endpoint->ep_serial, dial);
- port = 0;
- i = 0;
- j = 0;
- while(42)
- {
- if (j==6)
- goto invalid;
- if (port > 65535)
- goto invalid;
- if (dial[i]>='0' && dial[i]<='9')
- port = (port*10) + dial[i]-'0';
- else if (dial[i]=='*' || dial[i]=='/')
- {
- if (i) /* only if there is something entered */
- {
- set_port_macro
- dial[i] = '/';
- } else
- {
- i--;
- UCPY(dial+i, dial+i+1);
- dial[i] = '/';
- }
- i++;
- dial+= i;
- goto check_user;
- }
- else if (dial[i]=='#')
- {
- set_port_macro
- i++;
- dial+= i;
- goto address_complete;
- }
- else if (dial[i] == '\0')
- {
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): h323 address so far: %s\n", ea_endpoint->ep_serial, address);
- return;
- }
- else
- goto invalid;
- i++;
- j++;
- }
-
- /* get user */
- check_user:
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): checking dialed for user: %s\n", ea_endpoint->ep_serial, dial);
- port = 0;
- i = 0;
- j = 0;
- while(42)
- {
- if (dial[i]=='#')
- {
- dial[i] = '\0';
- /* convert to @-notation */
- SCPY(helpbuffer, strchr(address, '/')+1);
- SCAT(helpbuffer, "@");
- *strchr(address, '/') = '\0';
- SCAT(helpbuffer, address);
- UCPY(address, helpbuffer);
- goto address_complete;
- }
- else if (dial[i] == '\0')
- {
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): h323 address so far: %s\n", ea_endpoint->ep_serial, address);
- return;
- }
- i++;
- j++;
- }
-
- address_complete:
- /* send proceeding, because number is complete */
- set_tone(portlist, "proceeding");
- message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
- message_put(message);
- logmessage(message);
- new_state(EPOINT_STATE_IN_PROCEEDING);
-
- memset(&dialinginfo, 0, sizeof(dialinginfo));
- dialinginfo.itype = INFO_ITYPE_H323;
- dialinginfo.sending_complete = 1;
- SPRINT(dialinginfo.number, "%s", address);
- /* strip the # at the end */
- if (dialinginfo.number[0])
- if (dialinginfo.number[strlen(dialinginfo.number)-1] == '#')
- dialinginfo.number[strlen(dialinginfo.number)-1] = '\0';
-
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): complete multi-dial string \"%s\"\n", ea_endpoint->ep_serial, dialinginfo.number);
-
- /* add or update internal call */
- printlog("%3d action H323 call to address %s.\n", ea_endpoint->ep_serial, dialinginfo.number);
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_SETUP);
- memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
- memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
- memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
- memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
- message_put(message);
-}
-#else
-void EndpointAppPBX::action_dialing_h323(void)
-{
- struct port_list *portlist = ea_endpoint->ep_portlist;
-
- printlog("%3d action H323 stack not implemented.\n", ea_endpoint->ep_serial);
- message_disconnect_port(portlist, CAUSE_UNIMPLEMENTED, LOCATION_PRIVATE_LOCAL, "");
- new_state(EPOINT_STATE_OUT_DISCONNECT);
- set_tone(portlist,"cause_4f");
-}
-#endif
-
void EndpointAppPBX::action_dialing_chan(void)
{
struct port_list *portlist = ea_endpoint->ep_portlist;
@@ -1412,9 +986,6 @@ void EndpointAppPBX::_action_redial_reply(int in)
if (!strncmp(last, "intern:", 7))
SPRINT(message->param.notifyinfo.display, "(%d) %s int", e_select+1, last+7);
else
- if (!strncmp(last, "h323:", 5))
- SPRINT(message->param.notifyinfo.display, "(%d) %s h323", e_select+1, last+5);
- else
if (!strncmp(last, "chan:", 4))
SPRINT(message->param.notifyinfo.display, "(%d) %s chan", e_select+1, last+5);
else
@@ -2629,13 +2200,6 @@ void EndpointAppPBX::process_dialing(void)
e_action = &action_internal;
goto process_action;
}
- /* check for h323 call */
- if (!strncmp(e_dialinginfo.number, "h323:", 5))
- {
- e_extdialing = e_dialinginfo.number+5;
- e_action = &action_h323;
- goto process_action;
- }
/* check for chan call */
if (!strncmp(e_dialinginfo.number, "chan:", 5))
{
@@ -2808,9 +2372,6 @@ void EndpointAppPBX::process_hangup(int cause, int location)
PDEBUG(DEBUG_EPOINT, "EPOINT(%d): writing connect from %s to %s into logfile of %s\n", ea_endpoint->ep_serial, e_callerinfo.id, e_dialinginfo.number, e_terminal);
switch(e_dialinginfo.itype)
{
- case INFO_ITYPE_H323:
- SPRINT(dialingtext, "h323:%s", e_dialinginfo.number);
- break;
case INFO_ITYPE_CHAN:
SPRINT(dialingtext, "chan:%s", e_dialinginfo.number);
break;
diff --git a/admin_server.c b/admin_server.c
index c17620b..1d8f400 100644
--- a/admin_server.c
+++ b/admin_server.c
@@ -236,9 +236,6 @@ int admin_route(struct admin_queue **responsep)
case ACTION_EXTERNAL:
apppbx->e_action = &action_external;
break;
- case ACTION_H323:
- apppbx->e_action = &action_h323;
- break;
case ACTION_CHAN:
apppbx->e_action = &action_chan;
break;
diff --git a/apppbx.cpp b/apppbx.cpp
index c00ab69..ba29919 100644
--- a/apppbx.cpp
+++ b/apppbx.cpp
@@ -146,6 +146,94 @@ void EndpointAppPBX::new_state(int state)
}
+/* screen caller id
+ * out==0: incomming caller id, out==1: outgoing caller id
+ */
+void EndpointAppPBX::screen(int out, char *id, int idsize, int *type, int *present)
+{
+ struct interface *interface;
+
+ interface = interface_first;
+ while(interface)
+ {
+ if (!strcmp(e_callerinfo.interface, interface->name))
+ {
+ break;
+ }
+ interface = interface->next;
+ }
+add logging
+ if (interface)
+ {
+ /* screen incoming caller id */
+ if (!out)
+ {
+ /* check for MSN numbers, use first MSN if no match */
+ msn1 = NULL;
+ ifmsn = interface->ifmsn;
+ while(ifmns)
+ {
+ if (!msn1)
+ msn1 = ifmns->msn;
+ if (!strcmp(ifmns->mns, id))
+ {
+ break;
+ }
+ ifmsn = ifmsn->next;
+ }
+ if (!ifmns && mns1) // not in list, first msn given
+ UNCPY(id, msn1, idsize);
+ id[idsize-1] = '\0';
+ }
+
+ /* check screen list */
+ if (out)
+ iscreen = interface->ifscreen_out;
+ else
+ iscreen = interface->ifscreen_in;
+ while (ifscreen)
+ {
+ if (ifcreen->match_type==-1 || ifscreen->match_type==*type)
+ if (ifcreen->match_present==-1 || ifscreen->match_present==*present)
+ {
+ if (strchr(ifcreen->match_id,'%'))
+ {
+ if (!strncmp(ifscreen->match_id, id, strchr(ifscreen->match_id,'%')-ifscreen->match_id))
+ break;
+ } else
+ {
+ if (!strcmp(ifscreen->match_id, id))
+ break;
+ }
+ }
+ ifscreen = ifscreen->next;
+ }
+ if (ifscreen) // match
+ {
+ if (ifscren->result_type != -1)
+ *type = ifscreen->result_type;
+ if (ifscren->result_present != -1)
+ *present = ifscreen->result_present;
+ if (strchr(ifscreen->match_id,'%'))
+ {
+ SCPY(suffix, strchr(ifscreen->match_id,'%') - ifscreen->match_id + id);
+ UNCPY(id, ifscreen->result_id);
+ id[idsize-1] = '\0';
+ if (strchr(ifscreen->result_id,'%'))
+ {
+ *strchr(ifscreen->result_id,'%') = '\0';
+ UNCAT(id, suffix, idsize);
+ id[idsize-1] = '\0';
+ }
+ } else
+ {
+ UNCPY(id, ifscreen->result_id, idsize);
+ id[idsize-1] = '\0';
+ }
+ }
+ }
+}
+
/* release call and port (as specified)
*/
void EndpointAppPBX::release(int release, int calllocation, int callcause, int portlocation, int portcause)
@@ -1138,91 +1226,6 @@ void EndpointAppPBX::out_setup(void)
}
break;
-#ifdef H323
- /* *********************** h323 call */
- case INFO_ITYPE_H323:
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing H323: '%s'\n", ea_endpoint->ep_serial, e_dialinginfo.number);
-
- /* alloc port */
- if (!(port = new H323Port(PORT_TYPE_H323_OUT, "H323-out", &port_settings)))
- {
- PERROR("EPOINT(%d) no mem for port\n", ea_endpoint->ep_serial);
- break;
- }
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d) allocated port %s\n", ea_endpoint->ep_serial, port->p_name);
- memset(&dialinginfo, 0, sizeof(dialinginfo));
- SCPY(dialinginfo.number, e_dialinginfo.number);
- dialinginfo.itype = INFO_ITYPE_H323;
- dialinginfo.ntype = e_dialinginfo.ntype;
- portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, 0);
- if (!portlist)
- {
- PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
- delete port;
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
- return;
- }
-//printf("INTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.number);
- message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
- memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
- memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
- memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
- memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
-//terminal SCPY(message->param.setup.from_terminal, e_terminal);
-//terminal if (e_dialinginfo.number)
-//terminal SCPY(message->param.setup.to_terminal, e_dialinginfo.number);
- /* handle restricted caller ids */
- apply_callerid_restriction(e_ext.anon_ignore, port->p_type, message->param.setup.callerinfo.id, &message->param.setup.callerinfo.ntype, &message->param.setup.callerinfo.present, &message->param.setup.callerinfo.screen, message->param.setup.callerinfo.voip, message->param.setup.callerinfo.intern, message->param.setup.callerinfo.name);
- apply_callerid_restriction(e_ext.anon_ignore, port->p_type, message->param.setup.redirinfo.id, &message->param.setup.redirinfo.ntype, &message->param.setup.redirinfo.present, NULL, message->param.setup.redirinfo.voip, message->param.setup.redirinfo.intern, 0);
- /* display callerid if desired for extension */
- SCPY(message->param.setup.callerinfo.display, apply_callerid_display(message->param.setup.callerinfo.id, message->param.setup.callerinfo.itype, message->param.setup.callerinfo.ntype, message->param.setup.callerinfo.present, message->param.setup.callerinfo.screen, message->param.setup.callerinfo.voip, message->param.setup.callerinfo.intern, message->param.setup.callerinfo.name));
- message_put(message);
- logmessage(message);
- break;
-#endif
-#ifdef SIP
- /* *********************** sip call */
- case INFO_ITYPE_SIP:
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing SIP: '%s'\n", ea_endpoint->ep_serial, e_dialinginfo.number);
-
- /* alloc port */
- if (!(port = new Psip(PORT_TYPE_SIP_OUT, 0, 0, e_dialinginfo.number)))
- {
- PERROR("EPOINT(%d) no mem for port\n", ea_endpoint->ep_serial);
- break;
- }
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d) allocated port %s\n", ea_endpoint->ep_serial, port->p_name);
- memset(&dialinginfo, 0, sizeof(dialinginfo));
- SCPY(dialinginfo.number, e_dialinginfo.number);
- dialinginfo.itype = INFO_ITYPE_SIP;
- dialinginfo.ntype = e_dialinginfo.ntype;
- portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, 0);
- if (!portlist)
- {
- PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
- delete port;
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, call, port */
- return;
- }
-//printf("INTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.number);
- message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP);
- memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
- memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
- memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
- memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
-//terminal SCPY(message->param.setup.from_terminal, e_terminal);
-//terminal if (e_dialinginfo.number)
-//terminal SCPY(message->param.setup.to_terminal, e_dialinginfo.number);
- /* handle restricted caller ids */
- apply_callerid_restriction(e_ext.anon_ignore, port->p_type, message->param.setup.callerinfo.id, &message->param.setup.callerinfo.ntype, &message->param.setup.callerinfo.present, &message->param.setup.callerinfo.screen, message->param.setup.callerinfo.voip, message->param.setup.callerinfo.intern, message->param.setup.callerinfo.name);
- apply_callerid_restriction(e_ext.anon_ignore, port->p_type, message->param.setup.redirinfo.id, &message->param.setup.redirinfo.ntype, &message->param.setup.redirinfo.present, NULL, message->param.setup.redirinfo.voip, message->param.setup.redirinfo.intern, 0);
- /* display callerid if desired for extension */
- SCPY(message->param.setup.callerinfo.display, apply_callerid_display(message->param.setup.callerinfo.id, message->param.setup.callerinfo.itype, message->param.setup.callerinfo.ntype, message->param.setup.callerinfo.present, message->param.setup.callerinfo.screen, message->param.setup.callerinfo.voip, message->param.setup.callerinfo.intern, message->param.setup.callerinfo.name));
- message_put(message);
- logmessage(message);
- break;
-#endif
-
/* *********************** external call */
default:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing external: '%s'\n", ea_endpoint->ep_serial, e_dialinginfo.number);
@@ -1573,7 +1576,6 @@ void EndpointAppPBX::port_setup(struct port_list *portlist, int message_type, un
{
struct message *message;
char buffer[256];
- struct interface *interface;
char extension[32];
char extension1[32];
char *p;
@@ -1587,100 +1589,20 @@ void EndpointAppPBX::port_setup(struct port_list *portlist, int message_type, un
memcpy(&e_capainfo, &param->setup.capainfo, sizeof(e_capainfo));
e_dtmf = param->setup.dtmf;
- /* check where the call is from */
+ /* screen by interface */
if (e_callerinfo.interface[0])
{
- interface = interface_first;
- while(interface)
- {
- if (!strcmp(e_callerinfo.interface, interface->name))
- {
- break;
- }
- interface = interface->next;
- }
- if (interface)
- {
- /* check for MSN numbers, use first MSN if no match */
- msn1 = NULL;
- ifmsn = interface->ifmsn;
- while(ifmns)
- {
- if (!msn1)
- msn1 = ifmns->msn;
- if (!strcmp(ifmns->mns, e_callerinfo.id))
- {
- break;
- }
- ifmsn = ifmsn->next;
- }
- if (!ifmns && mns1) // not in list, first msn given
- SCPY(p_callerinfo.id, msn1);
-
- /* interface is known */
- if (interface->iftype==IF_INTERN)
- {
-
- /* interface is internal */
- if (interface->extensions[0])
- {
- hier denken
- /* extensions are assigned to interface */
- p = interface->extensions;
- extension1[0] = '\0';
- while(*p)
- {
- extension[0] = '\0';
- while(*p!=',' && *p!='\0')
- SCCAT(extension, *p++);
- if (*p == ',')
- p++;
- if (!extension1[0])
- SCPY(extension1, extension);
- if (!strcmp(extension, e_callerinfo.id))
- break;
- extension[0] = '\0'; /* NOTE: empty if we did not find */
- }
- if (extension[0])
- {
- /* id was found at extension's list */
- e_callerinfo.itype = INFO_ITYPE_INTERN;
- SCPY(e_callerinfo.intern, extension);
- } else
- if (extension1[0])
- {
- /* if was provided by default */
- e_callerinfo.itype = INFO_ITYPE_INTERN;
- printlog("%3d endpoint INTERFACE Caller ID '%s' not in list for interface '%s', using first ID '%s'.\n", ea_endpoint->ep_serial, e_callerinfo.id, interface->name, extension1);
- SCPY(e_callerinfo.intern, extension1);
- }
- } else
- {
- /* no extension given, so we use the caller id */
- e_callerinfo.itype = INFO_ITYPE_INTERN;
- SCPY(e_callerinfo.intern, e_callerinfo.id);
- }
- } else
- {
- /* interface is external */
- e_callerinfo.intern[0] = '\0';
- }
- } else
- {
- /* interface is unknown */
- message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
- new_state(EPOINT_STATE_OUT_DISCONNECT);
- set_tone(portlist, "cause_80"); /* pbx cause: extension not authorized */
- e_terminal[0] = '\0'; /* no terminal */
- return;
- }
+ /* screen incoming caller id */
+ screen(0, e_callerinfo.id, sizeof(e_callerinfo.id), &e_callerinfo.ntype, &e_callerinfo.present);
}
+colp, outclip, outcolp
+ /* process extension */
if (e_callerinfo.itype == INFO_ITYPE_INTERN)
{
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming call is internal\n", ea_endpoint->ep_serial);
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming call is extension\n", ea_endpoint->ep_serial);
/* port makes call from extension */
- SCPY(e_callerinfo.id, e_callerinfo.intern);
+ SCPY(e_callerinfo.intern, e_callerinfo.id);
SCPY(e_terminal, e_callerinfo.intern);
SCPY(e_terminal_interface, e_callerinfo.interface);
} else
@@ -1689,7 +1611,7 @@ void EndpointAppPBX::port_setup(struct port_list *portlist, int message_type, un
}
printlog("%3d incoming %s='%s'%s%s%s%s dialing='%s'\n",
ea_endpoint->ep_serial,
- (e_callerinfo.intern[0])?"SETUP from intern":"SETUP from extern",
+ (e_callerinfo.intern[0])?"SETUP from extension":"SETUP from extern",
(e_callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
(e_callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
(e_redirinfo.id[0])?"redirected='":"",
@@ -2204,6 +2126,13 @@ void EndpointAppPBX::port_connect(struct port_list *portlist, int message_type,
e_start = now;
+ /* screen by interface */
+ if (e_callerinfo.interface[0])
+ {
+ /* screen incoming caller id */
+ screen(0, e_connectinfo.id, sizeof(e_connectinfo.id), &e_connectinfo.ntype, &e_connectinfo.present);
+ }
+
/* screen connected name */
if (e_ext.name[0])
SCPY(e_connectinfo.name, e_ext.name);
@@ -2260,18 +2189,6 @@ void EndpointAppPBX::port_connect(struct port_list *portlist, int message_type,
e_connectinfo.present = INFO_PRESENT_ALLOWED;
}
}
- if (portlist->port_type==PORT_TYPE_H323_OUT) /* h323 extension answered */
- {
- SCPY(e_connectinfo.voip, port->p_dialinginfo.number);
- e_connectinfo.present = INFO_PRESENT_ALLOWED;
-// e_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
- }
- if (portlist->port_type==PORT_TYPE_SIP_OUT) /* sip extension answered */
- {
- SCPY(e_connectinfo.voip, port->p_dialinginfo.number);
- e_connectinfo.present = INFO_PRESENT_ALLOWED;
-// e_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
- }
}
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, message_type);
memcpy(&message->param.connectinfo, &e_connectinfo, sizeof(struct connect_info));
@@ -3172,6 +3089,14 @@ void EndpointAppPBX::call_connect(struct port_list *portlist, int message_type,
{
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
memcpy(&message->param, param, sizeof(union parameter));
+ /* screen by interface */
+ if (e_connectinfo.interface[0])
+ {
+ /* screen incoming caller id */
+ screen(1, e_connectinfo.id, sizeof(e_connectinfo.id), &e_connectinfo.ntype, &e_connectinfo.present);
+ }
+ memcpy(&message->param.connnectinfo, e_connectinfo);
+
/* screen clip if prefix is required */
if (e_terminal[0] && message->param.connectinfo.id[0] && e_ext.clip_prefix[0])
{
@@ -3179,19 +3104,23 @@ void EndpointAppPBX::call_connect(struct port_list *portlist, int message_type,
SCAT(message->param.connectinfo.id, numberrize_callerinfo(e_connectinfo.id,e_connectinfo.ntype));
message->param.connectinfo.ntype = INFO_NTYPE_UNKNOWN;
}
+
/* use internal caller id */
if (e_terminal[0] && e_connectinfo.intern[0] && (message->param.connectinfo.present!=INFO_PRESENT_RESTRICTED || e_ext.anon_ignore))
{
SCPY(message->param.connectinfo.id, e_connectinfo.intern);
message->param.connectinfo.ntype = INFO_NTYPE_UNKNOWN;
}
+
/* handle restricted caller ids */
apply_callerid_restriction(e_ext.anon_ignore, portlist->port_type, message->param.connectinfo.id, &message->param.connectinfo.ntype, &message->param.connectinfo.present, &message->param.connectinfo.screen, message->param.connectinfo.voip, message->param.connectinfo.intern, message->param.connectinfo.name);
/* display callerid if desired for extension */
SCPY(message->param.connectinfo.display, apply_callerid_display(message->param.connectinfo.id, message->param.connectinfo.itype, message->param.connectinfo.ntype, message->param.connectinfo.present, message->param.connectinfo.screen, message->param.connectinfo.voip, message->param.connectinfo.intern, message->param.connectinfo.name));
+
/* use conp, if enabld */
if (!e_ext.centrex)
message->param.connectinfo.name[0] = '\0';
+
/* send connect */
message_put(message);
logmessage(message);
@@ -3416,6 +3345,13 @@ void EndpointAppPBX::call_setup(struct port_list *portlist, int message_type, un
memcpy(&e_redirinfo, &param->setup.redirinfo, sizeof(e_redirinfo));
memcpy(&e_capainfo, &param->setup.capainfo, sizeof(e_capainfo));
+ /* screen by interface */
+ if (e_callerinfo.interface[0])
+ {
+ /* screen incoming caller id */
+ screen(1, e_callerinfo.id, sizeof(e_callerinfo.id), &e_callerinfo.ntype, &e_callerinfo.present);
+ }
+
/* process (voice over) data calls */
if (e_ext.datacall && e_capainfo.bearer_capa!=INFO_BC_SPEECH && e_capainfo.bearer_capa!=INFO_BC_AUDIO)
{
@@ -4264,32 +4200,6 @@ void EndpointAppPBX::logmessage(struct message *message)
pdss1->p_m_mISDNport->portnum
);
}
- if (port->p_type == PORT_TYPE_H323_OUT)
- {
- printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to h323='%s'\n",
- ea_endpoint->ep_serial,
- (message->param.setup.callerinfo.intern[0])?"intern":"extern",
- (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
- (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
- (message->param.setup.redirinfo.id[0])?"redirected='":"",
- message->param.setup.redirinfo.id,
- (message->param.setup.redirinfo.id[0])?"'":"",
- message->param.setup.dialinginfo.number
- );
- }
- if (port->p_type == PORT_TYPE_SIP_OUT)
- {
- printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to sip='%s'\n",
- ea_endpoint->ep_serial,
- (message->param.setup.callerinfo.intern[0])?"intern":"extern",
- (message->param.setup.callerinfo.intern[0])?e_callerinfo.intern:e_callerinfo.id,
- (message->param.setup.callerinfo.present==INFO_PRESENT_RESTRICTED)?" anonymous":"",
- (message->param.setup.redirinfo.id[0])?"redirected='":"",
- message->param.setup.redirinfo.id,
- (message->param.setup.redirinfo.id[0])?"'":"",
- message->param.setup.dialinginfo.number
- );
- }
if (port->p_type == PORT_TYPE_VBOX_OUT)
{
printlog("%3d outgoing SETUP from %s='%s'%s%s%s%s to vbox='%s'\n",
diff --git a/callpbx.cpp b/callpbx.cpp
index bb644d0..39dc82b 100644
--- a/callpbx.cpp
+++ b/callpbx.cpp
@@ -255,7 +255,8 @@ CallPBX::CallPBX(class Endpoint *epoint) : Call(epoint)
c_caller_id[0] = '\0';
c_dialed[0] = '\0';
c_todial[0] = '\0';
- c_mixer = 0;
+ c_pid = getpid();
+ c_updatebridge = 0;
c_partyline = 0;
/* initialize a relation only to the calling interface */
@@ -298,23 +299,26 @@ CallPBX::~CallPBX()
}
-/* mixer sets the mixer of hisax bchannels
- * the mixer() will set the mixer for the hisax ports which is done
- * at kernel space.
+/* bridge sets the audio flow of all bchannels assiociated to 'this' call
+ * also it changes and notifies active/hold/conference states
*/
-void CallPBX::mixer(void)
+void CallPBX::bridge(void)
{
struct call_relation *relation;
struct message *message;
- int numconnect, relations;
+ int numconnect = 0, relations = 0;
class Endpoint *epoint;
struct port_list *portlist;
class Port *port;
- int nodata = 1;
+ int allmISDN = 0; // relations that are no mISDN
relation = c_relation;
while(relation)
{
+ /* count all relations */
+ relations++;
+
+ /* check for relation's objects */
epoint = find_epoint_id(relation->epoint_id);
if (!epoint)
{
@@ -325,7 +329,7 @@ void CallPBX::mixer(void)
portlist = epoint->ep_portlist;
if (!portlist)
{
- PDEBUG((DEBUG_CALL|DEBUG_PORT), "ignoring relation without interfaces.\n");
+ PDEBUG((DEBUG_CALL|DEBUG_PORT), "ignoring relation without port object.\n");
//#warning testing: keep on hold until single audio stream available
relation->channel_state = CHANNEL_STATE_HOLD;
relation = relation->next;
@@ -342,38 +346,44 @@ void CallPBX::mixer(void)
port = find_port_id(portlist->port_id);
if (!port)
{
- PDEBUG((DEBUG_CALL|DEBUG_PORT), "software error: relation without existing port.\n");
+ PDEBUG((DEBUG_CALL|DEBUG_PORT), "ignoring relation without existing port object.\n");
relation = relation->next;
continue;
}
- if (port->p_record)
- {
- PDEBUG(DEBUG_CALL|DEBUG_PORT, "mixer(): relation ep%d does recording, so we must get data from all members.\n", epoint->ep_serial);
- if (nodata)
- {
- PDEBUG(DEBUG_CALL|DEBUG_PORT, "mixer(): at least one endpoint wants data.\n");
- nodata = 0;
- }
- }
if ((port->p_type&PORT_CLASS_MASK)!=PORT_CLASS_mISDN)
{
- PDEBUG((DEBUG_CALL|DEBUG_PORT), "ignoring relation ep%d because it is not mISDN.\n", epoint->ep_serial);
- if (nodata)
+ PDEBUG((DEBUG_CALL|DEBUG_PORT), "ignoring relation ep%d because it's port is not mISDN.\n", epoint->ep_serial);
+ if (allmISDN)
{
PDEBUG((DEBUG_CALL|DEBUG_PORT), "not all endpoints are mISDN.\n");
- nodata = 0;
+ allmISDN = 0;
}
relation = relation->next;
continue;
}
-// remove unconnected parties from conference, also remove remotely disconnected parties so conference will not be disturbed.
+ relation = relation->next;
+ }
+
+ /* we notify all relations about rxdata. */
+ relation = c_relation;
+ while(relation)
+ {
+ /* count connected relations */
+ if ((relation->channel_state == CHANNEL_STATE_CONNECT)
+ && (relation->rx_state != NOTIFY_STATE_SUSPEND)
+ && (relation->rx_state != NOTIFY_STATE_HOLD))
+ numconnect ++;
+
+ /* remove unconnected parties from conference, also remove remotely disconnected parties so conference will not be disturbed. */
if (relation->channel_state == CHANNEL_STATE_CONNECT
&& relation->rx_state != NOTIFY_STATE_HOLD
- && relation->rx_state != NOTIFY_STATE_SUSPEND)
+ && relation->rx_state != NOTIFY_STATE_SUSPEND
+ && relations>1 // no conf with on party
+ && allmISDN) // no conf if any member is not mISDN
{
message = message_create(c_serial, relation->epoint_id, CALL_TO_EPOINT, MESSAGE_mISDNSIGNAL);
message->param.mISDNsignal.message = mISDNSIGNAL_CONF;
- message->param.mISDNsignal.conf = (c_serial<<1) + 1;
+ message->param.mISDNsignal.conf = c_serial<<16 | c_pid;
PDEBUG(DEBUG_CALL, "%s +on+ id: 0x%08x\n", port->p_name, message->param.mISDNsignal.conf);
message_put(message);
} else
@@ -384,41 +394,31 @@ void CallPBX::mixer(void)
PDEBUG(DEBUG_CALL, "%s +off+ id: 0x%08x\n", port->p_name, message->param.mISDNsignal.conf);
message_put(message);
}
- relation = relation->next;
- }
- /* we notify all relations about rxdata. */
- relation = c_relation;
- while(relation)
- {
+
+ /*
+ * request data from endpoint/port if:
+ * - two relations
+ * - any without mISDN
+ * in this case we bridge
+ */
message = message_create(c_serial, relation->epoint_id, CALL_TO_EPOINT, MESSAGE_mISDNSIGNAL);
- message->param.mISDNsignal.message = mISDNSIGNAL_NODATA;
- message->param.mISDNsignal.nodata = nodata;
- PDEBUG(DEBUG_CALL, "call %d sets alldata on port %s to %d\n", c_serial, port->p_name, nodata);
+ message->param.mISDNsignal.message = mISDNSIGNAL_CALLDATA;
+ message->param.mISDNsignal.calldata = (relnum==2 && !allmISDN);
+ PDEBUG(DEBUG_CALL, "call %d sets 'calldata' on port %s to %d\n", c_serial, port->p_name, calldata);
message_put(message);
- relation = relation->next;
- }
- /* count relations and states */
- relation = c_relation;
- numconnect = 0;
- relations = 0;
- while(relation) /* count audio-connected and active relations */
- {
- relations ++;
- if ((relation->channel_state == CHANNEL_STATE_CONNECT)
- && (relation->rx_state != NOTIFY_STATE_SUSPEND)
- && (relation->rx_state != NOTIFY_STATE_HOLD))
- numconnect ++;
relation = relation->next;
}
- if (relations==2 && !c_partyline) /* two people just exchange their states */
+ /* two people just exchange their states */
+ if (relations==2 && !c_partyline)
{
relation = c_relation;
relation->tx_state = notify_state_change(c_serial, relation->epoint_id, relation->tx_state, relation->next->rx_state);
relation->next->tx_state = notify_state_change(c_serial, relation->next->epoint_id, relation->next->tx_state, relation->rx_state);
} else
- if ((relations==1 || numconnect==1) /*&& !c_partyline*/) /* one member in a call, so we put her on hold */
+ /* one member in a call, so we put her on hold */
+ if (relations==1 || numconnect==1)
{
relation = c_relation;
while(relation)
@@ -444,52 +444,45 @@ void CallPBX::mixer(void)
}
}
-
-/* send audio data to endpoints which do not come from an endpoint connected
- * to an isdn port and do not go to an endpoint which is connected to an
- * isdn port. in this case the mixing cannot be done with kernel space
+/*
+ * bridging is only possible with two connected endpoints
*/
-void CallPBX::call_mixer(unsigned long epoint_from, struct call_relation *relation_from, union parameter *param)
+void CallPBX::bridge_data(unsigned long epoint_from, struct call_relation *relation_from, union parameter *param)
{
struct call_relation *relation_to;
struct message *message;
+ /* if we are alone */
+ if (!c_relation->next)
+ return;
+
+ /* if we are more than two */
+ if (c_relation->next->next)
+ return;
+
/* skip if source endpoint has NOT audio mode CONNECT */
if (relation_from->channel_state != CHANNEL_STATE_CONNECT)
- {
return;
- }
- /* loop all endpoints and skip the endpoint where the audio is from
- * so we do not get a loop (echo)
- */
+ /* get destination relation */
relation_to = c_relation;
- while(relation_to)
+ if (relation_to == relation_from)
{
- /* skip source endpoint */
- if (relation_to->epoint_id == epoint_from)
- {
- relation_to = relation_to->next;
- continue;
- }
+ /* oops, we are the first, so destination is: */
+ relation_to = relation_to->next;
+ }
- /* skip if destination endpoint has audio mode HOLD */
- if (relation_to->channel_state != CHANNEL_STATE_CONNECT)
- {
- relation_to = relation_to->next;
- continue;
- }
+ /* skip if destomatopm endpoint has NOT audio mode CONNECT */
+ if (relation_to->channel_state != CHANNEL_STATE_CONNECT)
+ return;
- /* now we may send our data to the endpoint where it
- * will be delivered to the port
- */
+ /* now we may send our data to the endpoint where it
+ * will be delivered to the port
+ */
//PDEBUG(DEBUG_CALL, "mixing from %d to %d\n", epoint_from, relation_to->epoint_id);
- message = message_create(c_serial, relation_to->epoint_id, CALL_TO_EPOINT, MESSAGE_DATA);
- memcpy(&message->param, param, sizeof(union parameter));
- message_put(message);
-
- relation_to = relation_to->next;
- }
+ message = message_create(c_serial, relation_to->epoint_id, CALL_TO_EPOINT, MESSAGE_DATA);
+ memcpy(&message->param, param, sizeof(union parameter));
+ message_put(message);
}
@@ -527,11 +520,11 @@ void CallPBX::release(unsigned long epoint_id, int hold, int location, int cause
return;
}
- /* remove from mixer */
+ /* remove from bridge */
if (relation->channel_state != CHANNEL_STATE_HOLD)
{
relation->channel_state = CHANNEL_STATE_HOLD;
- c_mixer = 1; /* update mixer flag */
+ c_updatebridge = 1; /* update bridge flag */
}
/* detach given interface */
@@ -738,7 +731,7 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
if (relation->channel_state != param->channel)
{
relation->channel_state = param->channel;
- c_mixer = 1; /* update mixer flag */
+ c_updatebridge = 1; /* update bridge flag */
if (options.deb & DEBUG_CALL)
callpbx_debug(this, "Call::message_epoint{after setting new channel state}");
}
@@ -758,7 +751,7 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
if (new_state != relation->rx_state)
{
relation->rx_state = new_state;
- c_mixer = 1;
+ c_updatebridge = 1;
if (options.deb & DEBUG_CALL)
callpbx_debug(this, "Call::message_epoint{after setting new rx state}");
}
@@ -782,8 +775,8 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
/* audio data */
case MESSAGE_DATA:
- /* now send audio data to all endpoints connected */
- call_mixer(epoint_id, relation, param);
+ /* now send audio data to the other endpoint */
+ bridge_data(epoint_id, relation, param);
return;
}
@@ -795,7 +788,7 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
message = message_create(c_serial, epoint_id, CALL_TO_EPOINT, MESSAGE_CONNECT);
message->param.setup.partyline = c_partyline;
message_put(message);
- c_mixer = 1; /* update mixer flag */
+ c_updatebridge = 1; /* update bridge flag */
}
if (c_partyline)
{
@@ -807,7 +800,7 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
message->param.disconnectinfo.cause = CAUSE_NORMAL;
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
message_put(message);
-// c_mixer = 1; /* update mixer flag */
+// c_updatebridge = 1; /* update bridge flag */
return;
}
}
@@ -880,11 +873,11 @@ int CallPBX::handler(void)
// int i, j;
// char *p;
- /* the mixer must be updated */
- if (c_mixer)
+ /* the bridge must be updated */
+ if (c_updatebridge)
{
- mixer();
- c_mixer = 0;
+ bridge();
+ c_updatebridge = 0;
return(1);
}
@@ -988,6 +981,6 @@ int CallPBX::out_setup(unsigned long epoint_id, int message_type, union paramete
todo: beim release von einem relation_type_setup muss der cause gesammelt werden, bis keine weitere setup-relation mehr existiert
beim letzten den collected cause senden
-mixer kann ruhig loslegen, das aber dokumentieren
-mixer überdenken: wer sendet, welche töne verfügbar sind, u.s.w
+bridge kann ruhig loslegen, das aber dokumentieren
+bridge überdenken: wer sendet, welche töne verfügbar sind, u.s.w
diff --git a/callpbx.h b/callpbx.h
index a72d171..25e3220 100644
--- a/callpbx.h
+++ b/callpbx.h
@@ -63,13 +63,13 @@ class CallPBX : public Call
char c_dialed[1024]; /* dial string of (all) number(s) */
char c_todial[32]; /* overlap dialing (part not signalled yet) */
- int c_mixer; /* mixer must be updated */
+ int c_updatebridge; /* bridge must be updated */
struct call_relation *c_relation; /* list of endpoints that are related to the call */
int c_partyline; /* if set, call is conference room */
- void mixer(void);
- void call_mixer(unsigned long epoint_from, struct call_relation *relation_from, union parameter *param);
+ void bridge(void);
+ void bridge_data(unsigned long epoint_from, struct call_relation *relation_from, union parameter *param);
void remove_relation(struct call_relation *relation);
struct call_relation *add_relation(void);
int out_setup(unsigned long epoint_id, int message, union parameter *param, char *newnumber);
diff --git a/dss1.cpp b/dss1.cpp
index cbfc822..290ccf4 100644
--- a/dss1.cpp
+++ b/dss1.cpp
@@ -459,6 +459,7 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data)
break;
}
p_callerinfo.isdn_port = p_m_portnum;
+ SCPY(p_callerinfo.interface, p_m_mISDNport->ifport->interface->name);
/* dialing information */
dec_ie_called_pn(setup->CALLED_PN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, (unsigned char *)p_dialinginfo.number, sizeof(p_dialinginfo.number));
dec_ie_keypad(setup->KEYPAD, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)keypad, sizeof(keypad));
@@ -844,8 +845,6 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data)
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
message->param.setup.isdn_port = p_m_portnum;
message->param.setup.port_type = p_type;
- p_callerinfo.isdn_port = p_m_portnum;
- SCPY(p_callerinfo.interface, p_m_mISDNport->ifport->interface->name);;
memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
memcpy(&message->param.setup.redirinfo, &p_redirinfo, sizeof(struct redir_info));
@@ -1162,6 +1161,7 @@ void Pdss1::connect_ind(unsigned long prim, unsigned long dinfo, void *data)
break;
}
p_connectinfo.isdn_port = p_m_portnum;
+ SCPY(p_connectingo.interface, p_m_mISDNport->ifport->interface->name);
#ifdef CENTREX
/* te-mode: CONP (connected name identification presentation) */
if (!p_m_d_ntmode)
@@ -2100,6 +2100,11 @@ void Pdss1::new_state(int state)
*/
int Pdss1::handler(void)
{
+ int ret;
+
+ if ((ret = Port::handler()))
+ return(ret);
+
/* handle destruction */
if (p_m_delete && p_m_d_l3id==0)
{
@@ -2108,7 +2113,7 @@ int Pdss1::handler(void)
return(-1);
}
- return(PmISDN::handler());
+ return(0);
}
diff --git a/extension.c b/extension.c
index 83e3c35..38dfd4d 100644
--- a/extension.c
+++ b/extension.c
@@ -713,24 +713,6 @@ int read_extension(struct extension *ext, char *number)
PDEBUG(DEBUG_CONFIG, "given display_int param unknown: %s\n", param);
}
} else
- if (!strcmp(option,"display_voip"))
- {
- i=0;
- while(ext_yesno[i])
- {
- if (!strcasecmp(param,ext_yesno[i]))
- break;
- i++;
- }
- if (ext_yesno[i])
- {
- ext->display_voip = i;
- PDEBUG(DEBUG_CONFIG, "display voip %s\n", ext_yesno[i]);
- } else
- {
- PDEBUG(DEBUG_CONFIG, "given display_voip param unknown: %s\n", param);
- }
- } else
if (!strcmp(option,"display_fake"))
{
i=0;
@@ -1293,10 +1275,6 @@ int write_extension(struct extension *ext, char *number)
fprintf(fp,"# example: \"200 (int)\"\n");
fprintf(fp,"display_int %s\n\n",(ext->display_int)?"yes":"no");
- fprintf(fp,"# Display H323 caller ids using display override (yes or no)\n");
- fprintf(fp,"# example: \"15551212 jolly@192.168.0.3\"\n");
- fprintf(fp,"display_voip %s\n\n",(ext->display_voip)?"yes":"no");
-
fprintf(fp,"# Display if calls are anonymous using display override (yes or no)\n");
fprintf(fp,"# This makes only sense if the anon-ignore feature is enabled.\n");
fprintf(fp,"# example: \"15551212 anon\"\n");
diff --git a/interface.c b/interface.c
index 520ecbd..e522471 100644
--- a/interface.c
+++ b/interface.c
@@ -510,6 +510,8 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
memuse++;
memset(ifscreen, 0, sizeof(struct interface_screen));
#warning handle unchanged as unchanged!!
+ ifscreen->match_type = -1; /* unchecked */
+ ifscreen->match_present = -1; /* unchecked */
ifscreen->result_type = -1; /* unchanged */
ifscreen->result_present = -1; /* unchanged */
/* tail port */
@@ -554,7 +556,7 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
if (ifscreen->match_present != -1)
{
presenterror:
- SPRINT(interface_error, "Error in %s (line %d): presentation type already set earlier.\n", filename, line, parameter);
+ SPRINT(interface_error, "Error in %s (line %d): presentation type already set earlier.\n", filename, line);
return(-1);
}
ifscreen->match_present = INFO_PRESENT_ALLOWED;
@@ -566,6 +568,15 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
ifscreen->match_present = INFO_PRESENT_RESTRICTED;
} else {
SCPY(ifscreen->match, el);
+ /* check for % at the end */
+ if (strchr(el, '%'))
+ {
+ if (strchr(el, '%') != el+len(el)-1)
+ {
+ SPRINT(interface_error, "Error in %s (line %d): %% joker found, but must at the end.\n", filename, line, parameter);
+ return(-1);
+ }
+ }
break;
}
}
@@ -616,6 +627,15 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i
ifscreen->result_present = INFO_PRESENT_RESTRICTED;
} else {
SCPY(ifscreen->result, el);
+ /* check for % at the end */
+ if (strchr(el, '%'))
+ {
+ if (strchr(el, '%') != el+len(el)-1)
+ {
+ SPRINT(interface_error, "Error in %s (line %d): %% joker found, but must at the end.\n", filename, line, parameter);
+ return(-1);
+ }
+ }
break;
}
}
@@ -716,10 +736,13 @@ struct interface_param interface_param[] = {
"Adds an entry for outgoing calls to the caller ID screen list.\n"
"See 'screen-in' for help."},
+#if 0
+#warning todo: filter, also in the PmISDN object
{"filter", &inter_filter, "<filter> [parameters]",
"Adds/appends a filter. Filters are ordered in transmit direction.\n"
"gain <tx-volume> <rx-volume> - Changes volume (-8 .. 8)\n"
"blowfish <key> - Adds encryption. Key must be 4-56 bytes (8-112 hex characters."},
+#endif
{NULL, NULL, NULL, NULL}
};
diff --git a/mISDN.cpp b/mISDN.cpp
index 40d5204..0226947 100644
--- a/mISDN.cpp
+++ b/mISDN.cpp
@@ -60,15 +60,15 @@ PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_setti
p_m_hold = 0;
p_m_txvol = p_m_rxvol = 0;
p_m_conf = 0;
+ p_m_txdata = 0;
#warning set delay by routing parameter or interface config
p_m_delay = 0;
p_m_echo = 0;
p_m_tone = 0;
p_m_rxoff = 0;
- p_m_txmix = 0;
- p_m_txmix_on = 0;
p_m_nodata = 1; /* may be 1, because call always notifies us */
p_m_dtmf = !options.nodtmf;
+ sollen wir daraus eine interface-option machen?:
p_m_timeout = 0;
p_m_timer = 0;
#warning denke auch an die andere seite. also das setup sollte dies weitertragen
@@ -205,6 +205,11 @@ static void bchannel_activate(struct mISDNport *mISDNport, int i)
}
/* configure dsp features */
+ if (mISDNport->b_port[i]->p_m_txdata)
+ {
+ PDEBUG(DEBUG_BCHANNEL, "during activation, we set txdata to txdata=%d.\n", mISDNport->b_port[i]->p_m_txdata);
+ ph_control(mISDNport->b_addr[i], (mISDNport->b_port[i]->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF);
+ }
if (mISDNport->b_port[i]->p_m_delay)
{
PDEBUG(DEBUG_BCHANNEL, "during activation, we set delay to delay=%d.\n", mISDNport->b_port[i]->p_m_delay);
@@ -241,11 +246,13 @@ static void bchannel_activate(struct mISDNport *mISDNport, int i)
PDEBUG(DEBUG_BCHANNEL, "during activation, we set rxoff to rxoff=%d.\n", mISDNport->b_port[i]->p_m_rxoff);
ph_control(mISDNport->b_addr[i], CMX_RECEIVE_OFF, 0);
}
+#if 0
if (mISDNport->b_port[i]->p_m_txmix)
{
PDEBUG(DEBUG_BCHANNEL, "during activation, we set txmix to txmix=%d.\n", mISDNport->b_port[i]->p_m_txmix);
ph_control(mISDNport->b_addr[i], CMX_MIX_ON, 0);
}
+#endif
if (mISDNport->b_port[i]->p_m_dtmf)
{
PDEBUG(DEBUG_BCHANNEL, "during activation, we set dtmf to dtmf=%d.\n", mISDNport->b_port[i]->p_m_dtmf);
@@ -287,6 +294,11 @@ static void bchannel_deactivate(struct mISDNport *mISDNport, int i)
{
if (mISDNport->b_port[i]->p_m_delay)
{
+ PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset txdata from txdata=%d.\n", mISDNport->b_port[i]->p_m_txdata);
+ ph_control(mISDNport->b_addr[i], CMX_TXDATA_OFF, 0);
+ }
+ if (mISDNport->b_port[i]->p_m_delay)
+ {
PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset delay from delay=%d.\n", mISDNport->b_port[i]->p_m_delay);
ph_control(mISDNport->b_addr[i], CMX_JITTER, 0);
}
@@ -320,11 +332,13 @@ static void bchannel_deactivate(struct mISDNport *mISDNport, int i)
PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset rxoff from rxoff=%d.\n", mISDNport->b_port[i]->p_m_rxoff);
ph_control(mISDNport->b_addr[i], CMX_RECEIVE_ON, 0);
}
+#if 0
if (mISDNport->b_port[i]->p_m_txmix)
{
PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset txmix from txmix=%d.\n", mISDNport->b_port[i]->p_m_txmix);
ph_control(mISDNport->b_addr[i], CMX_MIX_OFF, 0);
}
+#endif
if (mISDNport->b_port[i]->p_m_dtmf)
{
PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset dtmf from dtmf=%d.\n", mISDNport->b_port[i]->p_m_dtmf);
@@ -641,6 +655,7 @@ void PmISDN::bchannel_receive(iframe_t *frm)
if (newlen>0 && (p_tone_fh>=0 || p_tone_fetched || !p_m_nodata || p_m_crypt_msg_loops))
{
//printf("jolly: sending.... %d %d %d %d %d\n", newlen, p_tone_fh, p_tone_fetched, p_m_nodata, p_m_crypt_msg_loops);
+#if 0
if (p_m_txmix_on)
{
p_m_txmix_on -= newlen;
@@ -653,6 +668,7 @@ void PmISDN::bchannel_receive(iframe_t *frm)
ph_control(p_m_b_addr, CMX_MIX_ON, 0);
}
}
+#endif
if (p_m_crypt_msg_loops)
{
/* send pending message */
@@ -667,11 +683,13 @@ void PmISDN::bchannel_receive(iframe_t *frm)
{
p_m_crypt_msg_current = 0;
p_m_crypt_msg_loops--;
+#if 0
// we need to disable rxmix some time after sending the loops...
if (!p_m_crypt_msg_loops && p_m_txmix)
{
p_m_txmix_on = 8000; /* one sec */
}
+#endif
}
}
frm->prim = frm->prim & 0xfffffffc | REQUEST;
@@ -873,6 +891,16 @@ void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union
//if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
break;
+ case mISDNSIGNAL_CALLDATA:
+ if (p_m_calldata != param->mISDNsignal.calldata)
+ {
+ p_m_calldata = param->mISDNsignal.calldata;
+ PDEBUG(DEBUG_BCHANNEL, "we change to calldata=%d.\n", p_m_calldata);
+ auch senden
+ }
+ break;
+
+#if 0
case mISDNSIGNAL_NODATA:
p_m_nodata = param->mISDNsignal.nodata;
if (p_m_txmix == p_m_nodata) /* txmix != !nodata */
@@ -884,6 +912,7 @@ void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union
ph_control(p_m_b_addr, p_m_txmix?CMX_MIX_ON:CMX_MIX_OFF, 0);
}
break;
+#endif
#if 0
case mISDNSIGNAL_RXOFF:
@@ -963,12 +992,14 @@ void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parame
}
p_m_crypt_msg_current = 0; /* reset */
p_m_crypt_msg_loops = 3; /* enable */
+#if 0
/* disable txmix, or we get corrupt data due to audio process */
if (p_m_txmix)
{
PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
ph_control(p_m_b_addr, CMX_MIX_OFF, 0);
}
+#endif
break;
default:
@@ -1017,6 +1048,9 @@ int mISDN_handler(void)
mISDNuser_head_t *hh;
int i;
+ if ((ret = Port::handler()))
+ return(ret);
+
/* the que avoids loopbacks when replying to stack after receiving
* from stack. */
mISDNport = mISDNport_first;
diff --git a/mISDN.h b/mISDN.h
index 20937e4..5aba535 100644
--- a/mISDN.h
+++ b/mISDN.h
@@ -101,8 +101,8 @@ class PmISDN : public Port
int p_m_tone; /* current kernel space tone */
int p_m_rxoff; /* rx from driver is disabled */
int p_m_nodata; /* all parties within a conf are isdn ports, so pure bridging is possible */
- int p_m_txmix; /* mix tx with conference */
- int p_m_txmix_on; /* delay for turning back on after sending a binary message, must be signed */
+// int p_m_txmix; /* mix tx with conference */
+// int p_m_txmix_on; /* delay for turning back on after sending a binary message, must be signed */
int p_m_dtmf; /* dtmf decoding is enabled */
int p_m_crypt; /* encryption is enabled */
diff --git a/main.c b/main.c
index 12e43b8..1a5cb75 100644
--- a/main.c
+++ b/main.c
@@ -49,39 +49,6 @@ pthread_mutex_t mutexd; // debug output mutex
pthread_mutex_t mutexl; // log output mutex
pthread_mutex_t mutexe; // error output mutex
-#ifdef H323
-PMutex mutex_h323; // mutual exclude threads when using OpenH323
-#endif
-
-#ifdef VOIP
-class PBXMain : public PProcess
-{
- PCLASSINFO(PBXMain, PProcess)
- public:
- PBXMain(void);
- ~PBXMain(void);
- void Main();
-};
-
-PCREATE_PROCESS(PBXMain)
-
-PBXMain::PBXMain(void) : PProcess("Jolly", "LinuxPBX", 0, 1, AlphaCode, 1)
-{
-}
-
-PBXMain::~PBXMain(void)
-{
-}
-#endif
-
-#ifdef H323
-H323_ep *h323_ep = NULL;
-#endif
-#ifdef OPAL
-OpalManager *opal_mgr = NULL;
-#endif
-
-
int memuse = 0;
int mmemuse = 0;
int cmemuse = 0;
@@ -277,15 +244,7 @@ int main(int argc, char *argv[])
GET_NOW();
/* show version */
-#ifdef OPAL
- printf("\n** %s Version %s (with OPAL)\n\n", NAME, VERSION_STRING);
-#else
- #ifdef H323
- printf("\n** %s Version %s (with H323)\n\n", NAME, VERSION_STRING);
- #else
printf("\n** %s Version %s\n\n", NAME, VERSION_STRING);
- #endif
-#endif
/* show options */
if (ARGC <= 1)
@@ -485,39 +444,6 @@ int main(int argc, char *argv[])
goto free;
}
-#ifdef OPAL
- /* create OPAL manager */
- opal_mgr = new PBXManager;
- if (!opal_mgr)
- {
- fprintf(stderr, "Unable to create OPAL manager.\n");
- goto free;
- }
- if (opal_mgr->Initialise())
- {
- todo thread kreieren...
- opal_mgr->Main();
- }
-
-#endif
-
-
-#ifdef H323
- // create h323 endpoint and initialize
- h323_ep = new H323_ep();
- if (!h323_ep)
- {
- fprintf(stderr, "Unable to create h323 endpoint.\n");
- goto free;
- }
- if (h323_ep->Init() == FALSE)
- {
- fprintf(stderr, "Unable to init h323 endpoint.\n");
- goto free;
- }
-
-#endif
-
/* read interfaces and open ports */
if (!read_interfaces())
{
@@ -591,10 +517,6 @@ int main(int argc, char *argv[])
while(!quit)
{
/* all loops must be counted from the beginning since nodes might get freed during handler */
-#ifdef H323
- mutex_h323.Wait();
- debug_prefix = 0;
-#endif
all_idle = 1;
/* handle mISDN messages from kernel */
@@ -801,12 +723,6 @@ BUDETECT
GET_NOW();
#endif
-#ifdef H323
- // NOTE: be carefull with this, don't do anything after unlocking except sleeping and locking!
- debug_prefix = "h323";
- mutex_h323.Signal();
-#endif
-
/* did we do nothing? so we wait to give time to other processes */
if (all_idle)
{
@@ -822,7 +738,6 @@ free:
/* set scheduler & priority
- * we must remove realtimeshed, because h323 may lock during exit
*/
if (options.schedule > 1)
{
@@ -840,9 +755,6 @@ free:
}
/* destroy objects */
-#ifdef H323
- mutex_h323.Wait();
-#endif
debug_prefix = "free";
while(port_first)
@@ -880,37 +792,6 @@ free:
PDEBUG(DEBUG_MSG, "freed %d pending messages\n", i);
}
-#ifdef H323
- mutex_h323.Signal();
-#endif
-
-#ifdef OPAL
- /* destroy manager */
- if (opal_mgr)
- {
- todo kill an den main-thread von opal und warten...
- if (options.deb & DEBUG_OPAL)
- printf("->now deleting opal manager\n");
- delete opal_mgr;
- if (options.deb & DEBUG_OPAL)
- printf("->opal manager deleted\n");
- }
-
-#endif
-
-#ifdef H323
- /* destroy endpoint */
- if (h323_ep)
- {
- if (options.deb & DEBUG_H323)
- printf("->now deleting endpoint\n");
- delete h323_ep;
- if (options.deb & DEBUG_H323)
- printf("->endpoint deleted\n");
- }
-
-#endif
-
/* free tones */
if (toneset_first)
free_tones();
diff --git a/main.h b/main.h
index d09239e..2519970 100644
--- a/main.h
+++ b/main.h
@@ -40,8 +40,6 @@ void _printerror(const char *function, int line, const char *fmt, ...);
#define DEBUG_BCHANNEL 0x0008
#define DEBUG_PORT 0x0100
#define DEBUG_ISDN 0x0110
-#define DEBUG_OPAL 0x0120
-#define DEBUG_H323 0x0130
//#define DEBUG_KNOCK 0x0140
#define DEBUG_VBOX 0x0180
#define DEBUG_EPOINT 0x0200
@@ -60,30 +58,17 @@ void _printerror(const char *function, int line, const char *fmt, ...);
*/
#define DEBUG_LOG 0x7fff
-/* audio buffer for mixer and recording.
- * all partys within a call (most time two endpoints) write audio data to the buffer. this is used because
- * the buffer experience jitter. if the buffer is too small, jitter will cause drops and gaps.
- * if the buffer is too large, the delay is large. 768 is a good value to start with.
+/*
+ * transmit interval for tones and announcements (or samples of all kind)
+ *
*/
-#ifdef VOIP
-#warning to be removed soon
-#endif
-#define PORT_BUFFER 768
+#define ISDN_TRANSMIT 128
-/* keep this 0 for minimum delay */
-#ifdef VOIP
-#warning to be removed soon
-#endif
-#define ISDN_PRELOAD 0
-
-/* the jitterlimit specifies the number of samples received too fast, before
- * it recognizes a stalling process.
- * but should NOT be less 256.
+/*
+ * preload transmit buffer to avoid gaps at the beginning due to jitter
+ * keep this 0 for minimum delay
*/
-#ifdef VOIP
-#warning to be removed soon
-#endif
-#define ISDN_JITTERLIMIT 512 /* maximum samples received before dropping */
+#define ISDN_PRELOAD 0
/* give sendmail program. if not inside $PATH, give absolute path here (e.g. "/usr/sbin/sendmail")
*/
@@ -118,28 +103,6 @@ void _printerror(const char *function, int line, const char *fmt, ...);
#define BUDETECT ;
#endif
-#ifdef H323
-#define VOIP
-#ifdef OPAL
-#error It is not allowed to use H323 and OPAL. Please disable H323, because it is included in OPAL.
-#endif
-#endif
-#ifdef OPAL
-#define VOIP
-#endif
-
-#ifdef H323INCLUDE
-#define NO_VIDEO_CAPTURE
-//#include <vector>
-//#include <string>
-#include <ptlib.h>
-#include <h225.h>
-#include <h323.h>
-#include <h323pdu.h>
-#include <h323caps.h>
-#include <q931.h>
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -158,7 +121,6 @@ extern "C" {
#include "save.h"
#include "options.h"
#include "interface.h"
-#include "h323conf.h"
#include "extension.h"
#include "message.h"
#include "endpoint.h"
@@ -168,12 +130,6 @@ extern "C" {
#include "port.h"
#include "mISDN.h"
#include "dss1.h"
-#ifdef H323
-#include "h323.h"
-#endif
-#ifdef OPAL
-#include "opal.h"
-#endif
#include "vbox.h"
#include "call.h"
#include "callpbx.h"
@@ -191,12 +147,4 @@ extern struct timeval now_tv;
extern struct timezone now_tz;
-#ifdef H323INCLUDE
-#include "h323_ep.h"
-#include "h323_con.h"
-#include "h323_chan.h"
-
-extern PMutex mutex_h323; // mutual exclude for synchroniszing threads
-extern H323_ep *h323_ep;
-#endif
diff --git a/message.c b/message.c
index 97c032c..0e4fd67 100644
--- a/message.c
+++ b/message.c
@@ -19,10 +19,6 @@ MESSAGES
struct message *message_first = NULL;
struct message **messagepointer_end = &message_first;
-//#ifdef H323
-//PMutex mutex_message;
-//#endif
-
/* creates a new message with the given attributes. the message must be filled then. after filling, the message_put must be called */
struct message *message_create(int id_from, int id_to, int flow, int type)
{
@@ -60,11 +56,6 @@ struct message *message_create(int id_from, int id_to, int flow, int type)
/* attaches a message to the end of the message chain */
void message_put(struct message *message)
{
- /* the mutex prevents from creating two messages at a time (h323 thread and main thread). */
-//#ifdef H323
-// mutex_message.Wait();
-//#endif
-
if (message->id_to == 0)
{
PDEBUG(DEBUG_MSG, "message %s not written, because destination is 0.\n", messages_txt[message->type]);
@@ -77,10 +68,6 @@ void message_put(struct message *message)
*messagepointer_end = message;
messagepointer_end = &(message->next);
-
-//#ifdef H323
-// mutex_message.Signal();
-//#endif
}
@@ -89,16 +76,8 @@ struct message *message_get(void)
{
struct message *message;
- /* the mutex prevents from getting a message while creating a messages at a time (h323 thread and main thread). */
-//#ifdef H323
-// mutex_message.Wait();
-//#endif
-
if (!message_first)
{
-//#ifdef H323
-// mutex_message.Signal();
-//#endif
return(0);
}
@@ -107,10 +86,6 @@ struct message *message_get(void)
if (!message_first)
messagepointer_end = &message_first;
-//#ifdef H323
-// mutex_message.Signal();
-//#endif
-
if ((options.deb&DEBUG_MSG) && message->type != MESSAGE_DATA)
PDEBUG(DEBUG_MSG, "message %s reading from %ld to %ld (memory %x)\n", messages_txt[message->type], message->id_from, message->id_to, message);
diff --git a/message.h b/message.h
index e95e8e7..ce1bb76 100644
--- a/message.h
+++ b/message.h
@@ -120,7 +120,7 @@ enum { /* diversion types */
enum { /* isdnsignal */
mISDNSIGNAL_VOLUME,
mISDNSIGNAL_CONF,
- mISDNSIGNAL_NODATA, /* no data required */
+ mISDNSIGNAL_CALLDATA, /* data required by call instance */
mISDNSIGNAL_ECHO,
};
@@ -151,7 +151,7 @@ struct dialing_info {
struct connect_info {
char id[32]; /* id of caller (user number) */
char voip[64]; /* URI of voip (or gateway) */
- char intern[32]; /* internal id */
+ char extension[32]; /* internal id */
char name[16];
int isdn_port; /* internal/external port (if call is isdn) */
char interfaces[128]; /* interfaces for extenal calls */
@@ -241,7 +241,6 @@ struct park_info {
struct param_data {
unsigned char data[512]; /* audio/hdlc data */
int len; /* audio/hdlc data */
- int compressed; /* 0 for law-data, 1 for 16-bit data */
unsigned long port_id; /* to identify the source of this data */
int port_type; /* type of the source's port */
};
@@ -266,7 +265,7 @@ struct param_mISDNsignal {
int rxvol;
int txvol;
int conf;
- int nodata;
+ int calldata;
int tone;
int echo;
};
diff --git a/options.c b/options.c
index bd4e002..a69dd61 100644
--- a/options.c
+++ b/options.c
@@ -31,12 +31,6 @@ struct options options = {
"tones_american", /* directory of tones */
"", /* directories of tones to fetch */
"extensions", /* directory of extensions */
- "", /* h323 endpoint name */
- 0, /* h323 ringconnect */
- 0,4, 0,2, 0, 0, 0, 0,4, 0,4, 0,64, /* h323 codecs to use */
- 0,"",1720, /* allow incoming h323 calls */
- 0,"", /* register with h323 gatekeeper */
- 5060, 5, /* SIP port, maxqueue */
0, /* dtmf detection on */
"", /* dummy caller id */
0, /* use tones by dsp.o */
@@ -57,9 +51,6 @@ int read_options(void)
char param[256];
unsigned int line,i;
char buffer[256];
-#ifdef H323
- int codecpri = 0;
-#endif
SPRINT(filename, "%s/options.conf", INSTALL_DATA);
@@ -189,168 +180,6 @@ int read_options(void)
PDEBUG(DEBUG_CONFIG, "isdn audio type: ulaw\n");
} else
- if (!strcmp(option,"h323_name"))
- {
-#ifdef H323
- SCPY(options.h323_name, param);
-
- PDEBUG(DEBUG_CONFIG, "H323 endpoint name: '%s'\n", param);
-#endif
- } else
- if (!strcmp(option,"h323_ringconnect"))
- {
-#ifdef H323
- options.h323_ringconnect = 1;
-
- PDEBUG(DEBUG_CONFIG, "H323 ringconnect: enabled\n");
-#endif
- } else
- if (!strcmp(option,"h323_gsm"))
- {
-#ifdef H323
- codecpri ++;
- options.h323_gsm_pri = codecpri;
- options.h323_gsm_opt = atoi(param);
- if (atoi(param)<1 && atoi(param)>7)
- {
- PERROR_RUNTIME("Error in %s (line %d): parameter for option %s must be in range 1..7.\n",filename,line,option);
- goto error;
- }
-
- PDEBUG(DEBUG_CONFIG, "H323 codec to use: GSM, MicrosoftGSM priority %d\n", codecpri);
-#endif
- } else
- if (!strcmp(option,"h323_g726"))
- {
-#ifdef H323
- codecpri ++;
- options.h323_g726_pri = codecpri;
- options.h323_g726_opt = atoi(param);
- if (atoi(param)<2 && atoi(param)>5)
- {
- PERROR_RUNTIME("Error in %s (line %d): parameter for option %s must be in range 2..5.\n",filename,line,option);
- goto error;
- }
-
- PDEBUG(DEBUG_CONFIG, "H323 codec to use: G726 priority %d\n", codecpri);
-#endif
- } else
- if (!strcmp(option,"h323_g7231"))
- {
-#ifdef H323
- codecpri ++;
- options.h323_g7231_pri = codecpri;
-
- PDEBUG(DEBUG_CONFIG, "H323 codec to use: G7231 priority %d\n", codecpri);
-#endif
- } else
- if (!strcmp(option,"h323_g729a"))
- {
-#ifdef H323
- codecpri ++;
- options.h323_g729a_pri = codecpri;
-
- PDEBUG(DEBUG_CONFIG, "H323 codec to use: G729A priority %d\n", codecpri);
-#endif
- } else
- if (!strcmp(option,"h323_lpc10"))
- {
-#ifdef H323
- codecpri ++;
- options.h323_lpc10_pri = codecpri;
-
- PDEBUG(DEBUG_CONFIG, "H323 codec to use: LPC-10 priority %d\n", codecpri);
-#endif
- } else
- if (!strcmp(option,"h323_speex"))
- {
-#ifdef H323
- codecpri ++;
- options.h323_speex_pri = codecpri;
- options.h323_speex_opt = atoi(param);
- if (atoi(param)<2 && atoi(param)>6)
- {
- PERROR_RUNTIME("Error in %s (line %d): parameter for option %s must be in range 2..6.\n",filename,line,option);
- goto error;
- }
-
- PDEBUG(DEBUG_CONFIG, "H323 codec to use: Speex priority %d\n", codecpri);
-#endif
- } else
- if (!strcmp(option,"h323_xspeex"))
- {
-#ifdef H323
- codecpri ++;
- options.h323_xspeex_pri = codecpri;
- options.h323_xspeex_opt = atoi(param);
- if (atoi(param)<2 && atoi(param)>6)
- {
- PERROR_RUNTIME("Error in %s (line %d): parameter for option %s must be in range 2..6.\n",filename,line,option);
- goto error;
- }
-
- PDEBUG(DEBUG_CONFIG, "H323 codec to use: XiphSpeex priority %d\n", codecpri);
-#endif
- } else
- if (!strcmp(option,"h323_law"))
- {
-#ifdef H323
- codecpri ++;
- options.h323_law_pri = codecpri;
- options.h323_law_opt = atoi(param);
- if (atoi(param)<10 && atoi(param)>240)
- {
- PERROR_RUNTIME("Error in %s (line %d): parameter for option %s must be in range 10..240.\n",filename,line,option);
- goto error;
- }
-
- PDEBUG(DEBUG_CONFIG, "H323 codec to use: Alaw, muLaw priority %d\n", codecpri);
-#endif
- } else
- if (!strcmp(option,"h323_icall"))
- {
-#ifdef H323
- options.h323_icall = 1;
- SCPY(options.h323_icall_prefix, param);
-
- PDEBUG(DEBUG_CONFIG, "process incoming H323 call with prefix '%s'\n", param);
-#endif
- } else
- if (!strcmp(option,"h323_port"))
- {
-#ifdef H323
- options.h323_port = atoi(param);
-
- PDEBUG(DEBUG_CONFIG, "use port for incoming H323 calls: %d\n", atoi(param));
-#endif
- } else
- if (!strcmp(option,"sip_port"))
- {
-#ifdef SIP
- options.sip_port = atoi(param);
-
- PDEBUG(DEBUG_CONFIG, "use port for incoming SIP calls: %d\n", atoi(param));
-#endif
- } else
- if (!strcmp(option,"sip_maxqueue"))
- {
-#ifdef SIP
- options.sip_maxqueue = atoi(param);
-
- PDEBUG(DEBUG_CONFIG, "number of simultanious incoming sockets for SIP calls: %d\n", atoi(param));
-#endif
- } else
- if (!strcmp(option,"h323_gatekeeper"))
- {
-#ifdef H323
- options.h323_gatekeeper = 1;
- if (param[0])
- {
- SCPY(options.h323_gatekeeper_host, param);
- }
- PDEBUG(DEBUG_CONFIG, "register with H323 gatekeeper (%s)\n", (param[0])?param:"automatically");
-#endif
- } else
if (!strcmp(option,"tones_dir"))
{
if (param[0]==0)
diff --git a/options.h b/options.h
index 90270c6..ecf7e3c 100644
--- a/options.h
+++ b/options.h
@@ -22,28 +22,6 @@ struct options {
char tones_dir[64]; /* directory of all tones/patterns */
char fetch_tones[256]; /* directories of tones to fetch */
char extensions_dir[64]; /* directory of extensions */
- char h323_name[128]; /* the name of h323 endpoint */
- int h323_ringconnect; /* connected when ringing */
- int h323_gsm_pri; /* priority to use of GSM codec (0 == don't use) */
- int h323_gsm_opt;
- int h323_g726_pri; /* priority to use of G726 codec (0 == don't use) */
- int h323_g726_opt;
- int h323_g7231_pri; /* priority to use of G7231 codec (0 == don't use) */
- int h323_g729a_pri; /* priority to use of G729a codec (0 == don't use) */
- int h323_lpc10_pri; /* priority to use of lpc-10 codec (0 == don't use) */
- int h323_speex_pri; /* priority to use of speex codec (0 == don't use) */
- int h323_speex_opt;
- int h323_xspeex_pri; /* priority to use of xspeex codec (0 == don't use) */
- int h323_xspeex_opt;
- int h323_law_pri; /* priority to use of law codec (0 == don't use) */
- int h323_law_opt;
- int h323_icall; /* allow incoming h323 calls */
- char h323_icall_prefix[32]; /* the prefix */
- int h323_port; /* port for incoming calls */
- int h323_gatekeeper; /* register with h323 gatekeeper */
- char h323_gatekeeper_host[128];/* the gatekeeper host */
- int sip_port;
- int sip_maxqueue;
int nodtmf; /* use dtmf detection */
char dummyid[32]; /* caller id for external calls if not available */
int dsptones; /* tones will be generated via dsp.o 1=american 2=ger */
diff --git a/port.cpp b/port.cpp
index a68ca59..a3a33c8 100644
--- a/port.cpp
+++ b/port.cpp
@@ -141,6 +141,7 @@ Port::Port(int type, char *portname, struct port_settings *settings)
}
SCPY(p_name, portname);
SCPY(p_tone_dir, p_settings.tones_dir); // just to be sure
+ p_clock = 0;
p_type = type;
p_serial = port_serial++;
p_debug_nothingtosend = 0;
@@ -262,25 +263,6 @@ void Port::new_state(int state)
/*
- * find the port using h323 token
- */
-class Port *find_port_with_token(char *name)
-{
- class Port *port = port_first;
-
- while(port)
- {
-//printf("comparing: '%s' with '%s'\n", name, p_name);
- if ((port->p_type==PORT_TYPE_H323_IN || port->p_type==PORT_TYPE_H323_OUT) && !strcmp(port->p_name, name))
- return(port);
- port = port->next;
- }
-
- return(NULL);
-}
-
-
-/*
* find the port with port_id
*/
class Port *find_port_id(unsigned long port_id)
@@ -298,47 +280,6 @@ class Port *find_port_id(unsigned long port_id)
return(NULL);
}
-#if 0
-/*
- * open the knock sound
- */
-void Port::set_knock(char *tones_dir_epoint)
-{
- char filename[128], *tones_dir;
-
- /* check if we have the epoint override the tones_dir of options.conf */
- tones_dir = options.tones_dir;
- if (tones_dir_epoint[0])
- {
- tones_dir = tones_dir_epoint;
- }
-
- if (p_knock_fh >= 0)
- {
- close(p_knock_fh);
- p_knock_fh = -1;
- fhuse--;
- }
- p_knock_fetched = NULL;
-
- if ((p_knock_fetched=open_tone_fetched(tones_dir, "knock", &p_knock_codec, &p_knock_size, &p_knock_left)))
- {
- PDEBUG(DEBUG_PORT, "PORT(%s) opening fetched tone: %s\n", p_name, "knock");
- return;
- }
-
- SPRINT(filename, "%s/%s/knock", INSTALL_DATA, tones_dir);
- if ((p_knock_fh=open_tone(filename, &p_knock_codec, &p_knock_size, &p_knock_left)) >= 0)
- {
- PDEBUG(DEBUG_PORT, "PORT(%s) opening tone: %s\n", p_name, filename);
- fhuse++;
- } else
- {
- p_knock_fh = -1;
- }
-}
-#endif
-
/*
* set echotest
@@ -348,6 +289,7 @@ void Port::set_echotest(int echotest)
p_echotest = echotest;
}
+
/*
* set the file in the tone directory with the given name
*/
@@ -359,15 +301,6 @@ void Port::set_tone(char *dir, char *name)
if (name == NULL)
name = "";
-#if 0
- /* knocking ? */
- if (!strcmp(name, "knock"))
- {
- set_knock(tones_dir_epoint);
- return;
- }
-#endif
-
/* no counter, no eof, normal speed */
p_tone_counter = 0;
p_tone_eof = 0;
@@ -518,45 +451,6 @@ void Port::set_vbox_play(char *name, int offset)
/* seek */
if (p_tone_name[0])
{
-//printf("\n\n\n tone_codec = %d\n\n\n\n",p_tone_codec);
-#if 0
- switch(p_tone_codec)
- {
- case CODEC_LAW:
- case CODEC_8BIT:
- lseek(p_tone_fh, offset*8000L, SEEK_SET);
- size = p_tone_size / 8000L;
- if (offset*8000L <= p_tone_left)
- p_tone_left -= offset*8000L;
- break;
-
- case CODEC_MONO:
- lseek(p_tone_fh, offset*16000L, SEEK_SET);
- size = p_tone_size / 16000L;
- if (offset*16000L <= p_tone_left)
- p_tone_left -= offset*16000L;
-//printf("\n\n\n size = %d\n\n\n\n",size);
- break;
-
- case CODEC_STEREO:
- lseek(p_tone_fh, offset*32000L, SEEK_SET);
- size = p_tone_size / 32000L;
- if (offset*32000L <= p_tone_left)
- p_tone_left -= offset*32000L;
- break;
-
- default:
- PERROR("no codec specified! exitting...\n");
- exit(-1);
- }
-#else
- lseek(p_tone_fh, offset*8000L, SEEK_SET);
- size = p_tone_size / 8000L;
- if (offset*8000L <= p_tone_left)
- p_tone_left -= offset*8000L;
-#endif
-
-
/* send message with counter value */
if (p_tone_size>=0 && ACTIVE_EPOINT(p_epointlist))
{
@@ -578,274 +472,30 @@ void Port::set_vbox_speed(int speed)
p_tone_speed = speed;
}
-/* write data to port's mixer buffer
- * it will be read by the port using read_audio
- * synchronisation is also done when writing is too fast and buffer is full
- * the mixer buffer will only mix what cannot be mixed by kernel mixer
- *
- * also write data to the record buffer. the record buffer will mix everything.
- */
-void Port::mixer(union parameter *param)
-{
- struct mixer_relation *relation, **relationpointer;
- int len;
- unsigned char *data;
- signed short *data_16;
- int writep;
- signed long *buffer, *record;
- int must_mix = 1; /* set, if we need to mix (not done by kernel) */
-
- /* we do not mix if we have audio from ourself but we need to record
- * unless we have a local echo enabled
- */
- if (param->data.port_id==p_serial && !p_echotest)
- must_mix = 0;
-
- if ((param->data.port_type&PORT_CLASS_MASK)==PORT_CLASS_mISDN
- && (p_type&PORT_CLASS_MASK)==PORT_CLASS_mISDN)
- {
- must_mix = 0;
- }
- if (!p_record && !must_mix) /* if we do not record AND no need to mix */
- {
- return;
- }
-
- /* get the relation to the write pointer. if no relation exists
- * for the given source port, we create one.
- */
- relation = p_mixer_rel;
- relationpointer = &(p_mixer_rel);
- if (!relation) /* there is no relation at all */
- {
- /* clear buffer to 0-volume and reset writep */
- memset(p_mixer_buffer, 0, sizeof(p_mixer_buffer));
- memset(p_record_buffer, 0, sizeof(p_record_buffer));
- memset(p_stereo_buffer, 0, sizeof(p_stereo_buffer));
- } else /* else because we do not need to run a 0-loop */
- while(relation)
- {
- if (relation->port_id == param->data.port_id)
- break;
- relationpointer = &(relation->next);
- relation = relation->next;
- }
- if (!relation)
- {
- relation = *relationpointer = (struct mixer_relation *)calloc(1, sizeof(struct mixer_relation));
- if (!relation)
- {
- PERROR("fatal error: cannot alloc memory for port mixer relation\n");
- return; /* no mem */
- }
- pmemuse++;
- memset(relation, 0, sizeof(struct mixer_relation));
- relation->port_id = param->data.port_id;
- /* put write buffer in front of read buffer */
-#ifndef BETTERDELAY
- relation->mixer_writep = (p_mixer_readp+(PORT_BUFFER/2))%PORT_BUFFER;
-#else
- relation->mixer_writep = p_mixer_readp;
-#endif
-#ifdef MIXER_DEBUG
- PDEBUG(DEBUG_PORT, "PORT(%s) Adding new mixer relation from port #%d (readp=%d, writep=%d, PORT_BUFFER=%d).\n", p_name, param->data.port_id, p_mixer_readp, relation->mixer_writep, PORT_BUFFER);
-#endif
- }
-
- /* adding remote's audio data to our mixer_buffer / record_buffer */
- len = param->data.len;
- if (param->data.compressed == 0) /* in case of 16 bit data */
- len >>= 1;
- if (len>PORT_BUFFER)
- PERROR("fatal error: audio data from remote port #%d is larger than mixer buffer %d>%d\n", param->data.port_id, len, PORT_BUFFER);
- writep = relation->mixer_writep;
- buffer = p_mixer_buffer;
- record = p_record_buffer;
- /* if stereo should be recorded */
- if (param->data.port_id == p_serial)
- if (p_record_type == CODEC_STEREO)
- record = p_stereo_buffer;
- /* NOTE: if read and write pointer are equal, the buffer is full */
- if ((p_mixer_readp-writep+PORT_BUFFER)%PORT_BUFFER < len) /* we would overrun the read pointer */
- {
-#ifdef MIXER_DEBUG
- PERROR("PORT(%s) buffer overrun, source port #%d is sending too fast. (dropping %d samples)\n", p_name, param->data.port_id, len);
-#endif
- // we do not resync since dropping causes slowing writepointer down anyway...
- //relation->mixer_writep = (p_mixer_readp+(PORT_BUFFER/2))%PORT_BUFFER;
- return;
- }
-
- if (!p_record && must_mix)
- {
- /* WE MUST MIX BUT DO NOT RECORD */
- if (param->data.compressed)
- {
- /* compressed data */
- data = param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- buffer[writep++] += audio_law_to_s32[*(data++)];
- writep = 0;
- }
- while(len--) /* write rest */
- buffer[writep++] += audio_law_to_s32[*(data++)];
- } else
- {
- /* uncompressed data */
- data_16 = (signed short *)param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- buffer[writep++] += *(data_16++);
- writep = 0;
- }
- while(len--) /* write rest */
- buffer[writep++] += *(data_16++);
- }
- } else /* else */
- if (p_record && !must_mix)
- {
- /* WE MUST RECORD BUT DO NOT MIX */
- if (param->data.compressed)
- {
- /* compressed data */
- data = param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- record[writep++] += audio_law_to_s32[*(data++)];
- writep = 0;
- }
- while(len--) /* write rest */
- record[writep++] += audio_law_to_s32[*(data++)];
- } else
- {
- /* uncompressed data */
- data_16 = (signed short *)param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- record[writep++] += *(data_16++);
- writep = 0;
- }
- while(len--) /* write rest */
- record[writep++] += *(data_16++);
- }
- } else
- {
- /* WE MUST MIX AND MUST RECORD */
- if (param->data.compressed)
- {
- /* compressed data */
- data = param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- {
- buffer[writep] += audio_law_to_s32[*data];
- record[writep++] += audio_law_to_s32[*(data++)];
- }
- writep = 0;
- }
- while(len--) /* write rest */
- {
- buffer[writep] += audio_law_to_s32[*data];
- record[writep++] += audio_law_to_s32[*(data++)];
- }
- } else
- {
- /* uncompressed data */
- data_16 = (signed short *)param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- {
- buffer[writep] += *data_16;
- record[writep++] += *(data_16++);
- }
- writep = 0;
- }
- while(len--) /* write rest */
- {
- buffer[writep] += *data_16;
- record[writep++] += *(data_16++);
- }
- }
- }
- relation->mixer_writep = writep; /* new write pointer */
-// PDEBUG(DEBUG_PORT "written data len=%d port=%d (readp=%d, writep=%d, PORT_BUFFER=%d).\n", param->data.len, param->data.port_id, p_mixer_readp, relation->mixer_writep, PORT_BUFFER);
-}
-
-
/*
* read from the given file as specified in port_set_tone and return sample data
- * this data is mixed with the user space mixer (if anything mixed) and
- * filled into the buffer as many as given by length.
- * if compressed is true, the result in buffer is alaw/ulaw-compressed
- * otherwhise it is 16 bit audio. in this case the buffer size must be twice the lenght.
- * the length is the number of samples, not bytes in buffer!
*/
-int Port::read_audio(unsigned char *buffer, int length, int compressed)
+int Port::read_audio(unsigned char *buffer, int length)
{
int l,len;
- unsigned short temp_buffer[PORT_BUFFER]; /* buffer for up to 32 bit of data */
- int codec_in; /* current codec to use */
- unsigned char *buf_in8; /* buffer pointer for alaw/ulaw/8bit data */
- signed short *buf_in16; /* buffer pointer for alaw/ulaw/8bit data */
- signed short *buf_out16; /* buffer pointer for outgoing audio data */
- signed long *mix_buffer, *mix_buffer2, sample; /* pointer to mixer buffer */
- struct mixer_relation *relation, **relationpointer;
int readp;
- int nodata=0; /* to detect 0-length files */
+ int nodata=0; /* to detect 0-length files and avoid endless reopen */
char filename[128];
- signed short record_buffer[PORT_BUFFER<<1], *rec_buffer; /* buffer of recorded part which will be written (*2 for stereo) */
- unsigned char *rec8_buffer; /* used to send 8-bit audio (wave-8bit, law) */
int tone_left_before; /* temp variable to determine the change in p_tone_left */
/* nothing */
if (length == 0)
return(0);
- /* just in case, we get too much to do */
- if (length > PORT_BUFFER-1)
- length = PORT_BUFFER-1;
-
len = length;
- buf_in8 = (unsigned char *)temp_buffer;
- buf_in16 = (signed short *)temp_buffer;
-
codec_in = p_tone_codec;
/* if there is no tone set, use silence */
if (p_tone_name[0] == 0)
{
- codec_in = CODEC_LAW;
rest_is_silence:
- switch(codec_in)
- {
- case CODEC_LAW:
- memset(buf_in8, (options.law=='a')?0x2a:0xff, len); /* silence */
- break;
-
- case CODEC_MONO:
- case CODEC_8BIT:
- case CODEC_STEREO:
- memset(buf_in16, 0, len<<1); /* silence */
- break;
-
- default:
- PERROR("Software error: no codec during silence\n");
- exit(-1);
- }
- goto mix_to_buffer;
+ memset(buffer, (options.law=='a')?0x2a:0xff, len); /* silence */
+ goto done;
}
/* if the file pointer is not open, we open it */
@@ -877,8 +527,6 @@ rest_is_silence:
}
fhuse++;
}
- codec_in = p_tone_codec;
-//printf("\n\ncodec=%d\n\n\n", p_tone_codec);
PDEBUG(DEBUG_PORT, "PORT(%s) opening %stone: %s\n", p_name, p_tone_fetched?"fetched ":"", filename);
}
@@ -887,69 +535,19 @@ read_more:
tone_left_before = p_tone_left;
if (p_tone_fh >= 0)
{
- switch(codec_in)
- {
- case CODEC_LAW:
- l = read_tone(p_tone_fh, buf_in8, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in8 += l;
- len -= l;
- break;
-
- case CODEC_8BIT:
- l = read_tone(p_tone_fh, buf_in16, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in16 += l;
- len -= l;
- break;
-
- case CODEC_MONO:
- l = read_tone(p_tone_fh, buf_in16, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in16 += l;
- len -= l;
- break;
-
- case CODEC_STEREO:
- l = read_tone(p_tone_fh, buf_in16, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in16 += l;
- len -= l;
- break;
-
- default:
- PERROR("Software error: current tone reading has no codec\n");
- exit(-1);
- }
+ l = read_tone(p_tone_fh, buffer, p_tone_codec, len, p_tone_size, &p_tone_left, p_tone_speed);
+ if (l<0 || l>len) /* paranoia */
+ l=0;
+ buffer += l;
+ len -= l;
}
if (p_tone_fetched)
{
- switch(codec_in)
- {
- case CODEC_LAW:
- l = read_tone_fetched(&p_tone_fetched, buf_in8, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in8 += l;
- len -= l;
- break;
-
- case CODEC_MONO:
- l = read_tone_fetched(&p_tone_fetched, buf_in16, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in16 += l;
- len -= l;
- break;
-
- default:
- PERROR("Software error: current tone reading has no codec\n");
- exit(-1);
- }
+ l = read_tone_fetched(&p_tone_fetched, buffer, len, p_tone_size, &p_tone_left, p_tone_speed);
+ if (l<0 || l>len) /* paranoia */
+ l=0;
+ buffer += l;
+ len -= l;
}
/* if counter is enabled, we check if we have a change */
@@ -968,7 +566,7 @@ read_more:
}
if (len==0)
- goto mix_to_buffer;
+ goto done;
if (p_tone_fh >= 0)
{
@@ -1031,690 +629,23 @@ try_loop:
}
fhuse++;
}
- codec_in = p_tone_codec;
nodata++;
PDEBUG(DEBUG_PORT, "PORT(%s) opening %stone: %s\n", p_name, p_tone_fetched?"fetched ":"", filename);
/* now we have opened the loop */
goto read_more;
- /* **********
- * now we mix
- * we take the buffer content and mix the mixer_buffer to what we got
- */
-mix_to_buffer:
- /* release all writepointer which will underrun, since writing of
- * remote port data is too slow
- */
- relation = p_mixer_rel;
- readp = p_mixer_readp;
- relationpointer = &(p_mixer_rel);
- while(relation) /* if no relation, this is skipped */
- {
- /* NOTE: if writep and readp are equal, the distance ist max
- * == PORT_BUFFER
- */
- if (((relation->mixer_writep-readp-1+PORT_BUFFER)%PORT_BUFFER)+1 <= length) /* underrun */
- {
- /* remove port relation in order to resync.
- * this is also caused by ports which do not transmit
- * anymore.
- */
-#ifdef MIXER_DEBUG
- PERROR("PORT(%s) Buffer underrun, source port is sending too slow or stopped sending, removing relation. (readp=%d, writep=%d, PORT_BUFFER=%d)\n", p_name, readp, relation->mixer_writep, PORT_BUFFER);
-#endif
-
- *relationpointer = relation->next;
- memset(relation, 0, sizeof(struct mixer_relation));
- free(relation);
- pmemuse--;
- relation = *relationpointer;
- continue;
- }
- relationpointer = &(relation->next);
- relation = relation->next;
- }
-
- /* if we do recording, we write the record data and the buffer data to the record fp and increment record_count */
- if (p_record)
- switch (p_record_type)
- {
- case CODEC_MONO:
- /* convert from mixer to uncompressed 16 bit mono audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- rec_buffer = record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<1), 1, p_record);
- p_record_length = (length<<1) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- rec_buffer = record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<1), 1, p_record);
- p_record_length = (length<<1) + p_record_length;
- }
- break;
-
- }
- break;
-
- case CODEC_STEREO:
- /* convert from mixer to uncompressed 16 bit stereo audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- mix_buffer2 = p_stereo_buffer;
- rec_buffer = record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
-
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<2), 1, p_record);
- p_record_length = (length<<2) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- mix_buffer2 = p_stereo_buffer;
- rec_buffer = record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
-
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<2), 1, p_record);
- p_record_length = (length<<2) + p_record_length;
- }
- break;
- }
- break;
-
- case CODEC_8BIT:
- /* convert from mixer to uncompressed 8 bit mono audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
-
- }
- break;
-
- case CODEC_LAW:
- case CODEC_OFF: /* if no codec is specified, the recorded data will be stored as LAW */
- /* convert from mixer to law */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
- }
- break;
- }
-
- /* if we have no transmitting relation, we do not need read mixer */
- if (!p_mixer_rel)
- { /* nothing mixed to(no rel), so we are just done */
- if (compressed)
- {
- /* compress to law */
- len = length;
- buf_in8 = (unsigned char *)temp_buffer;
- buf_in16 = (signed short *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- while(len--)
- *(buffer++) = audio_s16_to_law[*(buf_in16++) & 0xffff];
- break;
-
- case CODEC_LAW:
- memcpy(buffer, temp_buffer, length);
- break;
-
- default:
- PERROR("Software error: current tone for unmixed & uncompressed, has no codec\n");
- exit(-1);
- }
- } else
- {
- /* uncompress law files */
- len = length;
- buf_in8 = (unsigned char *)temp_buffer;
- buf_in16 = (signed short *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- while(len--)
- (*(buf_out16++)) = *(buf_in16++);
- break;
-
- case CODEC_LAW:
- while(len--)
- (*(buf_out16++)) = audio_law_to_s32[*(buf_in8++)];
- break;
-
- default:
- PERROR("Software error: current tone for unmixed & uncompressed, has no codec\n");
- exit(-1);
- }
- }
- return(length);
- }
-
-// PDEBUG(DEBUG_PORT, "PORT(%s) mixing %d bytes. (readp=%d, PORT_BUFFER=%d)\n", p_name, length, readp, PORT_BUFFER);
- /* now we got our stuff and we'll mix it baby */
-
- len = length;
- mix_buffer = p_mixer_buffer;
- if (compressed)
- {
- /* convert from mixer to compressed law data */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- break;
-
- case CODEC_LAW:
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- break;
-
- default:
- PERROR("Software error: current tone for compressed data has no codec\n");
- exit(-1);
- }
- } else
- {
- /* convert from mixer to uncompressed 16 bit audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- buf_in16 = (signed short *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- break;
-
- case CODEC_LAW:
- buf_in8 = (unsigned char *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- break;
-
- default:
- PERROR("Software error: current tone for uncompressed data has no codec\n");
- exit(-1);
- }
- }
-
- p_mixer_readp = readp; /* new read pointer */
-
+done:
return(length);
}
-/* dummy handler */
+/* port handler:
+ * process transmission clock */
int Port::handler(void)
{
+ port
+
return(0);
}
diff --git a/port.h b/port.h
index 688faa6..bb93479 100644
--- a/port.h
+++ b/port.h
@@ -24,12 +24,6 @@
/* te-mode */
#define PORT_TYPE_DSS1_TE_IN 0x0113
#define PORT_TYPE_DSS1_TE_OUT 0x0114
- /* sip */
-#define PORT_TYPE_SIP_IN 0x0121
-#define PORT_TYPE_SIP_OUT 0x0122
- /* h323 */
-#define PORT_TYPE_H323_IN 0x0211
-#define PORT_TYPE_H323_OUT 0x0212
/* answering machine */
#define PORT_TYPE_VBOX_OUT 0x0311
@@ -172,16 +166,6 @@ class Port
void set_vbox_play(char *name, int offset); /* sample of answ. */
void set_vbox_speed(int speed); /* speed of answ. */
- /* user space mixer buffer */
- signed long p_mixer_buffer[PORT_BUFFER]; /* mixer buffer */
- signed long p_record_buffer[PORT_BUFFER]; /* record buffer */
- signed long p_stereo_buffer[PORT_BUFFER]; /* record buffer for stereo (user only) */
- struct mixer_relation *p_mixer_rel; /* list of mixer relations */
- int p_mixer_readp; /* read pointer in buffer */
-
- /* methods */
- void mixer(union parameter *param);
-
/* identification */
unsigned long p_serial; /* serial unique id of port */
char p_name[128]; /* name of port or token (h323) */
diff --git a/route.c b/route.c
index 38f1f7e..b39d2e0 100644
--- a/route.c
+++ b/route.c
@@ -20,16 +20,10 @@ struct route_ruleset *ruleset_first; /* first entry */
struct route_ruleset *ruleset_main; /* pointer to main ruleset */
struct cond_defs cond_defs[] = {
-#ifdef PBX
{ "extern", MATCH_EXTERN, COND_TYPE_NULL,
- "extern", "Matches if call is from external port."},
- { "intern", MATCH_INTERN, COND_TYPE_NULL,
- "intern", "Matches if call is from internal port."},
-#endif
- { "h323", MATCH_H323, COND_TYPE_NULL,
- "h323", "Matches if call is received via H.323."},
-// { "ip", MATCH_IP, COND_TYPE_IP,
-// "ip=<ip>[-<ip>|/<mask>][,...]", "Matches if caller matches given source IP address(es) / range(s) / block(s)."},
+ "extern", "Matches if call is from external port (no extension)."},
+ { "intern", MATCH_INTERN,COND_TYPE_NULL,
+ "intern", "Matches if call is from an extension."},
{ "port", MATCH_PORT, COND_TYPE_INTEGER,
"port=<number>[-<number>][,...]", "Matches if call is received from given port(s). NOT INTERFACE!"},
{ "interface", MATCH_INTERFACE,COND_TYPE_STRING,
@@ -111,14 +105,12 @@ struct param_defs param_defs[] = {
{ PARAM_CONNECT,
"connect", PARAM_TYPE_NULL,
"connect", "Will complete the call before processing the action. Audio path for external calls will be established."},
-#ifdef PBX
{ PARAM_EXTENSION,
"extension", PARAM_TYPE_STRING,
"extension=<digits>", "Give extension name (digits) to relate this action to."},
{ PARAM_EXTENSIONS,
"extensions", PARAM_TYPE_STRING,
"extensions=<extension>[,<extension>[,...]]", "One or more extensions may be given."},
-#endif
{ PARAM_PREFIX,
"prefix", PARAM_TYPE_STRING,
"prefix=<digits>", "Add prefix in front of the dialed number."},
@@ -170,11 +162,9 @@ struct param_defs param_defs[] = {
{ PARAM_SAMPLE,
"sample", PARAM_TYPE_STRING,
"sample=<file prefix>", "Filename of sample (current tone's dir) or full path to sample. ('.wav'/'.wave'/'.isdn' is added automatically."},
-#ifdef PBX
{ PARAM_ANNOUNCEMENT,
"announcement",PARAM_TYPE_STRING,
"announcement=<file prefix>", "Filename of announcement (inside vbox recording dir) or full path to sample. ('.wav'/'.wave'/'.isdn' is added automatically."},
-#endif
{ PARAM_RULESET,
"ruleset", PARAM_TYPE_STRING,
"ruleset=<name>", "Ruleset to go to."},
@@ -229,11 +219,9 @@ struct param_defs param_defs[] = {
{ PARAM_TIMEOUT,
"timeout", PARAM_TYPE_INTEGER,
"timeout=<seconds>", "Timeout before continue with next action."},
-#ifdef PBX
{ PARAM_NOPASSWORD,
"nopassword", PARAM_TYPE_NULL,
"nopassword", "Don't ask for password. Be sure to authenticate right via real caller ID."},
-#endif
{ 0, NULL, 0, NULL, NULL}
};
@@ -250,10 +238,6 @@ struct action_defs action_defs[] = {
"outdial", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call,
PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_TIMEOUT,
"Same as 'extern'"},
- { ACTION_H323,
- "h323", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_h323, &EndpointAppPBX::action_hangup_call,
- PARAM_CONNECT | PARAM_PREFIX | PARAM_HOST | PARAM_PORT | PARAM_ADDRESS | PARAM_TIMEOUT,
- "Call is routed to H.323 host/gateway."},
{ ACTION_CHAN,
"asterisk", &EndpointAppPBX::action_init_chan, &EndpointAppPBX::action_dialing_chan, &EndpointAppPBX::action_hangup_call,
PARAM_CONNECT | PARAM_TIMEOUT,
@@ -2038,13 +2022,6 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
istrue = 1;
break;
- case MATCH_H323:
-// printf("\n\n\nport-type %x\n\n\n\n", ea_endpoint->ep_portlist->port_type);
- if (ea_endpoint->ep_portlist)
- if (ea_endpoint->ep_portlist->port_type == PORT_TYPE_H323_IN)
- istrue = 1;
- break;
-
case MATCH_PORT:
if (ea_endpoint->ep_portlist)
if ((ea_endpoint->ep_portlist->port_type & PORT_CLASS_mISDN_MASK) != PORT_CLASS_mISDN_DSS1)
@@ -2481,14 +2458,6 @@ struct route_action action_internal = {
0,
};
-struct route_action action_h323 = {
- NULL,
- NULL,
- ACTION_H323,
- 0,
- 0,
-};
-
struct route_action action_chan = {
NULL,
NULL,
diff --git a/route.h b/route.h
index c4da1b4..7ed536d 100644
--- a/route.h
+++ b/route.h
@@ -36,12 +36,8 @@ enum { /* how to parse text file during startup */
};
enum { /* what to check during runtime */
-#ifdef PBX
MATCH_EXTERN,
MATCH_INTERN,
-#endif
- MATCH_H323,
-// MATCH_IP,
MATCH_PORT,
MATCH_INTERFACE,
MATCH_CALLERID,
@@ -96,10 +92,8 @@ enum { /* how to parse text file during startup */
#define PARAM_PROCEEDING 1LL
#define PARAM_ALERTING (1LL<<1)
#define PARAM_CONNECT (1LL<<2)
-#ifdef PBX
#define PARAM_EXTENSION (1LL<<3)
#define PARAM_EXTENSIONS (1LL<<4)
-#endif
#define PARAM_PREFIX (1LL<<5)
#define PARAM_CAPA (1LL<<6)
#define PARAM_BMODE (1LL<<7)
@@ -149,37 +143,36 @@ enum { /* how to parse text file during startup */
#define ACTION_EXTERNAL 0
#define ACTION_INTERNAL 1
#define ACTION_OUTDIAL 2
-#define ACTION_H323 3
-#define ACTION_CHAN 4
-#define ACTION_VBOX_RECORD 5
-#define ACTION_PARTYLINE 6
-#define ACTION_LOGIN 7
-#define ACTION_CALLERID 8
-#define ACTION_CALLERIDNEXT 9
-#define ACTION_FORWARD 10
-#define ACTION_REDIAL 11
-#define ACTION_REPLY 12
-#define ACTION_POWERDIAL 13
-#define ACTION_CALLBACK 14
-#define ACTION_ABBREV 15
-#define ACTION_TEST 16
-#define ACTION_PLAY 17
-#define ACTION_VBOX_PLAY 18
-#define ACTION_CALCULATOR 19
-#define ACTION_TIMER 20
-#define ACTION_GOTO 21
-#define ACTION_MENU 22
-#define ACTION_DISCONNECT 23
-#define ACTION_HELP 24
-#define ACTION_DEFLECT 25
-#define ACTION_SETFORWARD 26
-#define ACTION_EXECUTE 27
-#define ACTION_FILE 28
-#define ACTION_PICK 29
-#define ACTION_PASSWORD 30
-#define ACTION_PASSWORD_WRITE 31
-#define ACTION_NOTHING 32
-#define ACTION_EFI 33
+#define ACTION_CHAN 3
+#define ACTION_VBOX_RECORD 4
+#define ACTION_PARTYLINE 5
+#define ACTION_LOGIN 6
+#define ACTION_CALLERID 7
+#define ACTION_CALLERIDNEXT 8
+#define ACTION_FORWARD 9
+#define ACTION_REDIAL 10
+#define ACTION_REPLY 11
+#define ACTION_POWERDIAL 12
+#define ACTION_CALLBACK 13
+#define ACTION_ABBREV 14
+#define ACTION_TEST 15
+#define ACTION_PLAY 16
+#define ACTION_VBOX_PLAY 17
+#define ACTION_CALCULATOR 18
+#define ACTION_TIMER 19
+#define ACTION_GOTO 20
+#define ACTION_MENU 21
+#define ACTION_DISCONNECT 22
+#define ACTION_HELP 23
+#define ACTION_DEFLECT 24
+#define ACTION_SETFORWARD 25
+#define ACTION_EXECUTE 26
+#define ACTION_FILE 27
+#define ACTION_PICK 28
+#define ACTION_PASSWORD 29
+#define ACTION_PASSWORD_WRITE 30
+#define ACTION_NOTHING 31
+#define ACTION_EFI 32
struct route_cond { /* an item */
struct route_cond *next; /* next entry */
@@ -263,7 +256,6 @@ extern struct route_ruleset *ruleset_first;
extern struct route_ruleset *ruleset_main;
extern struct route_action action_external;
extern struct route_action action_internal;
-extern struct route_action action_h323;
extern struct route_action action_chan;
extern struct route_action action_vbox;
extern struct route_action action_partyline;
diff --git a/todo.txt b/todo.txt
index 131a13c..ad0b9fc 100644
--- a/todo.txt
+++ b/todo.txt
@@ -3,7 +3,7 @@ define and change dsp conference ids
make asterisk call implementation
-new interface.conf
+new interface.conf (add remove ports by admin)
reduce mixer
@@ -20,10 +20,9 @@ trace with layers and filters
- application process (action)
- bchannel control (tones, dsp, filter, activation/deactivation)
-sip raus, h323 raus
-
avoid disconnect-collision (release if disconnect from both sides)
+display message during nothing/play
diff --git a/tones.c b/tones.c
index 45c05c9..5d64125 100644
--- a/tones.c
+++ b/tones.c
@@ -276,6 +276,7 @@ int open_tone(char *file, int *codec, signed long *length, signed long *left)
/*
* read from tone, check size
* the len must be the number of samples, NOT for the bytes to read!!
+ * the data returned is law-code
*/
int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed long *left, int speed)
{
@@ -319,15 +320,29 @@ int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed
break;
case CODEC_MONO:
- l = read(fh, buffer, len<<1); /* as is */
- if (l>0)
- l = l>>1;
+ signed short buffer16[len], *buf16 = buffer16;
+ signed long sample;
+ int i = 0;
+ l = read(fh, buf16, len<<1);
+ if (l>0)
+ {
+ l = l>>1;
+ while(i < l)
+ {
+ sample = *buf16++;
+ if (sample < -32767)
+ sample = -32767;
+ if (sample > 32767)
+ sample = 32767;
+ *buffer++ = audio_s16_to_law[sample & 0xffff];
+ i++;
+ }
+ }
break;
case CODEC_STEREO:
{
signed short buffer32[len<<1], *buf32 = buffer32;
- signed short *buf16 = (signed short *)buffer;
signed long sample;
int i = 0;
l = read(fh, buf32, len<<2);
@@ -341,7 +356,7 @@ int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed
sample = -32767;
if (sample > 32767)
sample = 32767;
- *buf16++ = sample;
+ *buffer++ = audio_s16_to_law[sample & 0xffff];
i++;
}
}
@@ -351,14 +366,13 @@ int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed
case CODEC_8BIT:
{
unsigned char buffer8[len], *buf8 = buffer8;
- signed short *buf16 = (signed short *)buffer;
int i = 0;
l = read(fh, buf8, len);
if (l>0)
{
while(i < l)
{
- *buf16++ = (((*buf8++) << 8) - 0x8000) & 0xffff;
+ *buffer++ = audio_s16_to_law[(((*buf8++)<<8)-0x8000) & 0xffff];
i++;
}
}
@@ -366,7 +380,7 @@ int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed
break;
default:
- PERROR("codec %d is not specified or supported, exitting...\n", codec);
+ PERROR("codec %d is not supported, exitting...\n", codec);
exit(-1);
}
@@ -420,7 +434,7 @@ int fetch_tones(void)
char filename[256], name[256];
int fh;
int tone_codec;
- signed long tone_size, tone_left, real_size;
+ signed long tone_size, tone_left;
unsigned long memory = 0;
int samples = 0;
@@ -515,32 +529,8 @@ int fetch_tones(void)
continue;
}
- /* real size */
- switch(tone_codec)
- {
- case CODEC_LAW:
- real_size = tone_size;
- break;
-
- case CODEC_MONO:
- real_size = tone_size << 1;
- break;
-
- case CODEC_STEREO:
- real_size = tone_size << 1;
- break;
-
- case CODEC_8BIT:
- real_size = tone_size << 1;
- break;
-
- default:
- PERROR("codec %d is not specified or supported, exitting...\n", tone_codec);
- exit(-1);
- }
-
/* allocate tone */
- *tonesettone_nextpointer = (struct tonesettone *)calloc(1, sizeof(struct tonesettone)+real_size);
+ *tonesettone_nextpointer = (struct tonesettone *)calloc(1, sizeof(struct tonesettone)+tone_size);
if (*toneset_nextpointer == NULL)
{
PERROR("No memory for tone set: '%s'\n",p);
@@ -550,8 +540,8 @@ int fetch_tones(void)
}
memuse++;
//printf("tone:%s, %ld bytes\n", name, tone_size);
- memset(*tonesettone_nextpointer, 0 , sizeof(struct tonesettone)+real_size);
- memory += sizeof(struct tonesettone)+real_size;
+ memset(*tonesettone_nextpointer, 0 , sizeof(struct tonesettone)+tone_size);
+ memory += sizeof(struct tonesettone)+tone_size;
samples ++;
/* load tone */
@@ -629,7 +619,7 @@ void *open_tone_fetched(char *dir, char *file, int *codec, signed long *length,
* read from fetched tone, check size
* the len must be the number of samples, NOT for the bytes to read!!
*/
-int read_tone_fetched(void **fetched, void *buffer, int codec, int len, signed long size, signed long *left, int speed)
+int read_tone_fetched(void **fetched, void *buffer, int len, signed long size, signed long *left, int speed)
{
int l;
//printf("left=%ld\n",*left);
@@ -643,24 +633,10 @@ int read_tone_fetched(void **fetched, void *buffer, int codec, int len, signed l
if (*left < len)
len = *left;
- switch(codec)
- {
- case CODEC_LAW:
- memcpy(buffer, *fetched, len);
- *((char **)fetched) += len;
- l = len;
- break;
-
- case CODEC_MONO:
- memcpy(buffer, *fetched, len<<1);
- *((char **)fetched) += len<<1;
- l = len;
- break;
- default:
- PERROR("codec %d is not specified or supported, exitting...\n", codec);
- exit(-1);
- }
+ memcpy(buffer, *fetched, len);
+ *((char **)fetched) += len;
+ l = len;
if (l>0 && left)
*left -= l;
diff --git a/vbox.cpp b/vbox.cpp
index 2a96962..a059898 100644
--- a/vbox.cpp
+++ b/vbox.cpp
@@ -62,9 +62,13 @@ int VBoxPort::handler(void)
{
struct message *message;
unsigned long tosend;
- signed short buffer[128<<1];
+ signed short buffer[128];
time_t currenttime;
class Endpoint *epoint;
+ int ret;
+
+ if ((ret = Port::handler()))
+ return(ret);
if (p_vbox_record_start && p_vbox_record_limit)
{
@@ -98,7 +102,7 @@ int VBoxPort::handler(void)
/* wait for more */
if (tosend < 32)
- return(0);
+ return(Port::handler());
/* too many samples, so we just process 128 bytes until the next call of handler() */
if (tosend > 128)
@@ -113,23 +117,7 @@ int VBoxPort::handler(void)
/* if announcement is currently played, send audio data */
if (p_vbox_announce_fh >=0)
{
- /* read from announcement file */
- switch(p_vbox_announce_codec)
- {
- case CODEC_LAW:
- tosend = read_tone(p_vbox_announce_fh, buffer, p_vbox_announce_codec, tosend, p_vbox_announce_size, &p_vbox_announce_left, 1);
- break;
-
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- tosend = read_tone(p_vbox_announce_fh, buffer, p_vbox_announce_codec, tosend, p_vbox_announce_size, &p_vbox_announce_left, 1);
- break;
-
- default:
- PERROR("correct codec not given.\n");
- exit(-1);
- }
+ tosend = read_tone(p_vbox_announce_fh, buffer, p_vbox_announce_codec, tosend, p_vbox_announce_size, &p_vbox_announce_left, 1);
if (tosend <= 0)
{
/* end of file */
@@ -175,34 +163,12 @@ int VBoxPort::handler(void)
}
} else
{
- switch(p_vbox_announce_codec)
- {
- case CODEC_LAW:
- message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
- message->param.data.compressed = 1;
- message->param.data.port_type = p_type;
- message->param.data.port_id = p_serial;
- message->param.data.len = tosend;
- memcpy(message->param.data.data, buffer, tosend);
- message_put(message);
- break;
-
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
- message->param.data.compressed = 0;
- message->param.data.port_type = p_type;
- message->param.data.port_id = p_serial;
- message->param.data.len = tosend<<1;
- memcpy(message->param.data.data, buffer, tosend<<1);
- message_put(message);
- break;
-
- default:
- PERROR("correct announce_codec not given.\n");
- exit(-1);
- }
+ message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
+ message->param.data.port_type = p_type;
+ message->param.data.port_id = p_serial;
+ message->param.data.len = tosend;
+ memcpy(message->param.data.data, buffer, tosend);
+ message_put(message);
}
}
@@ -221,6 +187,9 @@ int VBoxPort::message_epoint(unsigned long epoint_id, int message_id, union para
char filename[256], *c;
class EndpointAppPBX *eapp;
+ if (Port::message_epoint(epoint_id, message_id, param))
+ return(1);
+
epoint = find_epoint_id(epoint_id);
if (!epoint)
{
@@ -228,9 +197,6 @@ int VBoxPort::message_epoint(unsigned long epoint_id, int message_id, union para
return(0);
}
- if (Port::message_epoint(epoint_id, message_id, param))
- return(1);
-
switch(message_id)
{
case MESSAGE_DISCONNECT: /* call has been disconnected */