backup
This commit is contained in:
parent
559ff64e30
commit
fd2045584f
54
Makefile
54
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
|
||||
|
|
4
README
4
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!
|
||||
|
||||
|
|
441
action.cpp
441
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
334
apppbx.cpp
334
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, ¶m->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, ¶m->setup.redirinfo, sizeof(e_redirinfo));
|
||||
memcpy(&e_capainfo, ¶m->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",
|
||||
|
|
185
callpbx.cpp
185
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;
|
||||
}
|
||||
|
||||
/* skip if destination endpoint has audio mode HOLD */
|
||||
if (relation_to->channel_state != CHANNEL_STATE_CONNECT)
|
||||
{
|
||||
relation_to = relation_to->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* oops, we are the first, so destination is: */
|
||||
relation_to = relation_to->next;
|
||||
}
|
||||
|
||||
/* 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
|
||||
*/
|
||||
//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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
11
dss1.cpp
11
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
22
extension.c
22
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");
|
||||
|
|
25
interface.c
25
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}
|
||||
};
|
||||
|
|
38
mISDN.cpp
38
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);
|
||||
|
@ -285,6 +292,11 @@ static void bchannel_deactivate(struct mISDNport *mISDNport, int i)
|
|||
/* reset dsp features */
|
||||
if (mISDNport->b_port[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);
|
||||
|
@ -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;
|
||||
|
|
4
mISDN.h
4
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 */
|
||||
|
|
119
main.c
119
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();
|
||||
|
|
68
main.h
68
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,31 +58,18 @@ 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
|
||||
/*
|
||||
* preload transmit buffer to avoid gaps at the beginning due to jitter
|
||||
* keep this 0 for minimum delay
|
||||
*/
|
||||
#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.
|
||||
*/
|
||||
#ifdef VOIP
|
||||
#warning to be removed soon
|
||||
#endif
|
||||
#define ISDN_JITTERLIMIT 512 /* maximum samples received before dropping */
|
||||
|
||||
/* give sendmail program. if not inside $PATH, give absolute path here (e.g. "/usr/sbin/sendmail")
|
||||
*/
|
||||
#define SENDMAIL "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
|
||||
|
||||
|
|
25
message.c
25
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
171
options.c
171
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)
|
||||
|
|
22
options.h
22
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 */
|
||||
|
|
16
port.h
16
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) */
|
||||
|
|
37
route.c
37
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,
|
||||
|
|
68
route.h
68
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;
|
||||
|
|
5
todo.txt
5
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
|
||||
|
||||
|
||||
|
||||
|
|
84
tones.c
84
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;
|
||||
|
|
66
vbox.cpp
66
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 */
|
||||
|
|
Loading…
Reference in New Issue