summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg2011-07-14 14:25:42 +0200
committerAndreas Eversberg2011-07-14 14:25:42 +0200
commitda91d7d85fe092122e35ece52695f98345738359 (patch)
treea06ffff8291b8f61441ef75b28a4184824806af5
parent[GSM_BS] Added DTMF support. (diff)
parent[GSM] Replaced strcpy by required macro name. (diff)
downloadlcr-da91d7d85fe092122e35ece52695f98345738359.tar.gz
lcr-da91d7d85fe092122e35ece52695f98345738359.tar.xz
lcr-da91d7d85fe092122e35ece52695f98345738359.zip
Merge branch 'develop'
Conflicts: Makefile.in README chan_lcr.c configure gsm_bs.cpp gsm_ms.cpp interface.c route.c
-rw-r--r--.gitignore9
-rw-r--r--INSTALL2
-rw-r--r--Makefile.am10
-rw-r--r--Makefile.in158
-rw-r--r--README531
-rw-r--r--aclocal.m4964
-rw-r--r--action.cpp4
-rw-r--r--apppbx.cpp42
-rw-r--r--chan_lcr.c787
-rw-r--r--chan_lcr.h4
-rw-r--r--config.h.in252
-rwxr-xr-xconfigure51
-rw-r--r--configure.ac22
-rw-r--r--default/gsm.conf39
-rw-r--r--default/interface.conf16
-rw-r--r--default/options.conf15
-rwxr-xr-xdepcomp584
-rw-r--r--gsm.cpp338
-rw-r--r--gsm.h28
-rw-r--r--gsm_bs.cpp376
-rw-r--r--gsm_bs.h4
-rw-r--r--gsm_conf.c170
-rw-r--r--gsm_ms.cpp161
-rw-r--r--gsm_ms.h4
-rwxr-xr-xinstall-sh507
-rw-r--r--interface.c64
-rw-r--r--interface.h4
-rw-r--r--joinremote.cpp29
-rw-r--r--joinremote.h2
-rw-r--r--loop.c153
-rw-r--r--loop.h12
-rw-r--r--mISDN.cpp92
-rw-r--r--mISDN.h3
-rw-r--r--mail.c8
-rw-r--r--main.c29
-rw-r--r--main.h2
-rw-r--r--message.h9
-rwxr-xr-xmissing367
-rw-r--r--options.c20
-rw-r--r--options.h2
-rw-r--r--port.h7
-rw-r--r--remote.cpp221
-rw-r--r--remote.h20
-rw-r--r--route.c10
-rw-r--r--socket_server.c140
-rw-r--r--socket_server.h5
46 files changed, 1998 insertions, 4279 deletions
diff --git a/.gitignore b/.gitignore
index f551c7f..570e576 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+core
*.o
*.po
*.so
@@ -6,10 +7,16 @@
stamp-h1
.deps/
Makefile
-autom4te.cache/
config.h
config.log
config.status
+*.in
+aclocal.m4
+autom4te.cache/
+configure
+depcomp
+install-sh
+missing
genextension
genrc
gentones
diff --git a/INSTALL b/INSTALL
index 5458714..0894a83 100644
--- a/INSTALL
+++ b/INSTALL
@@ -44,6 +44,8 @@ of `autoconf'.
The simplest way to compile this package is:
+ 0. If compile from GIT, run "./autogen.sh" first.
+
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
diff --git a/Makefile.am b/Makefile.am
index d8ba3bf..f047c56 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -51,7 +51,7 @@ if ENABLE_GSM
GSM_INCLUDE +=
-GSM_SOURCE += gsm_audio.c gsm.cpp gsm_conf.c
+GSM_SOURCE += gsm_audio.c gsm.cpp
GSM_LIB += /usr/lib/libgsm.a
@@ -64,9 +64,7 @@ if ENABLE_GSM_BS
GSM_INCLUDE += -DWITH_GSM_BS -I./openbsc/include -I./libosmocore/include -I./openbsc
-GSM_SOURCE += gsm_bs.cpp openbsc/src/bsc_init.c openbsc/src/bsc_vty.c openbsc/src/vty_interface_layer3.c openbsc/src/bsc_api.c openbsc/src/bsc_version.c
-
-GSM_LIB += ./openbsc/src/libbsc.a ./openbsc/src/libmsc.a ./openbsc/src/libvty.a -losmovty -losmocore -ldbi -lcrypt
+GSM_SOURCE += gsm_bs.cpp
endif
@@ -125,8 +123,8 @@ endif
INCLUDES = $(all_includes) $(GSM_INCLUDE) $(SS5_INCLUDE) -Wall $(INSTALLATION_DEFINES)
-lcr_SOURCES = $(GSM_SOURCE) $(SS5_SOURCE) select.c action.cpp mISDN.cpp tones.c \
- action_efi.cpp crypt.cpp mail.c trace.c \
+lcr_SOURCES = $(GSM_SOURCE) $(SS5_SOURCE) select.c action.cpp mISDN.cpp \
+ tones.c loop.c remote.c action_efi.cpp crypt.cpp mail.c trace.c \
action_vbox.cpp dss1.cpp main.c \
vbox.cpp alawulaw.c endpoint.cpp interface.c message.c \
apppbx.cpp endpointapp.cpp join.cpp options.c \
diff --git a/Makefile.in b/Makefile.in
index 067dfe1..5930a8e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -33,17 +33,16 @@ NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
@ENABLE_GSM_TRUE@am__append_1 =
-@ENABLE_GSM_TRUE@am__append_2 = gsm_audio.c gsm.cpp gsm_conf.c
+@ENABLE_GSM_TRUE@am__append_2 = gsm_audio.c gsm.cpp
@ENABLE_GSM_TRUE@am__append_3 = /usr/lib/libgsm.a
#gsm_audio.po: gsm_audio.c gsm_audio.h
# $(CC) -D_GNU_SOURCE -fPIC -c gsm_audio.c -o gsm_audio.po
@ENABLE_GSM_BS_TRUE@am__append_4 = -DWITH_GSM_BS -I./openbsc/include -I./libosmocore/include -I./openbsc
-@ENABLE_GSM_BS_TRUE@am__append_5 = gsm_bs.cpp openbsc/src/bsc_init.c openbsc/src/bsc_vty.c openbsc/src/vty_interface_layer3.c openbsc/src/bsc_api.c openbsc/src/bsc_version.c
-@ENABLE_GSM_BS_TRUE@am__append_6 = ./openbsc/src/libbsc.a ./openbsc/src/libmsc.a ./openbsc/src/libvty.a -losmovty -losmocore -ldbi -lcrypt
-@ENABLE_GSM_MS_TRUE@am__append_7 = -DPACKAGE_VERSION=0 -DWITH_GSM_MS -I./layer23/include -I./libosmocore/include
-@ENABLE_GSM_MS_TRUE@am__append_8 = gsm_ms.cpp layer23/src/mobile/app_mobile.c
-@ENABLE_GSM_MS_TRUE@am__append_9 = ./layer23/src/mobile/libmobile.a \
+@ENABLE_GSM_BS_TRUE@am__append_5 = gsm_bs.cpp
+@ENABLE_GSM_MS_TRUE@am__append_6 = -DPACKAGE_VERSION=0 -DWITH_GSM_MS -I./layer23/include -I./libosmocore/include
+@ENABLE_GSM_MS_TRUE@am__append_7 = gsm_ms.cpp layer23/src/mobile/app_mobile.c
+@ENABLE_GSM_MS_TRUE@am__append_8 = ./layer23/src/mobile/libmobile.a \
@ENABLE_GSM_MS_TRUE@ ./layer23/src/common/liblayer23.a \
@ENABLE_GSM_MS_TRUE@ ./libosmocore/build-host/src/.libs/libosmocore.a \
@ENABLE_GSM_MS_TRUE@ ./libosmocore/build-host/src/vty/.libs/libosmovty.a \
@@ -92,23 +91,16 @@ gentones_LDADD = $(LDADD)
genwave_SOURCES = genwave.c
genwave_OBJECTS = genwave.$(OBJEXT)
genwave_LDADD = $(LDADD)
-am__lcr_SOURCES_DIST = gsm_audio.c gsm.cpp gsm_conf.c gsm_bs.cpp \
- openbsc/src/bsc_init.c openbsc/src/bsc_vty.c \
- openbsc/src/vty_interface_layer3.c openbsc/src/bsc_api.c \
- openbsc/src/bsc_version.c gsm_ms.cpp \
+am__lcr_SOURCES_DIST = gsm_audio.c gsm.cpp gsm_bs.cpp gsm_ms.cpp \
layer23/src/mobile/app_mobile.c ss5.cpp ss5_encode.c \
- ss5_decode.c select.c action.cpp mISDN.cpp tones.c \
- action_efi.cpp crypt.cpp mail.c trace.c action_vbox.cpp \
- dss1.cpp main.c vbox.cpp alawulaw.c endpoint.cpp interface.c \
- message.c apppbx.cpp endpointapp.cpp join.cpp options.c \
- extension.c joinpbx.cpp port.cpp callerid.c joinremote.cpp \
- route.c cause.c socket_server.c
-@ENABLE_GSM_TRUE@am__objects_1 = gsm_audio.$(OBJEXT) gsm.$(OBJEXT) \
-@ENABLE_GSM_TRUE@ gsm_conf.$(OBJEXT)
-@ENABLE_GSM_BS_TRUE@am__objects_2 = gsm_bs.$(OBJEXT) \
-@ENABLE_GSM_BS_TRUE@ bsc_init.$(OBJEXT) bsc_vty.$(OBJEXT) \
-@ENABLE_GSM_BS_TRUE@ vty_interface_layer3.$(OBJEXT) \
-@ENABLE_GSM_BS_TRUE@ bsc_api.$(OBJEXT) bsc_version.$(OBJEXT)
+ ss5_decode.c select.c action.cpp mISDN.cpp tones.c loop.c \
+ remote.c action_efi.cpp crypt.cpp mail.c trace.c \
+ action_vbox.cpp dss1.cpp main.c vbox.cpp alawulaw.c \
+ endpoint.cpp interface.c message.c apppbx.cpp endpointapp.cpp \
+ join.cpp options.c extension.c joinpbx.cpp port.cpp callerid.c \
+ joinremote.cpp route.c cause.c socket_server.c
+@ENABLE_GSM_TRUE@am__objects_1 = gsm_audio.$(OBJEXT) gsm.$(OBJEXT)
+@ENABLE_GSM_BS_TRUE@am__objects_2 = gsm_bs.$(OBJEXT)
@ENABLE_GSM_MS_TRUE@am__objects_3 = gsm_ms.$(OBJEXT) \
@ENABLE_GSM_MS_TRUE@ app_mobile.$(OBJEXT)
am__objects_4 = $(am__objects_1) $(am__objects_2) $(am__objects_3)
@@ -116,22 +108,18 @@ am__objects_4 = $(am__objects_1) $(am__objects_2) $(am__objects_3)
@ENABLE_SS5_TRUE@ ss5_decode.$(OBJEXT)
am_lcr_OBJECTS = $(am__objects_4) $(am__objects_5) select.$(OBJEXT) \
action.$(OBJEXT) mISDN.$(OBJEXT) tones.$(OBJEXT) \
- action_efi.$(OBJEXT) crypt.$(OBJEXT) mail.$(OBJEXT) \
- trace.$(OBJEXT) action_vbox.$(OBJEXT) dss1.$(OBJEXT) \
- main.$(OBJEXT) vbox.$(OBJEXT) alawulaw.$(OBJEXT) \
- endpoint.$(OBJEXT) interface.$(OBJEXT) message.$(OBJEXT) \
- apppbx.$(OBJEXT) endpointapp.$(OBJEXT) join.$(OBJEXT) \
- options.$(OBJEXT) extension.$(OBJEXT) joinpbx.$(OBJEXT) \
- port.$(OBJEXT) callerid.$(OBJEXT) joinremote.$(OBJEXT) \
- route.$(OBJEXT) cause.$(OBJEXT) socket_server.$(OBJEXT)
+ loop.$(OBJEXT) remote.$(OBJEXT) action_efi.$(OBJEXT) \
+ crypt.$(OBJEXT) mail.$(OBJEXT) trace.$(OBJEXT) \
+ action_vbox.$(OBJEXT) dss1.$(OBJEXT) main.$(OBJEXT) \
+ vbox.$(OBJEXT) alawulaw.$(OBJEXT) endpoint.$(OBJEXT) \
+ interface.$(OBJEXT) message.$(OBJEXT) apppbx.$(OBJEXT) \
+ endpointapp.$(OBJEXT) join.$(OBJEXT) options.$(OBJEXT) \
+ extension.$(OBJEXT) joinpbx.$(OBJEXT) port.$(OBJEXT) \
+ callerid.$(OBJEXT) joinremote.$(OBJEXT) route.$(OBJEXT) \
+ cause.$(OBJEXT) socket_server.$(OBJEXT)
lcr_OBJECTS = $(am_lcr_OBJECTS)
am__DEPENDENCIES_1 =
-@ENABLE_GSM_BS_TRUE@am__DEPENDENCIES_2 = ./openbsc/src/libbsc.a \
-@ENABLE_GSM_BS_TRUE@ ./openbsc/src/libmsc.a \
-@ENABLE_GSM_BS_TRUE@ ./openbsc/src/libvty.a
-am__DEPENDENCIES_3 = $(am__append_3) $(am__DEPENDENCIES_2) \
- $(am__append_9)
-lcr_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
+lcr_DEPENDENCIES = $(am__DEPENDENCIES_1) $(GSM_LIB)
am_lcradmin_OBJECTS = lcradmin.$(OBJEXT) cause.$(OBJEXT) \
options.$(OBJEXT)
lcradmin_OBJECTS = $(am_lcradmin_OBJECTS)
@@ -276,17 +264,17 @@ INSTALLATION_DEFINES = \
-DLOG_DIR="\"$(LOGdir)\"" \
-DEXTENSION_DATA="\"$(EXTENSIONdir)\""
-GSM_INCLUDE = $(am__append_1) $(am__append_4) $(am__append_7)
-GSM_SOURCE = $(am__append_2) $(am__append_5) $(am__append_8)
-GSM_LIB = $(am__append_3) $(am__append_6) $(am__append_9)
+GSM_INCLUDE = $(am__append_1) $(am__append_4) $(am__append_6)
+GSM_SOURCE = $(am__append_2) $(am__append_5) $(am__append_7)
+GSM_LIB = $(am__append_3) $(am__append_8)
@ENABLE_SS5_TRUE@SS5_INCLUDE = -DWITH_SS5
@ENABLE_SS5_TRUE@SS5_SOURCE = ss5.cpp ss5_encode.c ss5_decode.c
@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@chan_lcr_so_SOURCES =
@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@chan_lcr_so_LDFLAGS = -shared
@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@chan_lcr_so_LDADD = chan_lcr.po bchannel.po options.po callerid.po select.po
INCLUDES = $(all_includes) $(GSM_INCLUDE) $(SS5_INCLUDE) -Wall $(INSTALLATION_DEFINES)
-lcr_SOURCES = $(GSM_SOURCE) $(SS5_SOURCE) select.c action.cpp mISDN.cpp tones.c \
- action_efi.cpp crypt.cpp mail.c trace.c \
+lcr_SOURCES = $(GSM_SOURCE) $(SS5_SOURCE) select.c action.cpp mISDN.cpp \
+ tones.c loop.c remote.c action_efi.cpp crypt.cpp mail.c trace.c \
action_vbox.cpp dss1.cpp main.c \
vbox.cpp alawulaw.c endpoint.cpp interface.c message.c \
apppbx.cpp endpointapp.cpp join.cpp options.c \
@@ -474,10 +462,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alawulaw.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/app_mobile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apppbx.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsc_api.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsc_init.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsc_version.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsc_vty.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callerid.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cause.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypt.Po@am__quote@
@@ -492,19 +476,20 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_audio.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_bs.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_conf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_ms.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interface.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/join.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/joinpbx.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/joinremote.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lcradmin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mISDN.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mail.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/port.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remote.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/select.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket_server.Po@am__quote@
@@ -514,7 +499,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tones.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vbox.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vty_interface_layer3.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -530,76 +514,6 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-bsc_init.o: openbsc/src/bsc_init.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bsc_init.o -MD -MP -MF $(DEPDIR)/bsc_init.Tpo -c -o bsc_init.o `test -f 'openbsc/src/bsc_init.c' || echo '$(srcdir)/'`openbsc/src/bsc_init.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/bsc_init.Tpo $(DEPDIR)/bsc_init.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='openbsc/src/bsc_init.c' object='bsc_init.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bsc_init.o `test -f 'openbsc/src/bsc_init.c' || echo '$(srcdir)/'`openbsc/src/bsc_init.c
-
-bsc_init.obj: openbsc/src/bsc_init.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bsc_init.obj -MD -MP -MF $(DEPDIR)/bsc_init.Tpo -c -o bsc_init.obj `if test -f 'openbsc/src/bsc_init.c'; then $(CYGPATH_W) 'openbsc/src/bsc_init.c'; else $(CYGPATH_W) '$(srcdir)/openbsc/src/bsc_init.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/bsc_init.Tpo $(DEPDIR)/bsc_init.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='openbsc/src/bsc_init.c' object='bsc_init.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bsc_init.obj `if test -f 'openbsc/src/bsc_init.c'; then $(CYGPATH_W) 'openbsc/src/bsc_init.c'; else $(CYGPATH_W) '$(srcdir)/openbsc/src/bsc_init.c'; fi`
-
-bsc_vty.o: openbsc/src/bsc_vty.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bsc_vty.o -MD -MP -MF $(DEPDIR)/bsc_vty.Tpo -c -o bsc_vty.o `test -f 'openbsc/src/bsc_vty.c' || echo '$(srcdir)/'`openbsc/src/bsc_vty.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/bsc_vty.Tpo $(DEPDIR)/bsc_vty.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='openbsc/src/bsc_vty.c' object='bsc_vty.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bsc_vty.o `test -f 'openbsc/src/bsc_vty.c' || echo '$(srcdir)/'`openbsc/src/bsc_vty.c
-
-bsc_vty.obj: openbsc/src/bsc_vty.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bsc_vty.obj -MD -MP -MF $(DEPDIR)/bsc_vty.Tpo -c -o bsc_vty.obj `if test -f 'openbsc/src/bsc_vty.c'; then $(CYGPATH_W) 'openbsc/src/bsc_vty.c'; else $(CYGPATH_W) '$(srcdir)/openbsc/src/bsc_vty.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/bsc_vty.Tpo $(DEPDIR)/bsc_vty.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='openbsc/src/bsc_vty.c' object='bsc_vty.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bsc_vty.obj `if test -f 'openbsc/src/bsc_vty.c'; then $(CYGPATH_W) 'openbsc/src/bsc_vty.c'; else $(CYGPATH_W) '$(srcdir)/openbsc/src/bsc_vty.c'; fi`
-
-vty_interface_layer3.o: openbsc/src/vty_interface_layer3.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vty_interface_layer3.o -MD -MP -MF $(DEPDIR)/vty_interface_layer3.Tpo -c -o vty_interface_layer3.o `test -f 'openbsc/src/vty_interface_layer3.c' || echo '$(srcdir)/'`openbsc/src/vty_interface_layer3.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vty_interface_layer3.Tpo $(DEPDIR)/vty_interface_layer3.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='openbsc/src/vty_interface_layer3.c' object='vty_interface_layer3.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vty_interface_layer3.o `test -f 'openbsc/src/vty_interface_layer3.c' || echo '$(srcdir)/'`openbsc/src/vty_interface_layer3.c
-
-vty_interface_layer3.obj: openbsc/src/vty_interface_layer3.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vty_interface_layer3.obj -MD -MP -MF $(DEPDIR)/vty_interface_layer3.Tpo -c -o vty_interface_layer3.obj `if test -f 'openbsc/src/vty_interface_layer3.c'; then $(CYGPATH_W) 'openbsc/src/vty_interface_layer3.c'; else $(CYGPATH_W) '$(srcdir)/openbsc/src/vty_interface_layer3.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/vty_interface_layer3.Tpo $(DEPDIR)/vty_interface_layer3.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='openbsc/src/vty_interface_layer3.c' object='vty_interface_layer3.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vty_interface_layer3.obj `if test -f 'openbsc/src/vty_interface_layer3.c'; then $(CYGPATH_W) 'openbsc/src/vty_interface_layer3.c'; else $(CYGPATH_W) '$(srcdir)/openbsc/src/vty_interface_layer3.c'; fi`
-
-bsc_api.o: openbsc/src/bsc_api.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bsc_api.o -MD -MP -MF $(DEPDIR)/bsc_api.Tpo -c -o bsc_api.o `test -f 'openbsc/src/bsc_api.c' || echo '$(srcdir)/'`openbsc/src/bsc_api.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/bsc_api.Tpo $(DEPDIR)/bsc_api.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='openbsc/src/bsc_api.c' object='bsc_api.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bsc_api.o `test -f 'openbsc/src/bsc_api.c' || echo '$(srcdir)/'`openbsc/src/bsc_api.c
-
-bsc_api.obj: openbsc/src/bsc_api.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bsc_api.obj -MD -MP -MF $(DEPDIR)/bsc_api.Tpo -c -o bsc_api.obj `if test -f 'openbsc/src/bsc_api.c'; then $(CYGPATH_W) 'openbsc/src/bsc_api.c'; else $(CYGPATH_W) '$(srcdir)/openbsc/src/bsc_api.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/bsc_api.Tpo $(DEPDIR)/bsc_api.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='openbsc/src/bsc_api.c' object='bsc_api.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bsc_api.obj `if test -f 'openbsc/src/bsc_api.c'; then $(CYGPATH_W) 'openbsc/src/bsc_api.c'; else $(CYGPATH_W) '$(srcdir)/openbsc/src/bsc_api.c'; fi`
-
-bsc_version.o: openbsc/src/bsc_version.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bsc_version.o -MD -MP -MF $(DEPDIR)/bsc_version.Tpo -c -o bsc_version.o `test -f 'openbsc/src/bsc_version.c' || echo '$(srcdir)/'`openbsc/src/bsc_version.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/bsc_version.Tpo $(DEPDIR)/bsc_version.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='openbsc/src/bsc_version.c' object='bsc_version.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bsc_version.o `test -f 'openbsc/src/bsc_version.c' || echo '$(srcdir)/'`openbsc/src/bsc_version.c
-
-bsc_version.obj: openbsc/src/bsc_version.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bsc_version.obj -MD -MP -MF $(DEPDIR)/bsc_version.Tpo -c -o bsc_version.obj `if test -f 'openbsc/src/bsc_version.c'; then $(CYGPATH_W) 'openbsc/src/bsc_version.c'; else $(CYGPATH_W) '$(srcdir)/openbsc/src/bsc_version.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/bsc_version.Tpo $(DEPDIR)/bsc_version.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='openbsc/src/bsc_version.c' object='bsc_version.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bsc_version.obj `if test -f 'openbsc/src/bsc_version.c'; then $(CYGPATH_W) 'openbsc/src/bsc_version.c'; else $(CYGPATH_W) '$(srcdir)/openbsc/src/bsc_version.c'; fi`
-
app_mobile.o: layer23/src/mobile/app_mobile.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT app_mobile.o -MD -MP -MF $(DEPDIR)/app_mobile.Tpo -c -o app_mobile.o `test -f 'layer23/src/mobile/app_mobile.c' || echo '$(srcdir)/'`layer23/src/mobile/app_mobile.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/app_mobile.Tpo $(DEPDIR)/app_mobile.Po
@@ -955,19 +869,19 @@ uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS
@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@chan_lcr.po: chan_lcr.c chan_lcr.h
-@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@ $(CC) $(INCLUDES) $(AST_CFLAGS) -D_GNU_SOURCE -fPIC -c chan_lcr.c -o chan_lcr.po
+@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@ $(CC) $(INCLUDES) $(AST_CFLAGS) $(CPPFLAGS) $(CFLAGS) -D_GNU_SOURCE -fPIC -c chan_lcr.c -o chan_lcr.po
@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@bchannel.po: bchannel.c bchannel.h
-@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@ $(CC) $(INCLUDES) -D_GNU_SOURCE -fPIC -c bchannel.c -o bchannel.po
+@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@ $(CC) $(INCLUDES) -D_GNU_SOURCE $(CPPFLAGS) $(CFLAGS) -fPIC -c bchannel.c -o bchannel.po
@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@callerid.po: callerid.c callerid.h
-@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@ $(CC) $(INCLUDES) -D_GNU_SOURCE -fPIC -c callerid.c -o callerid.po
+@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@ $(CC) $(INCLUDES) -D_GNU_SOURCE $(CPPFLAGS) $(CFLAGS) -fPIC -c callerid.c -o callerid.po
@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@options.po: options.c options.h
-@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@ $(CC) $(INCLUDES) -D_GNU_SOURCE -fPIC -c options.c -o options.po
+@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@ $(CC) $(INCLUDES) -D_GNU_SOURCE $(CPPFLAGS) $(CFLAGS) -fPIC -c options.c -o options.po
@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@select.po: select.c select.h
-@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@ $(CC) $(INCLUDES) -D_GNU_SOURCE -fPIC -c select.c -o select.po
+@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@ $(CC) $(INCLUDES) -D_GNU_SOURCE $(CPPFLAGS) $(CFLAGS) -fPIC -c select.c -o select.po
@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@install-exec-hook:
@ENABLE_ASTERISK_CHANNEL_DRIVER_TRUE@ mkdir -p $(astmoddir)
diff --git a/README b/README
index 8515363..ffd2bdb 100644
--- a/README
+++ b/README
@@ -24,534 +24,3 @@ Read the documentation at http://www.linux-call-router.de
Also you will find a quick howto there.
-History:
---------
-
-Changes in Version 20021228
-- first release
-
-Changes in Version 20030111 (buggy and unuseable)
-- support dtmf for callback and dtmf dialing mode (dial through via dtmf)
-- bug fixes
-- dialing improvement: dialing h323 now possible with port and alias
-- other stuff
-- new Makefile: make install will now install binaries and data on your system
-
-Changes in Version 20030118 (buggy and unuseable)
-- information exchange between isdn/h323-ports, endpoints and calls are messages now
- previousely using direct calls with pointers were dangerous
-- removed bug since 200301011, which caued h323 calls to deadlock
-
-Changes in Version 20030120
-- login function
-- callback authentication
-- h323 audio bug. no h323 audio transmission sice version 20030111
-- some other bug fixes
-
-Changes in Version 20030206 (first beta release 1.0)
-- callerid (CLIP/COLP) is now processed correctly with all features
-- hold sound and active/inactive notification
-- CD notification
-- many callerid display function
-- bug fixes
-- documentation as word document (partly done)
-- Note: This week I have my vakation, so there is no response to any question in the mailing list.
-
-Changes in Version 1.0
-- first release
-- finished the first version of the documentation
-- new style internet page with documentation in html
-- all enities (port, endpoint, call) are now c++ objects, rather than structures
-- tones may now be played and recorded using wave (8bit mono, 16bit mono, 16bit stereo) or law (alwa/ulaw mono)
-- fixed corruption in wave-file creation
-- now call forwad (cfb, cfnr) is implemented and working
-- an answering machine with playback function is implemented.
-- lots of bug fixes
-
-Changes in Version 1.1
-- option to fetch tones into memory, causing faster access, then from hard disk
-- Memory is now locked using mlockall(), to prevent paging which causes jitter and interruption.
-- Answering machine now works with keypad information.
-- callback on internal port, if hangup with call on hold.
-- A pocket calcularor with simple terms (*, /, +, -) and floating point is added.
-- If a calls had more than two endpoints, any message has been ignored.
- This caused not to receive the retreive notification, which caused the hold
- music to continue to play.
-- minor buf fixes
-- Disconnect/release "causes" are now processed by priority, if a multipoint call is made.
-
-Changes in Version 1.2
-- bugfix: dialing of vbox-caller now works.
-- bugfix: minor answering machine announcement bug
-- fixed compiling error: h323_con.cpp (p_type not declared) thanx arne!
-- added include definition for kernel api in Makefile. Hope it works...
-- fix: dummyid is used for external calls when no caller id is available. the
- dummy id is transmitted as restricted id. if the police is called, it will
- see the dummyid rather than the pbx line id. this is used on forwarded calls
- when the caller id is not available.
-- doc: added a simple instruction to build a cross over cable.
-
-Changes in Version 2.0pre
-- NEW ISDN DRIVER SUPPORT (Forget the HiSax, now use 'mISDN'.)
-- NEW KERNEL REALTIME MODULE (mISDN_dsp.o)
-- NEW NT-MODE LIBRARY SUPPORT (now MULTIPOINT!!!)
-- NEW TE-MODE STACK SUPPORT
-- support of call suspension and retrieval (switch between calls)
-- call waiting on internal phone (calls when no bchannel is available)
-- doc: Now headlines are moved to the next page if they are at the bottom of a
- page.
-- vbox: minor speech syntax bugfix
-- up to 50 (compiler flag) dialed numbers can be recalled.
-- up to 50 (compiler flag) received calls are listed and can be replied.
-- Dialing informations are now queued by endpoint until port has received
- setup acknowledge on the outgoing connection.
-- Starting PBX without parameter gives a list of options.
-- Query option for listing available ports/cards.
-- CNIP (calling name) Some Simens switches and telephones support this.
-- Extensions no have names.
-- Timeouts can now be specified for different call states on ISDN phones.
-- Tones/Announcements can now be overridden at different call states.
-- isdn.cpp is completely reworked.
-- Tones/Announcements can be played externally, if supported by the external
- line.
-- Commandline parameters must be given on startup of pbx.
-- query option to check out the current isdn cards and protocolls.
-- Debug flags can now be used to speciallize the debug output.
-- vbox: Recorded calls can now be sent as attached sound file via email, or
- just a notifaction mail without sound file can be sent.
-- PBX now runs with highest prio (99) to get as much cpu as possible.
-- CPU scheduler now runs PBX4Linux as real time process.
-- Internal calls now use internal extension number as caller id.
-- Rework of hold/conference.
-- New option to allow an incoming h323-call to be connected at ringing state.
-- New codecs supported with h323 (speex and law)
-- COLP now works with h323
-- Answering machine now delays to avoid the dtmf tone when start recording
-- Answering machine now adds the beep behind the announcement file.
-- keypad facility dialing option
-- Conference now really works using call hold feature in conjunction with
- keypad feature
-- Picking of an incoming call on isdn now really works.
-- picking of a call forwarded to vbox
-- I fixed a bug that did not queue the dialed digits correctly before getting
- an external connecting.
-- Logfiles of calls now show the correct year.
-- Callback now rejects if no password is given or the given extension doesn't
- exist.
-- Incoming H.323 calls may now instantly connect using a special option.
-- H323 compiles faster, because the H323 includes are only used for the H323
- code part.
-- Using 'curses' for a state debugging. The current state of all instances
- is displayed on the screen including calls, endpoints and ports.
-- manny, manny more things that I forgot
-
-Changes in Version 2.0
-- fixed memory leak
-- fixed COLP bug
-- finally SUSPEND/RESUME (call parking), resume is allowed from any ISDN-port
-- some CRITICAL bugfixes
-- Fixed and reworked sample counting when playing tones. Now fast wind and
- rewind works correctly. Also 8-bit recording can be played back now.
- I hope it works now without problems.
-- An internal phone without caller id will now be rejected rather than
- treated as an extenal call.
-- Fixed bug in rejecting an external call.
-- Corrected handeling of 'inbandpatterns'.
-- Data calls will not enable DTMF detection.
-- Data calls will not use any audio transmission from user space.
-- Forward to VBOX only if call is an audio call.
-- Fixed library bug, that caused not to process keypad-information during
- setup message.
-- Fixed a 'release_complete' bug.
-- Debug information now have the correct month.
-- Fixed bug of wave-playback of voicebox recoding, caused by rework of the
- audio routines. It caused a SEGMENTATION FAULT!
-- Using threads now to send email and using libcrypto.
-- Introducing encryption of external calls using Blowfish.
-- Key exchange using RSA.
-- Fixed a bug in dialing H323-IP with numerical digits.
-- Fixed a bug that causes endpoint, which receives audio data, to crash when
- no port is related to it.
-- Fixed a bug that did not release endpoint, when it receives a disconnect
- if it has no port (parked).
-- Fixed a channel assignment bug when retrieving call. (second B-channel)
-- Now COLP with H.323 works. No more crash!
-- Park attribute was not set, which caused a crash.
-- Conference now works correctly with dsp-module.
-- Fixed a serious NT-mode process handling problem. (crash after some calls)
-- Added log file which is also displayed on the 'state' screen.
-- * Happy new year 2004 *
-
-Changes in Version 2.1
-- Fixed a bug that caused not to reply external calls (also VBOX).
-- 'genrc' now supports loading HFC-4S, HFC-8S and HFC-E1 drivers
-- Outgoing setup now expires after 8 seconds!
-- Fixed a bug that causes mISDNuser to crash during cleanup.
-- Fixed memory bug, thanx Paul!
-- hfc-4s/8s driver support (mISDN)
-- Improvement of isdn audio processing, hardware support.
-- Fixed diplay callerid bug "anonymousunknown anon"
-- Added more stable malloc (calloc) / free handling
-
-Changes in Version 2.2
-- PRI proof (2 MBit interface support when using HFC-E1)
-- Fixed data call bug
-- Improved display of PRI channels
-- Now VBOX playback says "no messages" if the last message has been deleted
- and will not play the last but one, unless the "previous" button has been
- pressed.
-
-Changes in Version 2.3
-- Fixed HFC_MULTI driver activation problem (HW_RESET was not implemented)
-- Fixed login prefix bug. Thanx Karsten V.
-- MISDN: better layer 2 check
-- Now facility informations are transfered during call to terminal
- (finally advice of charge is displayed) MUST BE ENABLED BY SETTINGS!
-- Fixed 'reply' dialing bug, that caused a crash. Thanx Karsten V.
-- Added L1 activation for NT-Mode. Fixed problems with inactive links.
-- Fixed a bug that caused subsequent data calls after a data call. Thanx JC.
-- mISDN: layer 1 now works correct with E1 cards.
-
-Changes in Version 2.4
-- Fixed parallel ringing to multiple external numbers.
-- Fixed login again (was still buggy).
-
-Changes in Version 2.5
-- Fixed callback bug. (International numbers were not detected.)
-- Fixed typos (mostly "incoming") - thanx Lars.
-- Fixed vbox-email bug - thanx Martin. (and also the compiler error)
-- Fixed compiler bug, that caused compiling without crypto lib to fail.
-- Fixed some mISDN crash problems.
-- Now it should also compile with the original CVS tree.
-- Fixed hfc_multi unloading bug - thanx Karsten!
-- Now disabling DSP_MODULE really causes DSP to be disabled.
-- Now disabling real time scheduling really works.
-- mISDNuser (CVS) now compiles with the mISDN (CVS)
-- Adding the outdial prefix to the caller ID is now possible.
-- Fixed bug that caused echo test not to work.
-- And finally hardware echo now works on HFC 4s/8s/E1 (hfc_multi)
- For echo dial 993 (Test + 3) for standard configuration.
-- Added new hfc_multi vendor IDs including "Beronet Cards".
-
-Changes in Version 2.6
-- Fixed hookflash bug in conjunction with prefix. Thanx Tobias!
-- Fixed cleanup bug when loading of ISDN driver failed.
-- Fixed mISDN bug that caused cards not to be found, if loaded in different
- order as found by kernel.
-- Fixed a bug that causes a segfault when a phone disconnects while
- parallel ringing multiple phones/ports.
-- Added capability for Point-To-Point in NT mode, including PRI.
-- Added L1 link control for NT mode.
-- Fixed bug in hfc_multi and mISDN driver that caused mISDN not to work
- with kernel > 2.6.7.
-- Fixed a but when detecting different cards with hfc_multi.
-- Fixed timer bug that caused timers of multiple NT ports not to work
- correctly.
-
-Changes in Version 2.7
-- Fixed lots of bugs.
-- Now receive stream from mISDN is disabled when not needed.
-- Added NT mode support for incoming "SETUP_ACKNOWLEDGE".
-
-Changes in Version 3.0
-- Advanced routing capability to replace the numbering_*.conf
- (Don't worry, internal and external numbering is a feature of the routing
- capability and is easy to convert.)
-- Now correct cause location is generated and handled.
-- New cause display feature. Location is displayed with the cause number.
-- Many source cleanups.
-- New interface (Unix socket) to administrate. Status informations are now
- viewable without restarting PBX. Even may processes may view status info.
- Starting / stopping state debugging, doesn't require to restart PBX.
-- Status information now has selectable details.
-- Better structure for debugging functions and better logging. (code)
-- Dialing may also be done via command line interface.
-- Now internel/external dialtone and ringing depends on internal/external call.
-- Now endpoints (partys) can be released via command line (admin tool).
-- Watchdog "pbxwatch" to automatically restart and even debug PBX4Linux.
-- Removed problem with uninitialized variable in ISDNPort object causing to
- crash. It did not happen very often.(only after some hundred/thousand calls)
-- HFC-E1 cards did not correctly synchronize to external lines.
-- dsp.o now allocates only one timeslot per call, as expected.
-- mISDNuser now correctly connects PRI calls.
-- PRI improvements and bugfixes.
-- Support for conference rooms.
-- Voice box is now able to play announcement before connecting the call.
- A special feature on the external line is required to send audio before
- answering the call.
-- It is now possible to include seconds (time) in the connect message. This
- might not be supported by all telephones, so it is an optional feature.
-- Moved open and close of recording audio to the "Port" class, where it
- belongs. The mixer will be more performant this way.
-- Notify is now supported by mISDN and also correctly handled and queued
- by PBX.
-- Fixed bug that caused not to free broadcast process IDs in certain cases.
- This would cause calls to internal phones (from extern or intern) not to
- work after a while.
-- Added HFC-S USB to 'genrc' tool.
-- printisdn now shows corret month.
-
-Changes in Version 3.0-fix1
-- Rule for changing the forwarding now works. Enter "pbx rules forward" for
- description. Also the example in "defaults/route.conf" is corrected.
-- Forking now forks twice and suppresses debug output. Closing of shell is
- possible.
-
-Changes in Version 3.0-fix2
-- Fixed memory leak bug in pbxadmin that caused to eat all memory and make it
- stop.
-- Fixed audio handling that cause forking calls to be mute. (Parallel
- forwarding causes calls to fork to multiple destinations.)
-
-Changes in Version 3.0-fix3
-- Added "nopassword" parameter for login action.
-- Fixed bolean condition bug.
-- pbxadmin will not exit if terminal size changes.
-
-Changes in Version 3.1
-- Internal structure changed. "Endpoints" and "applications" are now two
- linked classes. The code is now reusable for other projects than
- "PBX4Linux". (No added features!)
-- Some source cleanups.
-- Now keypad must be enabled for each extension if required. (settings)
-- Removed a new bug that caused remotely parked/holded calls not to be removed
- from conference. The conference got disturbed by park/hold sound from
- remote.
-- Removed bug that caused printing of unset pointers.
-
-Changes in Version 3.2
-- PBX now works with mqueue branch. This is the latest CVS source:
- * HFCmulti is ported
- * HFC-PCI is ported
- * DSP is ported
- * nt-mode lib (libi4l) is ported
- * source is now SMP (multiple processors or hyperthreading) save.
-- Fixed bug that caused not to record if annoucement is missing
-- A prefix may be specified with callback for predefined dialing after
- callback.
-- Now b-channels are displayed more compressed on admin tool.
-
-Changes in Version 3.3
-- * te-mode works
-- * te-mode layer 1 and layer 2 control works (SHORTMESSAGE)
-
-Changes in Version 3.3-fix2
-- OpenH323 midas release compiles
-- Fixed bug in MESSAGE_NOTIFY which cases display information not to dliver.
-- OpenH323 midas release works currently only with law-codecs
-- Dixed some dial string parsing for Openh323.
-
-Changes in Version 3.3-fix3
-- Rework of kernel audio briding. Much faster (less delay), dynamically
- handles jitter. Ready for future RTP / ISDNoIP modules.
-
-Changes in Version 3.4
-- Removed DSP_MODULE switch, because it will be essential for PBX operation.
-- Fixed pbxadmin offset bug.
-- Added special feature "efi" to announce caller's ID. You call, and it tells
- your caller ID. (if available) Sample set is not complete!
-- Now caller ID and type can be given for external call rule.
-- Now caller ID and type can be given for changing caller ID.
-- Removed a display bug in pbxadmin, that caused busy channels to be omitted.
-- Fixed layer 2 handling bug.
-- Increased performance of pbx-status screen. Many interfaces/calls caused
- lock up of machine.
-- Timeout condition seems to work now.
-- Timeout action seems to work now.
-
-New Verion for new name: LCR
-
-Changes in Version 0.1
-- Statefull b-channel open and closing
-- Rebuild audio flow
- Made much simpler
- Preloading and keeping transmit buffer for seamless tones and patterns.
- Recording of what is actually transmitted and received by party.
-- Logging is replaced by trace
-- New isdn interface and port structure with many features
- Interfaces can be changed at runtime.
- Interfaces can be loaded and unloaded at runtime.
-- mISDN stack fixes
-- DDI in and out on all stacks
-- Layer 1 over IP supports interconnection via IP
-- Rebuild line and b-channel hunting with individual lists
-- Screen lists for changing caller IDs
-- Multiplexing calls to multiple extensions
-- Removed all VoIP stuff to make core fast and stable (Use Asterisk for VoIP.)
-- Fixed a bug that caused some isdn connections to hang during disconnect
-- Many bug fixes
-- Many minor improvements
-- New bugs of course...
-- Rename of 'Call' instances to 'Join', because they join parties together.
-- A new remote interface for external applications is integrated
- -> Our first application is (-: *ASTERISK CHANNEL DRIVER* :-)
-
-Changes in Version 0.2
-- Fixed partyline handling
-- Stall warning
-- Audio recoriding still does not work.
-
-Changes in Version 0.3
-- Added join/release jingle options for partylines
-- Fixed bug that did not release reserved channels, so interface run out of
- channels.
-- Bugfixes...
-- Minor bugfixes
-****** Major hfc_multi bugfix *******
-* no more crash with multiple cards *
-*************************************
-- Screening bug removed. (Thanx Martin)
-- Wave files with FMT header > 16 now work.
-- Added timeouts for testcall feature. (lcradmin)
- -> You can run scripts, that generate testcalls of multiple destinations.
-- Added origin flag to correctly process last_in and last_out call logging.
-- Tones and annoucements are not overwritten if exist, during installation.
-- Screening now also works for outgoing calls (to interface)
-- Fixed VBox, also added trace debugging.
-- Nice 'Beep' after the announcement.
-- Special announcement recording without beep.
-- Filters now work for interface.conf
-- Fixed minor audio gain bug.
-- Moved timeout setting from extension to interface.conf.
-
-Changes in Version 0.4
-- Complete set of EFI samples
-
-Changes in Version 0.5
-- Preperations for Asterisk channel driver (chan_lcr)
-- Errors in information elements are now reported inside log/trace.
-- Recover bchannel (de-)activation if message from mISDN got lost
-
-Changes in Version 1.0
-- Bugfixes
-- Complete port to new mISDN V2 API (socket based).
- -> Old mISDN will not work anymore.
-- Interfaces mode (NT/TE PTP/PTMP) can now be changed at runtime.
- -> No more module parameters must be given for cards.
-- First Alpha release of chan_lcr - the Asterisk PBX channel link driver.
- -> Use LCR in conjunction with Asterisk, or simply as ISDN frontend.
-
-Changes in Version 1.1
-- Fixed dtmf bug.
-- Added more display infos
-- Fixed b-channel check bug. (channel seemed busy, even if it was free)
-- Forced proceeding, if "sending complete".
-- Removed 'lcr query'. It is obsolete, because 'isdninfo' does it.
-- Fixed lockinproblem with chan_lcr (hopefully).
-- HDLC now works and is used for B-channels, if required.
-- Briding for chan_lcr fixed, many other fixed for chan_lcr. Overlap dialing!
-- Compiling and 64-bit issues fixed by Karsten.
-- chan_lcr fixes and tests by Peter.
-- LCR now runs as user, but still can be run as root.
-- Ports can now be given with number or with name.
-
-Changes in Version 1.2
-- Changed isdninfo to misdn_info.
-- Fixed some trace bugs.
-- Fixed some layer2-link issues.
-- special interface config option "te-special" to allow transmit of all IEs
- in TE-mode. this is usefull to interconnect LCRs.
-- Introduceing autoconf (./configure) with help of Joerg and Peter.
- -> Default installation path remains /usr/local/lcr, so don't worry!
-
-Changes in Version 1.3
-- Finished autoconf.
-- Obsolete "pbxwatch" is removed.
-
-Changes after Version 1.3 release
-- fixes in chan_lcr, thanx to peter and gregor
-- message pointer forwarding fix, thanx to bodo!
-- capability fix, thanx to gregor
-- processing of second caller id
-- Dialing length can now be limited. EWSD allows only 20 digits at a time.
- -> Multiple messages are sent to dial full string.
-- Added alerting and proceeding to the goto rule.
-- Added patch by gregory, asterisk should now use faxdetection with mISDN_dsp
- disabled.
-
-Changes after Version 1.4 release
-- Bugfix: When reloading interfaces, interface will not be reopened, if
- interface was specified by name.
-- Added PID file (thanx to Joerg)
-- Added Callweaver support. (thanx to Kristijan)
-- Bugfix on timeout rules. (thanx to Benjamin)
-- Fixed dtmf detection of A-D. (thanx to Ralf)
-- Fixed Notification messages in NT-mode
- -> Notifications like diversions are now sent to terminal.
-- Added l1hold feature (requires new mISDN and mISDNuser).
-- chan_lcr: Fixed compile problem with newer versions.
-- chan_lcr: Open b-channel if asterisk indicates "PROGRESS".
- -> Also if tones are available, asterisk gets "PROGRESS" indication.
-- lcradmin displays TEI values in NT-mode PTMP
-- Added patch from Daniel
- -> Improved forking
- -> Execution action can now be done on call init or on call hangup.
-
-New release Version 1.5
-- Added GSM network support.
- -> Requires OpenBSC, GSM codec, and a BS11 base station.
- -> For more refer to www.linux-call-router.de.
-
-Changes after Version 1.5
-- Tones are restructured:
- -> mISDN_dsp.ko tones must now be specified via 'tones_dir' parameter.
- -> interface.conf has a tones_dir options for individual interfaces.
- -> interface.conf has priority over tones_dir in options.conf.
- -> exnsion's settings has pritority over other tones_dir setting.
-- Debug option now works for GSM.
-- Fixed some GSM information elements.
-- OpenBSC api changes.
-- Fixed disabling of DTMF using 'n' option of chan_lcr.
-- Added GSM IMSI dialing by using dialing "imsi-<number>".
-- Applied API change of OpenBSC.
-- Applied changes of OpenBSC main branch. LCR now works with OpenBSC main
- branch.
-- Minor fixes and source cleanups.
-- Added patch by Kai Peter to complete screening indicators. Thanx!
-- Join conference during alerting phase, so calls can be forwarded.
-- Fixed conference release bug.
-
-New release Version 1.6
-
-Changes after Version 1.6
-- Fixed bad call/conference bug in joinpbx.c
-- External interfaces must now be specified using 'extern' keyword.
- -> This prevents from selecting other interfaces when dialing out.
- -> Just add 'extern' right below your external interface definition, or give
- external interface name in routing.conf: ": extern interfaces=XXXXX"
-- Added experimental CCITT No. 5 signalling system. (for educational purpose)
-- Added socket owner/group options to options.conf
-- Fixed/simplyfied config parser. The last digit of the last line was ignored.
-- Added Keypad facility
- -> New option for chan_lcr: 'k'
- -> New dialing parameter for LCR: keypad
-- Keep up with current OpenBSC API
-- Fixed DTMF detection option with chan_lcr
-
-New release Version 1.7
-
-Changes after Version 1.7
-- Added new option to interface.conf: "nonotify" to disable notify messages.
-- Replaced polling main loop by event driven "select()" loop.
-- Also replaced polling main loop by event driven "select()" loop on chan_lcr.
-- Added "release" action and timeout to "execute" action.
-- Added queue buffer for chan_lcr sending faxes without interruption.
- -> Use options "t:q250" for disabling mISDN_dsp and adding a 250ms delay.
-- Fixed HLC (higher layer capability) modification to LCR routing.
-- Fixed chan_lcr fax queue buffer. Added LCR_TRANSFERCAPABILITY environment.
-- Fixed compiler warnings when compiling with gcc 4.3.4.
-- Fixed includes to latest mISDNuser structures.
-- Fix by Peter: NULL pointer issue in asterisk frame.
-- Fixes a locking bug in chan_lcr. Thanx to WIMPy for that report.
-- Fixed forwarding of sending-complete information.
-- Added progress messages (receive only).
-- Fixed redirection info in chan_lcr. Thanx to Dennis for the fix.
-- Added patch to play ringing tone when connected but the call is forwarded
- and ringing again. Thanx to Jacek for this patch.
-- Fixed LCR to work with the current API of OpenBSC.
-- Splitted GSM support into BS (network) and MS (mobile) part.
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!! there is no more update here, see "git log" !!
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
diff --git a/aclocal.m4 b/aclocal.m4
deleted file mode 100644
index 61989b2..0000000
--- a/aclocal.m4
+++ /dev/null
@@ -1,964 +0,0 @@
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],,
-[m4_warning([this file was generated for autoconf 2.65.
-You have another version of autoconf. It may work, but is not guaranteed to.
-If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically `autoreconf'.])])
-
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_AUTOMAKE_VERSION(VERSION)
-# ----------------------------
-# Automake X.Y traces this macro to ensure aclocal.m4 has been
-# generated from the m4 files accompanying Automake X.Y.
-# (This private macro should not be called outside this file.)
-AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.11'
-dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
-dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.1], [],
- [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
-])
-
-# _AM_AUTOCONF_VERSION(VERSION)
-# -----------------------------
-# aclocal traces this macro to find the Autoconf version.
-# This is a private macro too. Using m4_define simplifies
-# the logic in aclocal, which can simply ignore this definition.
-m4_define([_AM_AUTOCONF_VERSION], [])
-
-# AM_SET_CURRENT_AUTOMAKE_VERSION
-# -------------------------------
-# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
-# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
-AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
-
-# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
-#
-# Of course, Automake must honor this variable whenever it calls a
-# tool from the auxiliary directory. The problem is that $srcdir (and
-# therefore $ac_aux_dir as well) can be either absolute or relative,
-# depending on how configure is run. This is pretty annoying, since
-# it makes $ac_aux_dir quite unusable in subdirectories: in the top
-# source directory, any form will work fine, but in subdirectories a
-# relative path needs to be adjusted first.
-#
-# $ac_aux_dir/missing
-# fails when called from a subdirectory if $ac_aux_dir is relative
-# $top_srcdir/$ac_aux_dir/missing
-# fails if $ac_aux_dir is absolute,
-# fails when called from a subdirectory in a VPATH build with
-# a relative $ac_aux_dir
-#
-# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
-# are both prefixed by $srcdir. In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
-# start a VPATH build or use an absolute $srcdir.
-#
-# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
-# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
-# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
-# and then we would define $MISSING as
-# MISSING="\${SHELL} $am_aux_dir/missing"
-# This will work as long as MISSING is not called from configure, because
-# unfortunately $(top_srcdir) has no meaning in configure.
-# However there are other variables, like CC, which are often used in
-# configure, and could therefore not use this "fixed" $ac_aux_dir.
-#
-# Another solution, used here, is to always expand $ac_aux_dir to an
-# absolute PATH. The drawback is that using absolute paths prevent a
-# configured tree to be moved without reconfiguration.
-
-AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
-])
-
-# AM_CONDITIONAL -*- Autoconf -*-
-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 9
-
-# AM_CONDITIONAL(NAME, SHELL-CONDITION)
-# -------------------------------------
-# Define a conditional.
-AC_DEFUN([AM_CONDITIONAL],
-[AC_PREREQ(2.52)dnl
- ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
-AC_SUBST([$1_TRUE])dnl
-AC_SUBST([$1_FALSE])dnl
-_AM_SUBST_NOTMAKE([$1_TRUE])dnl
-_AM_SUBST_NOTMAKE([$1_FALSE])dnl
-m4_define([_AM_COND_VALUE_$1], [$2])dnl
-if $2; then
- $1_TRUE=
- $1_FALSE='#'
-else
- $1_TRUE='#'
- $1_FALSE=
-fi
-AC_CONFIG_COMMANDS_PRE(
-[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
- AC_MSG_ERROR([[conditional "$1" was never defined.
-Usually this means the macro was only invoked conditionally.]])
-fi])])
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 10
-
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
-# written in clear, in which case automake, when reading aclocal.m4,
-# will think it sees a *use*, and therefore will trigger all it's
-# C support machinery. Also note that it means that autoscan, seeing
-# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
-
-
-# _AM_DEPENDENCIES(NAME)
-# ----------------------
-# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
-# We try a few techniques and use that to set a single cache variable.
-#
-# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
-# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
-# dependency, and given that the user is not expected to run this macro,
-# just rely on AC_PROG_CC.
-AC_DEFUN([_AM_DEPENDENCIES],
-[AC_REQUIRE([AM_SET_DEPDIR])dnl
-AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
-AC_REQUIRE([AM_MAKE_INCLUDE])dnl
-AC_REQUIRE([AM_DEP_TRACK])dnl
-
-ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
- [$1], CXX, [depcc="$CXX" am_compiler_list=],
- [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
- [$1], UPC, [depcc="$UPC" am_compiler_list=],
- [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
-
-AC_CACHE_CHECK([dependency style of $depcc],
- [am_cv_$1_dependencies_compiler_type],
-[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_$1_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
- fi
- am__universal=false
- m4_case([$1], [CC],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac],
- [CXX],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac])
-
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
- am__obj=sub/conftest.${OBJEXT-o}
- am__minus_obj="-o $am__obj"
- case $depmode in
- gcc)
- # This depmode causes a compiler race in universal mode.
- test "$am__universal" = false || continue
- ;;
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
- # not run yet. These depmodes are late enough in the game, and
- # so weak that their functioning should not be impacted.
- am__obj=conftest.${OBJEXT-o}
- am__minus_obj=
- ;;
- none) break ;;
- esac
- if depmode=$depmode \
- source=sub/conftest.c object=$am__obj \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_$1_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_$1_dependencies_compiler_type=none
-fi
-])
-AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
-AM_CONDITIONAL([am__fastdep$1], [
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
-])
-
-
-# AM_SET_DEPDIR
-# -------------
-# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
-AC_DEFUN([AM_SET_DEPDIR],
-[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
-])
-
-
-# AM_DEP_TRACK
-# ------------
-AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE(dependency-tracking,
-[ --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors])
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
-fi
-AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
-AC_SUBST([AMDEPBACKSLASH])dnl
-_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
-])
-
-# Generate code to set up dependency tracking. -*- Autoconf -*-
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-#serial 5
-
-# _AM_OUTPUT_DEPENDENCY_COMMANDS
-# ------------------------------
-AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
-[{
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
- # are listed without --file. Let's play safe and only enable the eval
- # if we detect the quoting.
- case $CONFIG_FILES in
- *\'*) eval set x "$CONFIG_FILES" ;;
- *) set x $CONFIG_FILES ;;
- esac
- shift
- for mf
- do
- # Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # Grep'ing the whole file is not good either: AIX grep has a line
- # limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
- dirpart=`AS_DIRNAME("$mf")`
- else
- continue
- fi
- # Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
- test -z "$DEPDIR" && continue
- am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
- am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
- # Find all dependency output files, they are included files with
- # $(DEPDIR) in their names. We invoke sed twice because it is the
- # simplest approach to changing $(DEPDIR) to its actual value in the
- # expansion.
- for file in `sed -n "
- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`AS_DIRNAME(["$file"])`
- AS_MKDIR_P([$dirpart/$fdir])
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
- done
-}
-])# _AM_OUTPUT_DEPENDENCY_COMMANDS
-
-
-# AM_OUTPUT_DEPENDENCY_COMMANDS
-# -----------------------------
-# This macro should only be invoked once -- use via AC_REQUIRE.
-#
-# This code is only required when automatic dependency tracking
-# is enabled. FIXME. This creates each `.P' file that we will
-# need in order to bootstrap the dependency handling code.
-AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
-[AC_CONFIG_COMMANDS([depfiles],
- [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 8
-
-# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
-AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
-
-# Do all the work for Automake. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 16
-
-# This macro actually does too much. Some checks are only needed if
-# your package does certain things. But this isn't really a big deal.
-
-# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
-# AM_INIT_AUTOMAKE([OPTIONS])
-# -----------------------------------------------
-# The call with PACKAGE and VERSION arguments is the old style
-# call (pre autoconf-2.50), which is being phased out. PACKAGE
-# and VERSION should now be passed to AC_INIT and removed from
-# the call to AM_INIT_AUTOMAKE.
-# We support both call styles for the transition. After
-# the next Automake release, Autoconf can make the AC_INIT
-# arguments mandatory, and then we can depend on a new Autoconf
-# release and drop the old call support.
-AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.62])dnl
-dnl Autoconf wants to disallow AM_ names. We explicitly allow
-dnl the ones we care about.
-m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
-AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
-AC_REQUIRE([AC_PROG_INSTALL])dnl
-if test "`cd $srcdir && pwd`" != "`pwd`"; then
- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
- # is not polluted with repeated "-I."
- AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
- # test to see if srcdir already configured
- if test -f $srcdir/config.status; then
- AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
- fi
-fi
-
-# test whether we have cygpath
-if test -z "$CYGPATH_W"; then
- if (cygpath --version) >/dev/null 2>/dev/null; then
- CYGPATH_W='cygpath -w'
- else
- CYGPATH_W=echo
- fi
-fi
-AC_SUBST([CYGPATH_W])
-
-# Define the identity of the package.
-dnl Distinguish between old-style and new-style calls.
-m4_ifval([$2],
-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
- AC_SUBST([PACKAGE], [$1])dnl
- AC_SUBST([VERSION], [$2])],
-[_AM_SET_OPTIONS([$1])dnl
-dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
- [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
-
-_AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
-
-# Some tools Automake needs.
-AC_REQUIRE([AM_SANITY_CHECK])dnl
-AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
-AM_MISSING_PROG(AUTOCONF, autoconf)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
-AM_MISSING_PROG(AUTOHEADER, autoheader)
-AM_MISSING_PROG(MAKEINFO, makeinfo)
-AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
-AC_REQUIRE([AM_PROG_MKDIR_P])dnl
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
-AC_REQUIRE([AC_PROG_AWK])dnl
-AC_REQUIRE([AC_PROG_MAKE_SET])dnl
-AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
- [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
- [_AM_PROG_TAR([v7])])])
-_AM_IF_OPTION([no-dependencies],,
-[AC_PROVIDE_IFELSE([AC_PROG_CC],
- [_AM_DEPENDENCIES(CC)],
- [define([AC_PROG_CC],
- defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [_AM_DEPENDENCIES(CXX)],
- [define([AC_PROG_CXX],
- defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_OBJC],
- [_AM_DEPENDENCIES(OBJC)],
- [define([AC_PROG_OBJC],
- defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
-])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
-dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
-AC_CONFIG_COMMANDS_PRE(dnl
-[m4_provide_if([_AM_COMPILER_EXEEXT],
- [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-])
-
-dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
-dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
-dnl mangled by Autoconf and run in a shell conditional statement.
-m4_define([_AC_COMPILER_EXEEXT],
-m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
-
-
-# When config.status generates a header, we must update the stamp-h file.
-# This file resides in the same directory as the config header
-# that is generated. The stamp files are numbered to have different names.
-
-# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
-# loop where config.status creates the headers, so we can generate
-# our stamp files there.
-AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
-[# Compute $1's index in $config_headers.
-_am_arg=$1
-_am_stamp_count=1
-for _am_header in $config_headers :; do
- case $_am_header in
- $_am_arg | $_am_arg:* )
- break ;;
- * )
- _am_stamp_count=`expr $_am_stamp_count + 1` ;;
- esac
-done
-echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-
-# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_SH
-# ------------------
-# Define $install_sh.
-AC_DEFUN([AM_PROG_INSTALL_SH],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
- *)
- install_sh="\${SHELL} $am_aux_dir/install-sh"
- esac
-fi
-AC_SUBST(install_sh)])
-
-# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# Check whether the underlying file-system supports filenames
-# with a leading dot. For instance MS-DOS doesn't.
-AC_DEFUN([AM_SET_LEADING_DOT],
-[rm -rf .tst 2>/dev/null
-mkdir .tst 2>/dev/null
-if test -d .tst; then
- am__leading_dot=.
-else
- am__leading_dot=_
-fi
-rmdir .tst 2>/dev/null
-AC_SUBST([am__leading_dot])])
-
-# Check to see how 'make' treats includes. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# AM_MAKE_INCLUDE()
-# -----------------
-# Check to see how make treats includes.
-AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
- @echo this is the am__doit target
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
- am__include=include
- am__quote=
- _am_result=GNU
- ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- case `$am_make -s -f confmf 2> /dev/null` in #(
- *the\ am__doit\ target*)
- am__include=.include
- am__quote="\""
- _am_result=BSD
- ;;
- esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
-
-# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 6
-
-# AM_MISSING_PROG(NAME, PROGRAM)
-# ------------------------------
-AC_DEFUN([AM_MISSING_PROG],
-[AC_REQUIRE([AM_MISSING_HAS_RUN])
-$1=${$1-"${am_missing_run}$2"}
-AC_SUBST($1)])
-
-
-# AM_MISSING_HAS_RUN
-# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
-AC_DEFUN([AM_MISSING_HAS_RUN],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([missing])dnl
-if test x"${MISSING+set}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
- *)
- MISSING="\${SHELL} $am_aux_dir/missing" ;;
- esac
-fi
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
-else
- am_missing_run=
- AC_MSG_WARN([`missing' script is too old or missing])
-fi
-])
-
-# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_MKDIR_P
-# ---------------
-# Check for `mkdir -p'.
-AC_DEFUN([AM_PROG_MKDIR_P],
-[AC_PREREQ([2.60])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
-dnl while keeping a definition of mkdir_p for backward compatibility.
-dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
-dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
-dnl Makefile.ins that do not define MKDIR_P, so we do our own
-dnl adjustment using top_builddir (which is defined more often than
-dnl MKDIR_P).
-AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
-case $mkdir_p in
- [[\\/$]]* | ?:[[\\/]]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-])
-
-# Helper functions for option handling. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# _AM_MANGLE_OPTION(NAME)
-# -----------------------
-AC_DEFUN([_AM_MANGLE_OPTION],
-[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
-
-# _AM_SET_OPTION(NAME)
-# ------------------------------
-# Set option NAME. Presently that only means defining a flag for this option.
-AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
-
-# _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
-# OPTIONS is a space-separated list of Automake options.
-AC_DEFUN([_AM_SET_OPTIONS],
-[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
-
-# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
-# -------------------------------------------
-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
-AC_DEFUN([_AM_IF_OPTION],
-[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-
-# Check to make sure that the build environment is sane. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 5
-
-# AM_SANITY_CHECK
-# ---------------
-AC_DEFUN([AM_SANITY_CHECK],
-[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
-# Reject unsafe characters in $srcdir or the absolute working directory
-# name. Accept space and tab only in the latter.
-am_lf='
-'
-case `pwd` in
- *[[\\\"\#\$\&\'\`$am_lf]]*)
- AC_MSG_ERROR([unsafe absolute working directory name]);;
-esac
-case $srcdir in
- *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
- AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
-esac
-
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
-alias in your environment])
- fi
-
- test "$[2]" = conftest.file
- )
-then
- # Ok.
- :
-else
- AC_MSG_ERROR([newly created file is older than distributed files!
-Check your system clock])
-fi
-AC_MSG_RESULT(yes)])
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_STRIP
-# ---------------------
-# One issue with vendor `install' (even GNU) is that you can't
-# specify the program used to strip binaries. This is especially
-# annoying in cross-compiling environments, where the build's strip
-# is unlikely to handle the host's binaries.
-# Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in `make install-strip', and initialize
-# STRIPPROG with the value of the STRIP variable (set by the user).
-AC_DEFUN([AM_PROG_INSTALL_STRIP],
-[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
-if test "$cross_compiling" != no; then
- AC_CHECK_TOOL([STRIP], [strip], :)
-fi
-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
-AC_SUBST([INSTALL_STRIP_PROGRAM])])
-
-# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# _AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
-# This macro is traced by Automake.
-AC_DEFUN([_AM_SUBST_NOTMAKE])
-
-# AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Public sister of _AM_SUBST_NOTMAKE.
-AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
-
-# Check how to create a tarball. -*- Autoconf -*-
-
-# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# _AM_PROG_TAR(FORMAT)
-# --------------------
-# Check how to create a tarball in format FORMAT.
-# FORMAT should be one of `v7', `ustar', or `pax'.
-#
-# Substitute a variable $(am__tar) that is a command
-# writing to stdout a FORMAT-tarball containing the directory
-# $tardir.
-# tardir=directory && $(am__tar) > result.tar
-#
-# Substitute a variable $(am__untar) that extract such
-# a tarball read from stdin.
-# $(am__untar) < result.tar
-AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [tar])
-m4_if([$1], [v7],
- [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
- [m4_case([$1], [ustar],, [pax],,
- [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
-_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of `-'.
-for _am_tool in $_am_tools
-do
- case $_am_tool in
- gnutar)
- for _am_tar in tar gnutar gtar;
- do
- AM_RUN_LOG([$_am_tar --version]) && break
- done
- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
- am__untar="$_am_tar -xf -"
- ;;
- plaintar)
- # Must skip GNU tar: if it does not support --format= it doesn't create
- # ustar tarball either.
- (tar --version) >/dev/null 2>&1 && continue
- am__tar='tar chf - "$$tardir"'
- am__tar_='tar chf - "$tardir"'
- am__untar='tar xf -'
- ;;
- pax)
- am__tar='pax -L -x $1 -w "$$tardir"'
- am__tar_='pax -L -x $1 -w "$tardir"'
- am__untar='pax -r'
- ;;
- cpio)
- am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
- am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
- am__untar='cpio -i -H $1 -d'
- ;;
- none)
- am__tar=false
- am__tar_=false
- am__untar=false
- ;;
- esac
-
- # If the value was cached, stop now. We just wanted to have am__tar
- # and am__untar set.
- test -n "${am_cv_prog_tar_$1}" && break
-
- # tar/untar a dummy directory, and stop if the command works
- rm -rf conftest.dir
- mkdir conftest.dir
- echo GrepMe > conftest.dir/file
- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
- rm -rf conftest.dir
- if test -s conftest.tar; then
- AM_RUN_LOG([$am__untar <conftest.tar])
- grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
- fi
-done
-rm -rf conftest.dir
-
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
-AC_SUBST([am__tar])
-AC_SUBST([am__untar])
-]) # _AM_PROG_TAR
-
-m4_include([acinclude.m4])
diff --git a/action.cpp b/action.cpp
index b7dfc58..352efb4 100644
--- a/action.cpp
+++ b/action.cpp
@@ -1976,9 +1976,11 @@ void EndpointAppPBX::action_execute(void)
end_trace();
return;
}
+#if 0
argv[i++] = (char *)"/bin/sh";
argv[i++] = (char *)"-c";
argv[i++] = command;
+#endif
argv[i++] = command;
if ((rparam = routeparam(e_action, PARAM_PARAM))) {
argv[i++] = rparam->string_value;
@@ -1999,7 +2001,7 @@ void EndpointAppPBX::action_execute(void)
case 0:
/* To be shure there are no zombies created double fork */
if ((pid2 = fork()) == 0) {
- execve("/bin/sh", argv, environ);
+ execve(command, argv, environ);
}
else {
/* Exit immediately and release the waiting parent. The subprocess falls to init because the parent died */
diff --git a/apppbx.cpp b/apppbx.cpp
index f92f167..fff80ce 100644
--- a/apppbx.cpp
+++ b/apppbx.cpp
@@ -851,6 +851,7 @@ void EndpointAppPBX::out_setup(int cfnr)
int channel = 0;
int earlyb;
int mode = B_MODE_TRANSPARENT;
+ struct admin_list *admin;
/* set bchannel mode */
mode = e_capainfo.source_mode;
@@ -989,6 +990,21 @@ void EndpointAppPBX::out_setup(int cfnr)
port = new Pgsm_ms(PORT_TYPE_GSM_MS_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
else
#endif
+ if (mISDNport->ifport->remote) {
+ admin = admin_first;
+ while(admin) {
+ if (admin->remote_name[0] && !strcmp(admin->remote_name, mISDNport->ifport->remote_app))
+ break;
+ admin = admin->next;
+ }
+ if (!admin) {
+ trace_header("INTERFACE (remote not connected)", DIRECTION_NONE);
+ add_trace("application", NULL, "%s", mISDNport->ifport->remote_app);
+ end_trace();
+ continue;
+ }
+ port = new Premote(PORT_TYPE_REMOTE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode, admin->sock);
+ } else
port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
if (!port)
FATAL("Failed to create Port instance\n");
@@ -1208,6 +1224,21 @@ void EndpointAppPBX::out_setup(int cfnr)
port = new Pgsm_ms(PORT_TYPE_GSM_MS_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
else
#endif
+ if (mISDNport->ifport->remote) {
+ admin = admin_first;
+ while(admin) {
+ if (admin->remote_name[0] && !strcmp(admin->remote_name, mISDNport->ifport->remote_app))
+ break;
+ admin = admin->next;
+ }
+ if (!admin) {
+ trace_header("INTERFACE (remote not connected)", DIRECTION_NONE);
+ add_trace("application", NULL, "%s", mISDNport->ifport->remote_app);
+ end_trace();
+ continue;
+ }
+ port = new Premote(PORT_TYPE_REMOTE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode, admin->sock);
+ } else
port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
if (!port)
FATAL("No memory for Port instance\n");
@@ -2048,10 +2079,8 @@ void EndpointAppPBX::port_connect(struct port_list *portlist, int message_type,
/* other calls with no caller id (or not available for the extension) and force colp */
if ((e_connectinfo.id[0]=='\0' || (e_connectinfo.present==INFO_PRESENT_RESTRICTED && !e_ext.anon_ignore))&& e_ext.colp==COLP_FORCE) {
e_connectinfo.ntype = INFO_NTYPE_NOTPRESENT;
- if (portlist->port_type==PORT_TYPE_DSS1_TE_OUT
- || portlist->port_type==PORT_TYPE_DSS1_NT_OUT
- || portlist->port_type==PORT_TYPE_GSM_BS_OUT
- || portlist->port_type==PORT_TYPE_GSM_MS_OUT) { /* external extension answered */
+ if ((portlist->port_type & PORT_CLASS_DIR_MASK) == PORT_CLASS_DIR_OUT) {
+ /* external extension answered */
port = find_port_id(portlist->port_id);
if (port) {
SCPY(e_connectinfo.id, nationalize_callerinfo(port->p_dialinginfo.id, &e_connectinfo.ntype, options.national, options.international));
@@ -3530,10 +3559,7 @@ void EndpointAppPBX::pick_join(char *extensions)
break;
}
}
- if ((port->p_type==PORT_TYPE_DSS1_NT_OUT
- || port->p_type==PORT_TYPE_DSS1_TE_OUT
- || port->p_type==PORT_TYPE_GSM_BS_OUT
- || port->p_type==PORT_TYPE_GSM_MS_OUT)
+ if ((portlist->port_type & PORT_CLASS_DIR_MASK) == PORT_CLASS_DIR_OUT
&& port->p_state==PORT_STATE_OUT_ALERTING)
if (match_list(extensions, eapp->e_ext.number)) {
found = eapp;
diff --git a/chan_lcr.c b/chan_lcr.c
index f4d8378..3904c9a 100644
--- a/chan_lcr.c
+++ b/chan_lcr.c
@@ -40,7 +40,7 @@ a new call reference (ref).
The ref_was_assigned ist set to 1.
Further dialing information is queued.
After the new callref is received by special MESSAGE_NEWREF reply, new ref
-is stored in the chan_call structure.
+is stored in the chan_call structure.
The setup information is sent to LCR using MESSAGE_SETUP.
The state changes to CHAN_LCR_STATE_OUT_SETUP.
@@ -207,8 +207,6 @@ int global_change = 0;
int wake_global = 0;
int wake_pipe[2];
struct lcr_fd wake_fd;
-
-int quit;
int glob_channel = 0;
@@ -247,7 +245,7 @@ void chan_lcr_log(int type, const char *file, int line, const char *function, st
ast_text[sizeof(ast_text)-1] = '\0';
// ast_log(type, file, line, function, "[call=%s ast=%s] %s", call_text, ast_text, buffer);
- printf("[call=%s ast=%s] %s", call_text, ast_text, buffer);
+ printf("[call=%s ast=%s line=%d] %s", call_text, ast_text, line, buffer);
ast_mutex_unlock(&log_lock);
}
@@ -266,7 +264,7 @@ struct chan_call *find_call_ref(unsigned int ref)
{
struct chan_call *call = call_first;
int assigned = (ref > 0);
-
+
while(call) {
if (call->ref == ref && call->ref_was_assigned == assigned)
break;
@@ -595,8 +593,8 @@ void apply_opt(struct chan_call *call, char *data)
default:
CERROR(call, call->ast, "Option '%s' unknown.\n", opt);
}
- }
-
+ }
+
/* re-open, if bchannel is created */
if (call->bchannel && call->bchannel->b_sock > -1) {
bchannel_destroy(call->bchannel);
@@ -618,29 +616,40 @@ static void send_setup_to_lcr(struct chan_call *call)
if (!call->ast || !call->ref)
return;
+#ifdef AST_1_8_OR_HIGHER
+ CDEBUG(call, call->ast, "Sending setup to LCR. (interface=%s dialstring=%s, cid=%s)\n", call->interface, call->dialstring, call->callerinfo.id);
+#else
CDEBUG(call, call->ast, "Sending setup to LCR. (interface=%s dialstring=%s, cid=%s)\n", call->interface, call->dialstring, call->cid_num);
+#endif
/* send setup message to LCR */
memset(&newparam, 0, sizeof(union parameter));
- newparam.setup.dialinginfo.itype = INFO_ITYPE_ISDN;
- newparam.setup.dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
+ newparam.setup.dialinginfo.itype = INFO_ITYPE_ISDN;
+ newparam.setup.dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
if (call->keypad)
strncpy(newparam.setup.dialinginfo.keypad, call->dialstring, sizeof(newparam.setup.dialinginfo.keypad)-1);
else
strncpy(newparam.setup.dialinginfo.id, call->dialstring, sizeof(newparam.setup.dialinginfo.id)-1);
- strncpy(newparam.setup.dialinginfo.interfaces, call->interface, sizeof(newparam.setup.dialinginfo.interfaces)-1);
- newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;
- newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
+ if (!!strcmp(call->interface, "pbx"))
+ strncpy(newparam.setup.dialinginfo.interfaces, call->interface, sizeof(newparam.setup.dialinginfo.interfaces)-1);
+ newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;
+ newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
strncpy(newparam.setup.callerinfo.display, call->display, sizeof(newparam.setup.callerinfo.display)-1);
call->display[0] = '\0';
+
+#ifdef AST_1_8_OR_HIGHER
+ /* set stored call information */
+ memcpy(&newparam.setup.callerinfo, &call->callerinfo, sizeof(struct caller_info));
+ memcpy(&newparam.setup.redirinfo, &call->redirinfo, sizeof(struct redir_info));
+#else
if (call->cid_num[0])
strncpy(newparam.setup.callerinfo.id, call->cid_num, sizeof(newparam.setup.callerinfo.id)-1);
if (call->cid_name[0])
strncpy(newparam.setup.callerinfo.name, call->cid_name, sizeof(newparam.setup.callerinfo.name)-1);
if (call->cid_rdnis[0]) {
strncpy(newparam.setup.redirinfo.id, call->cid_rdnis, sizeof(newparam.setup.redirinfo.id)-1);
- newparam.setup.redirinfo.itype = INFO_ITYPE_CHAN;
- newparam.setup.redirinfo.ntype = INFO_NTYPE_UNKNOWN;
+ newparam.setup.redirinfo.itype = INFO_ITYPE_CHAN;
+ newparam.setup.redirinfo.ntype = INFO_NTYPE_UNKNOWN;
}
switch(ast->cid.cid_pres & AST_PRES_RESTRICTION) {
case AST_PRES_RESTRICTED:
@@ -666,6 +675,7 @@ static void send_setup_to_lcr(struct chan_call *call)
default:
newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
}
+#endif
#warning DISABLED DUE TO DOUBLE LOCKING PROBLEM
// tmp = pbx_builtin_getvar_helper(ast, "LCR_TRANSFERCAPABILITY");
// if (tmp && *tmp)
@@ -697,7 +707,7 @@ static void send_dialque_to_lcr(struct chan_call *call)
if (!call->ast || !call->ref || !call->dialque[0])
return;
-
+
CDEBUG(call, call->ast, "Sending dial queue to LCR. (dialing=%s)\n", call->dialque);
/* send setup message to LCR */
@@ -758,7 +768,7 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c
exten = "s";
CDEBUG(call, ast, "Try to start pbx. (exten=%s context=%s complete=%s)\n", exten, ast->context, complete?"yes":"no");
-
+
if (complete) {
/* if not match */
if (!ast_canmatch_extension(ast, ast->context, exten, 1, call->oad)) {
@@ -822,16 +832,16 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c
call->state = CHAN_LCR_STATE_RELEASE;
ast_hangup(ast); // call will be destroyed here
return;
-
+
start:
/* send setup to asterisk */
CDEBUG(call, ast, "Starting call to Asterisk due to matching extension.\n");
- #ifdef LCR_FOR_CALLWEAVER
+ #ifdef LCR_FOR_CALLWEAVER
ast->type = "LCR";
snprintf(ast->name, sizeof(ast->name), "LCR/%s-%04x",ast->cid.cid_num, ast_random() & 0xffff);
#endif
-
+
ret = ast_pbx_start(ast);
if (ret < 0) {
cause = (ret==-2)?34:27;
@@ -857,9 +867,13 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet
#endif
#ifdef LCR_FOR_ASTERISK
+#ifdef AST_1_8_OR_HIGHER
+ ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", "", 0, "%s/%d", lcr_type, ++glob_channel);
+#else
ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
+#endif
#endif
-
+
if (!ast) {
/* release */
CERROR(call, NULL, "Failed to create Asterisk channel - releasing.\n");
@@ -873,7 +887,7 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet
ast->tech_pvt = call;
ast->tech = &lcr_tech;
ast->fds[0] = call->pipe[0];
-
+
/* fill setup information */
if (param->setup.dialinginfo.id)
strncpy(ast->exten, param->setup.dialinginfo.id, AST_MAX_EXTENSION-1);
@@ -881,6 +895,139 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet
strncpy(ast->context, param->setup.context, AST_MAX_CONTEXT-1);
else
strncpy(ast->context, param->setup.callerinfo.interface, AST_MAX_CONTEXT-1);
+
+
+
+#ifdef AST_1_8_OR_HIGHER
+ if (param->setup.callerinfo.id[0]) {
+ ast->caller.id.number.valid = 1;
+ ast->caller.id.number.str = strdup(param->setup.callerinfo.id);
+ if (!param->setup.callerinfo.id[0]) {
+ ast->caller.id.number.presentation = AST_PRES_RESTRICTED;
+ ast->caller.id.number.plan = (0 << 4) | 1;
+ }
+ switch (param->setup.callerinfo.present) {
+ case INFO_PRESENT_ALLOWED:
+ ast->caller.id.number.presentation = AST_PRES_ALLOWED;
+ break;
+ case INFO_PRESENT_RESTRICTED:
+ ast->caller.id.number.presentation = AST_PRES_RESTRICTED;
+ break;
+ default:
+ ast->caller.id.number.presentation = AST_PRES_UNAVAILABLE;
+ }
+ switch (param->setup.callerinfo.screen) {
+ case INFO_SCREEN_USER:
+ ast->caller.id.number.presentation |= AST_PRES_USER_NUMBER_UNSCREENED;
+ break;
+ case INFO_SCREEN_USER_VERIFIED_PASSED:
+ ast->caller.id.number.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
+ break;
+ case INFO_SCREEN_USER_VERIFIED_FAILED:
+ ast->caller.id.number.presentation |= AST_PRES_USER_NUMBER_FAILED_SCREEN;
+ break;
+ default:
+ ast->caller.id.number.presentation |= AST_PRES_NETWORK_NUMBER;
+ }
+ switch (param->setup.callerinfo.ntype) {
+ case INFO_NTYPE_SUBSCRIBER:
+ ast->caller.id.number.plan = (4 << 4) | 1;
+ break;
+ case INFO_NTYPE_NATIONAL:
+ ast->caller.id.number.plan = (2 << 4) | 1;
+ break;
+ case INFO_NTYPE_INTERNATIONAL:
+ ast->caller.id.number.plan = (1 << 4) | 1;
+ break;
+ default:
+ ast->caller.id.number.plan = (0 << 4) | 1;
+ }
+ }
+ if (param->setup.callerinfo.id2[0]) {
+ ast->caller.ani.number.valid = 1;
+ ast->caller.ani.number.str = strdup(param->setup.callerinfo.id2);
+ switch (param->setup.callerinfo.present2) {
+ case INFO_PRESENT_ALLOWED:
+ ast->caller.ani.number.presentation = AST_PRES_ALLOWED;
+ break;
+ case INFO_PRESENT_RESTRICTED:
+ ast->caller.ani.number.presentation = AST_PRES_RESTRICTED;
+ break;
+ default:
+ ast->caller.ani.number.presentation = AST_PRES_UNAVAILABLE;
+ }
+ switch (param->setup.callerinfo.screen2) {
+ case INFO_SCREEN_USER:
+ ast->caller.ani.number.presentation |= AST_PRES_USER_NUMBER_UNSCREENED;
+ break;
+ case INFO_SCREEN_USER_VERIFIED_PASSED:
+ ast->caller.ani.number.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
+ break;
+ case INFO_SCREEN_USER_VERIFIED_FAILED:
+ ast->caller.ani.number.presentation |= AST_PRES_USER_NUMBER_FAILED_SCREEN;
+ break;
+ default:
+ ast->caller.ani.number.presentation |= AST_PRES_NETWORK_NUMBER;
+ }
+ switch (param->setup.callerinfo.ntype2) {
+ case INFO_NTYPE_SUBSCRIBER:
+ ast->caller.ani.number.plan = (4 << 4) | 1;
+ break;
+ case INFO_NTYPE_NATIONAL:
+ ast->caller.ani.number.plan = (2 << 4) | 1;
+ break;
+ case INFO_NTYPE_INTERNATIONAL:
+ ast->caller.ani.number.plan = (1 << 4) | 1;
+ break;
+ default:
+ ast->caller.ani.number.plan = (0 << 4) | 1;
+ }
+ }
+ if (param->setup.callerinfo.name[0]) {
+ ast->caller.id.name.valid = 1;
+ ast->caller.id.name.str = strdup(param->setup.callerinfo.name);
+ }
+ if (param->setup.redirinfo.id[0]) {
+ ast->redirecting.from.number.valid = 1;
+ ast->redirecting.from.number.str = strdup(param->setup.redirinfo.id);
+ switch (param->setup.redirinfo.present) {
+ case INFO_PRESENT_ALLOWED:
+ ast->redirecting.from.number.presentation = AST_PRES_ALLOWED;
+ break;
+ case INFO_PRESENT_RESTRICTED:
+ ast->redirecting.from.number.presentation = AST_PRES_RESTRICTED;
+ break;
+ default:
+ ast->redirecting.from.number.presentation = AST_PRES_UNAVAILABLE;
+ }
+ switch (param->setup.redirinfo.screen) {
+ case INFO_SCREEN_USER:
+ ast->redirecting.from.number.presentation |= AST_PRES_USER_NUMBER_UNSCREENED;
+ break;
+ case INFO_SCREEN_USER_VERIFIED_PASSED:
+ ast->redirecting.from.number.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
+ break;
+ case INFO_SCREEN_USER_VERIFIED_FAILED:
+ ast->redirecting.from.number.presentation |= AST_PRES_USER_NUMBER_FAILED_SCREEN;
+ break;
+ default:
+ ast->redirecting.from.number.presentation |= AST_PRES_NETWORK_NUMBER;
+ }
+ switch (param->setup.redirinfo.ntype) {
+ case INFO_NTYPE_SUBSCRIBER:
+ ast->redirecting.from.number.plan = (4 << 4) | 1;
+ break;
+ case INFO_NTYPE_NATIONAL:
+ ast->redirecting.from.number.plan = (2 << 4) | 1;
+ break;
+ case INFO_NTYPE_INTERNATIONAL:
+ ast->redirecting.from.number.plan = (1 << 4) | 1;
+ break;
+ default:
+ ast->redirecting.from.number.plan = (0 << 4) | 1;
+ }
+ }
+#else
memset(&ast->cid, 0, sizeof(ast->cid));
if (param->setup.callerinfo.id[0])
ast->cid.cid_num = strdup(param->setup.callerinfo.id);
@@ -913,6 +1060,8 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet
default:
ast->cid.cid_ton = 0;
}
+#endif
+
ast->transfercapability = param->setup.capainfo.bearer_capa;
/* enable hdlc if transcap is data */
if (param->setup.capainfo.source_mode == B_MODE_HDLC)
@@ -1080,8 +1229,8 @@ static void lcr_in_release(struct chan_call *call, int message_type, union param
call->state = CHAN_LCR_STATE_RELEASE;
/* copy release info */
if (!call->cause) {
- call->cause = param->disconnectinfo.cause;
- call->location = param->disconnectinfo.location;
+ call->cause = param->disconnectinfo.cause;
+ call->location = param->disconnectinfo.location;
}
/* if we have an asterisk instance, queue hangup, else we are done */
if (ast) {
@@ -1099,7 +1248,7 @@ static void lcr_in_release(struct chan_call *call, int message_type, union param
} else {
free_call(call);
}
-
+
}
/*
@@ -1110,7 +1259,7 @@ static void lcr_in_information(struct chan_call *call, int message_type, union p
struct ast_channel *ast = call->ast;
CDEBUG(call, call->ast, "Incoming information from LCR. (dialing=%s)\n", param->information.id);
-
+
if (!ast) return;
/* pbx not started */
@@ -1120,14 +1269,14 @@ static void lcr_in_information(struct chan_call *call, int message_type, union p
lcr_start_pbx(call, ast, param->information.sending_complete);
return;
}
-
+
/* change dailing state after setup */
if (call->state == CHAN_LCR_STATE_IN_SETUP) {
CDEBUG(call, call->ast, "Changing from SETUP to DIALING state.\n");
call->state = CHAN_LCR_STATE_IN_DIALING;
// ast_setstate(ast, AST_STATE_DIALING);
}
-
+
/* queue digits */
if (call->state == CHAN_LCR_STATE_IN_DIALING && param->information.id[0]) {
if (!wake_global) {
@@ -1303,6 +1452,10 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
CDEBUG(call, call->ast, "Join bchannel, because call is already bridged.\n");
bchannel_join(bchannel, call->bridge_id);
}
+ /* ignore all dsp features, if it is a loopback interface */
+ if (param->bchannel.isloopback)
+ call->nodsp = 1;
+
/* create only, if call exists, othewhise it bchannel is freed below... */
if (bchannel_create(bchannel, ((call->nodsp || call->faxdetect > 0)?1:0) + ((call->hdlc)?2:0), call->nodsp_queue))
bchannel_activate(bchannel, 1);
@@ -1333,7 +1486,7 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
newparam.bchannel.handle = param->bchannel.handle;
send_message(MESSAGE_BCHANNEL, 0, &newparam);
-
+
break;
default:
@@ -1344,7 +1497,7 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
/* handle new ref */
if (message_type == MESSAGE_NEWREF) {
- if (param->direction) {
+ if (param->newref.direction) {
/* new ref from lcr */
CDEBUG(NULL, NULL, "Received new ref by LCR, due to incomming call. (ref=%ld)\n", ref);
if (!ref || find_call_ref(ref)) {
@@ -1367,8 +1520,7 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
call = find_call_ref(0);
if (!call) {
/* send release, if ref does not exist */
- CDEBUG(NULL, NULL, "No call found, that requests a ref.\n");
- send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL);
+ CERROR(NULL, NULL, "No call found, that requests a ref.\n");
return 0;
}
/* store new ref */
@@ -1527,7 +1679,7 @@ static int handle_socket(struct lcr_fd *fd, unsigned int what, void *instance, i
/* read from socket */
len = read(lcr_sock, &msg, sizeof(msg));
if (len == 0) {
- CERROR(NULL, NULL, "Socket closed.\n");
+ CERROR(NULL, NULL, "Socket closed.(read)\n");
error:
CERROR(NULL, NULL, "Handling of socket failed - closing for some seconds.\n");
close_socket();
@@ -1560,7 +1712,7 @@ static int handle_socket(struct lcr_fd *fd, unsigned int what, void *instance, i
admin = admin_first;
len = write(lcr_sock, &admin->msg, sizeof(msg));
if (len == 0) {
- CERROR(NULL, NULL, "Socket closed.\n");
+ CERROR(NULL, NULL, "Socket closed.(write)\n");
goto error;
}
if (len > 0) {
@@ -1638,7 +1790,7 @@ void close_socket(void)
admin_first = NULL;
/* close socket */
- if (lcr_sock >= 0)
+ if (lcr_sock >= 0)
close(lcr_sock);
lcr_sock = -1;
global_change = 1;
@@ -1706,7 +1858,7 @@ again:
CDEBUG(call, ast, "Sending queued digit '%c' to Asterisk.\n", *p);
/* send digit to asterisk */
memset(&fr, 0, sizeof(fr));
-
+
#ifdef LCR_FOR_ASTERISK
fr.frametype = AST_FRAME_DTMF_BEGIN;
#endif
@@ -1714,16 +1866,20 @@ again:
#ifdef LCR_FOR_CALLWEAVER
fr.frametype = AST_FRAME_DTMF;
#endif
-
+
+#ifdef AST_1_8_OR_HIGHER
+ fr.subclass.integer = *p;
+#else
fr.subclass = *p;
+#endif
fr.delivery = ast_tv(0, 0);
ast_queue_frame(ast, &fr);
-
+
#ifdef LCR_FOR_ASTERISK
fr.frametype = AST_FRAME_DTMF_END;
ast_queue_frame(ast, &fr);
#endif
-
+
break;
default:
CDEBUG(call, ast, "Ignoring queued digit 0x%02x.\n", *p);
@@ -1777,23 +1933,11 @@ static void *chan_thread(void *arg)
ast_mutex_lock(&chan_lock);
- while(!quit) {
+ while(1) {
handle_queue();
select_main(0, &global_change, lock_chan, unlock_chan);
}
- close_socket();
-
- del_timer(&socket_retry);
-
- unregister_fd(&wake_fd);
- close(wake_pipe[0]);
- close(wake_pipe[1]);
-
- CERROR(NULL, NULL, "Thread exit.\n");
-
- ast_mutex_unlock(&chan_lock);
-
return NULL;
}
@@ -1801,11 +1945,15 @@ static void *chan_thread(void *arg)
* new asterisk instance
*/
static
+#ifdef AST_1_8_OR_HIGHER
+struct ast_channel *lcr_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+#else
struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
+#endif
{
char exten[256], *dial, *interface, *opt;
struct ast_channel *ast;
- struct chan_call *call;
+ struct chan_call *call;
ast_mutex_lock(&chan_lock);
CDEBUG(NULL, NULL, "Received request from Asterisk. (data=%s)\n", (char *)data);
@@ -1828,13 +1976,17 @@ struct ast_channel *lcr_request(const char *type, int format, void *data, int *c
/* create asterisk channel instrance */
#ifdef LCR_FOR_ASTERISK
+#ifdef AST_1_8_OR_HIGHER
+ ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, NULL, NULL, NULL, NULL, 0, "%s/%d", lcr_type, ++glob_channel);
+#else
ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
+#endif
#endif
-
+
#ifdef LCR_FOR_CALLWEAVER
ast = ast_channel_alloc(1);
#endif
-
+
if (!ast) {
CERROR(NULL, NULL, "Failed to create Asterisk channel.\n");
free_call(call);
@@ -1884,6 +2036,227 @@ struct ast_channel *lcr_request(const char *type, int format, void *data, int *c
strncpy(call->dialstring, dial, sizeof(call->dialstring)-1);
apply_opt(call, (char *)opt);
+#ifdef AST_1_8_OR_HIGHER
+// clone_variables(requestor, ast);
+
+#if 0
+ ast->caller.ani.number.valid= requestor->caller.ani.number.valid;
+ if (requestor->caller.ani.number.valid)
+ if (requestor->caller.ani.number.str)
+ if (requestor->caller.ani.number.str[0])
+ ast->caller.ani.number.str= strdup(requestor->caller.ani.number.str);
+ ast->caller.ani.number.plan= requestor->caller.ani.number.plan;
+ ast->caller.ani.number.presentation= requestor->caller.ani.number.presentation;
+
+ ast->caller.ani.name.valid= requestor->caller.ani.name.valid;
+ if (requestor->caller.ani.name.valid)
+ if (requestor->caller.ani.name.str)
+ if (requestor->caller.ani.name.str[0])
+ ast->caller.ani.name.str= strdup(requestor->caller.ani.name.str);
+ ast->caller.ani.name.presentation= requestor->caller.ani.name.presentation;
+
+ ast->caller.ani.subaddress.valid= requestor->caller.ani.subaddress.valid;
+ if (requestor->caller.ani.subaddress.valid)
+ if (requestor->caller.ani.subaddress.str)
+ if (requestor->caller.ani.subaddress.str[0])
+ ast->caller.ani.subaddress.str= strdup(requestor->caller.ani.subaddress.str);
+ ast->caller.ani.subaddress.type= requestor->caller.ani.subaddress.type;
+
+ ast->caller.id.number.valid= requestor->caller.id.number.valid;
+ if (requestor->caller.id.number.valid)
+ if (requestor->caller.id.number.str)
+ if (requestor->caller.id.number.str[0])
+ ast->caller.id.number.str= strdup(requestor->caller.id.number.str);
+ ast->caller.id.number.plan= requestor->caller.id.number.plan;
+ ast->caller.id.number.presentation= requestor->caller.id.number.presentation;
+
+ ast->caller.id.name.valid= requestor->caller.id.name.valid;
+ if (requestor->caller.id.name.valid)
+ if (requestor->caller.id.name.str)
+ if (requestor->caller.id.name.str[0])
+ ast->caller.id.name.str= strdup(requestor->caller.id.name.str);
+ ast->caller.id.name.presentation= requestor->caller.id.name.presentation;
+
+ ast->caller.id.subaddress.valid= requestor->caller.id.subaddress.valid;
+ if (requestor->caller.id.subaddress.valid)
+ if (requestor->caller.id.subaddress.str)
+ if (requestor->caller.id.subaddress.str[0])
+ ast->caller.id.subaddress.str= strdup(requestor->caller.id.subaddress.str);
+ ast->caller.id.subaddress.type= requestor->caller.id.subaddress.type;
+
+ if (requestor->dialed.number.str)
+ if (requestor->dialed.number.str[0])
+ ast->dialed.number.str= strdup(requestor->dialed.number.str);
+ ast->dialed.number.plan= requestor->dialed.number.plan;
+
+ ast->dialed.subaddress.valid= requestor->dialed.subaddress.valid;
+ if (requestor->dialed.subaddress.valid)
+ if (requestor->dialed.subaddress.str)
+ if (requestor->dialed.subaddress.str[0])
+ ast->dialed.subaddress.str= strdup(requestor->dialed.subaddress.str);
+ ast->dialed.subaddress.type= requestor->dialed.subaddress.type;
+
+ ast->dialed.transit_network_select= requestor->dialed.transit_network_select;
+ ast->redirecting.count= requestor->redirecting.count;
+ ast->redirecting.reason= requestor->redirecting.reason;
+
+ ast->redirecting.from.number.valid= requestor->redirecting.from.number.valid;
+ if (requestor->redirecting.from.number.valid)
+ if (requestor->redirecting.from.number.str)
+ if (requestor->redirecting.from.number.str[0])
+ ast->redirecting.from.number.str= strdup(requestor->redirecting.from.number.str);
+ ast->redirecting.from.number.plan= requestor->redirecting.from.number.plan;
+ ast->redirecting.from.number.presentation= requestor->redirecting.from.number.presentation;
+
+ ast->redirecting.to.number.valid= requestor->redirecting.to.number.valid;
+ if (requestor->redirecting.to.number.valid)
+ if (requestor->redirecting.to.number.str)
+ if (requestor->redirecting.to.number.str[0])
+ ast->redirecting.to.number.str= strdup(requestor->redirecting.to.number.str);
+ ast->redirecting.to.number.plan= requestor->redirecting.to.number.plan;
+ ast->redirecting.to.number.presentation= requestor->redirecting.to.number.presentation;
+#endif
+ /* store call information for setup */
+
+ /* caller ID */
+ if (requestor->caller.id.number.valid) {
+ if (requestor->caller.id.number.str)
+ strncpy(call->callerinfo.id, requestor->caller.id.number.str, sizeof(call->callerinfo.id)-1);
+ switch(requestor->caller.id.number.presentation & AST_PRES_RESTRICTION) {
+ case AST_PRES_RESTRICTED:
+ call->callerinfo.present = INFO_PRESENT_RESTRICTED;
+ break;
+ case AST_PRES_UNAVAILABLE:
+ call->callerinfo.present = INFO_PRESENT_NOTAVAIL;
+ break;
+ case AST_PRES_ALLOWED:
+ default:
+ call->callerinfo.present = INFO_PRESENT_ALLOWED;
+ }
+ switch(requestor->caller.id.number.presentation & AST_PRES_NUMBER_TYPE) {
+ case AST_PRES_USER_NUMBER_UNSCREENED:
+ call->callerinfo.screen = INFO_SCREEN_USER;
+ break;
+ case AST_PRES_USER_NUMBER_PASSED_SCREEN:
+ call->callerinfo.screen = INFO_SCREEN_USER_VERIFIED_PASSED;
+ break;
+ case AST_PRES_USER_NUMBER_FAILED_SCREEN:
+ call->callerinfo.screen = INFO_SCREEN_USER_VERIFIED_FAILED;
+ break;
+ default:
+ call->callerinfo.screen = INFO_SCREEN_NETWORK;
+ }
+ switch((requestor->caller.id.number.plan >> 4) & 7) {
+ case 4:
+ call->callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
+ break;
+ case 2:
+ call->callerinfo.ntype = INFO_NTYPE_NATIONAL;
+ break;
+ case 1:
+ call->callerinfo.ntype = INFO_NTYPE_INTERNATIONAL;
+ break;
+ default:
+ call->callerinfo.ntype = INFO_NTYPE_UNKNOWN;
+ }
+ } else
+ call->callerinfo.present = INFO_PRESENT_NOTAVAIL;
+
+ /* caller ID 2 */
+ if (requestor->caller.ani.number.valid) {
+ if (requestor->caller.ani.number.str)
+ strncpy(call->callerinfo.id2, requestor->caller.ani.number.str, sizeof(call->callerinfo.id2)-1);
+ switch(requestor->caller.ani.number.presentation & AST_PRES_RESTRICTION) {
+ case AST_PRES_RESTRICTED:
+ call->callerinfo.present2 = INFO_PRESENT_RESTRICTED;
+ break;
+ case AST_PRES_UNAVAILABLE:
+ call->callerinfo.present2 = INFO_PRESENT_NOTAVAIL;
+ break;
+ case AST_PRES_ALLOWED:
+ default:
+ call->callerinfo.present2 = INFO_PRESENT_ALLOWED;
+ }
+ switch(requestor->caller.ani.number.presentation & AST_PRES_NUMBER_TYPE) {
+ case AST_PRES_USER_NUMBER_UNSCREENED:
+ call->callerinfo.screen2 = INFO_SCREEN_USER;
+ break;
+ case AST_PRES_USER_NUMBER_PASSED_SCREEN:
+ call->callerinfo.screen2 = INFO_SCREEN_USER_VERIFIED_PASSED;
+ break;
+ case AST_PRES_USER_NUMBER_FAILED_SCREEN:
+ call->callerinfo.screen2 = INFO_SCREEN_USER_VERIFIED_FAILED;
+ break;
+ default:
+ call->callerinfo.screen2 = INFO_SCREEN_NETWORK;
+ }
+ switch((requestor->caller.ani.number.plan >> 4) & 7) {
+ case 4:
+ call->callerinfo.ntype2 = INFO_NTYPE_SUBSCRIBER;
+ break;
+ case 2:
+ call->callerinfo.ntype2 = INFO_NTYPE_NATIONAL;
+ break;
+ case 1:
+ call->callerinfo.ntype2 = INFO_NTYPE_INTERNATIONAL;
+ break;
+ default:
+ call->callerinfo.ntype2 = INFO_NTYPE_UNKNOWN;
+ }
+ } else
+ call->callerinfo.present2 = INFO_PRESENT_NOTAVAIL;
+
+ /* caller name */
+ if (requestor->caller.id.name.valid) {
+ if (requestor->caller.id.name.str)
+ strncpy(call->callerinfo.name, requestor->caller.id.name.str, sizeof(call->callerinfo.name)-1);
+ }
+
+ /* redir number */
+ if (requestor->redirecting.from.number.valid) {
+ call->redirinfo.itype = INFO_ITYPE_CHAN;
+ if (requestor->redirecting.from.number.str)
+ strncpy(call->redirinfo.id, requestor->redirecting.from.number.str, sizeof(call->redirinfo.id)-1);
+ switch(requestor->redirecting.from.number.presentation & AST_PRES_RESTRICTION) {
+ case AST_PRES_RESTRICTED:
+ call->redirinfo.present = INFO_PRESENT_RESTRICTED;
+ break;
+ case AST_PRES_UNAVAILABLE:
+ call->redirinfo.present = INFO_PRESENT_NOTAVAIL;
+ break;
+ case AST_PRES_ALLOWED:
+ default:
+ call->redirinfo.present = INFO_PRESENT_ALLOWED;
+ }
+ switch(requestor->redirecting.from.number.presentation & AST_PRES_NUMBER_TYPE) {
+ case AST_PRES_USER_NUMBER_UNSCREENED:
+ call->redirinfo.screen = INFO_SCREEN_USER;
+ break;
+ case AST_PRES_USER_NUMBER_PASSED_SCREEN:
+ call->redirinfo.screen = INFO_SCREEN_USER_VERIFIED_PASSED;
+ break;
+ case AST_PRES_USER_NUMBER_FAILED_SCREEN:
+ call->redirinfo.screen = INFO_SCREEN_USER_VERIFIED_FAILED;
+ break;
+ default:
+ call->redirinfo.screen = INFO_SCREEN_NETWORK;
+ }
+ switch((requestor->redirecting.from.number.plan >> 4) & 7) {
+ case 4:
+ call->redirinfo.ntype = INFO_NTYPE_SUBSCRIBER;
+ break;
+ case 2:
+ call->redirinfo.ntype = INFO_NTYPE_NATIONAL;
+ break;
+ case 1:
+ call->redirinfo.ntype = INFO_NTYPE_INTERNATIONAL;
+ break;
+ default:
+ call->redirinfo.ntype = INFO_NTYPE_UNKNOWN;
+ }
+ }
+#endif
+
ast_mutex_unlock(&chan_lock);
return ast;
}
@@ -1894,16 +2267,16 @@ struct ast_channel *lcr_request(const char *type, int format, void *data, int *c
static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
{
union parameter newparam;
- struct chan_call *call;
+ struct chan_call *call;
ast_mutex_lock(&chan_lock);
- call = ast->tech_pvt;
-
- #ifdef LCR_FOR_CALLWEAVER
- ast->type = "LCR";
- snprintf(ast->name, sizeof(ast->name), "LCR/%s-%04x",call->dialstring, ast_random() & 0xffff);
- #endif
-
+ call = ast->tech_pvt;
+
+ #ifdef LCR_FOR_CALLWEAVER
+ ast->type = "LCR";
+ snprintf(ast->name, sizeof(ast->name), "LCR/%s-%04x",call->dialstring, ast_random() & 0xffff);
+ #endif
+
if (!call) {
CERROR(NULL, ast, "Received call from Asterisk, but call instance does not exist.\n");
ast_mutex_unlock(&chan_lock);
@@ -1916,7 +2289,9 @@ static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
call->pbx_started = 1;
/* send MESSAGE_NEWREF */
memset(&newparam, 0, sizeof(union parameter));
- newparam.direction = 0; /* request from app */
+ newparam.newref.direction = 0; /* request from app */
+ if (!strcmp(call->interface, "pbx"))
+ newparam.newref.mode = 1;
send_message(MESSAGE_NEWREF, 0, &newparam);
/* set hdlc if capability requires hdlc */
@@ -1931,6 +2306,7 @@ static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
&& ast->transfercapability != INFO_BC_VIDEO)
ast->transfercapability = INFO_BC_DATAUNRESTRICTED;
+#ifndef AST_1_8_OR_HIGHER
call->cid_num[0] = 0;
call->cid_name[0] = 0;
call->cid_rdnis[0] = 0;
@@ -1938,51 +2314,51 @@ static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
if (ast->cid.cid_num) if (ast->cid.cid_num[0])
strncpy(call->cid_num, ast->cid.cid_num,
sizeof(call->cid_num)-1);
-
if (ast->cid.cid_name) if (ast->cid.cid_name[0])
- strncpy(call->cid_name, ast->cid.cid_name,
+ strncpy(call->cid_name, ast->cid.cid_name,
sizeof(call->cid_name)-1);
if (ast->cid.cid_rdnis) if (ast->cid.cid_rdnis[0])
- strncpy(call->cid_rdnis, ast->cid.cid_rdnis,
+ strncpy(call->cid_rdnis, ast->cid.cid_rdnis,
sizeof(call->cid_rdnis)-1);
+#endif
ast_mutex_unlock(&chan_lock);
- return 0;
+ return 0;
}
static void send_digit_to_chan(struct ast_channel * ast, char digit )
{
- static const char* dtmf_tones[] = {
- "!941+1336/100,!0/100", /* 0 */
- "!697+1209/100,!0/100", /* 1 */
- "!697+1336/100,!0/100", /* 2 */
- "!697+1477/100,!0/100", /* 3 */
- "!770+1209/100,!0/100", /* 4 */
- "!770+1336/100,!0/100", /* 5 */
- "!770+1477/100,!0/100", /* 6 */
- "!852+1209/100,!0/100", /* 7 */
- "!852+1336/100,!0/100", /* 8 */
- "!852+1477/100,!0/100", /* 9 */
- "!697+1633/100,!0/100", /* A */
- "!770+1633/100,!0/100", /* B */
- "!852+1633/100,!0/100", /* C */
- "!941+1633/100,!0/100", /* D */
- "!941+1209/100,!0/100", /* * */
- "!941+1477/100,!0/100" }; /* # */
-
- if (digit >= '0' && digit <='9')
- ast_playtones_start(ast,0,dtmf_tones[digit-'0'], 0);
- else if (digit >= 'A' && digit <= 'D')
- ast_playtones_start(ast,0,dtmf_tones[digit-'A'+10], 0);
- else if (digit == '*')
- ast_playtones_start(ast,0,dtmf_tones[14], 0);
- else if (digit == '#')
- ast_playtones_start(ast,0,dtmf_tones[15], 0);
- else {
- /* not handled */
+ static const char* dtmf_tones[] = {
+ "!941+1336/100,!0/100", /* 0 */
+ "!697+1209/100,!0/100", /* 1 */
+ "!697+1336/100,!0/100", /* 2 */
+ "!697+1477/100,!0/100", /* 3 */
+ "!770+1209/100,!0/100", /* 4 */
+ "!770+1336/100,!0/100", /* 5 */
+ "!770+1477/100,!0/100", /* 6 */
+ "!852+1209/100,!0/100", /* 7 */
+ "!852+1336/100,!0/100", /* 8 */
+ "!852+1477/100,!0/100", /* 9 */
+ "!697+1633/100,!0/100", /* A */
+ "!770+1633/100,!0/100", /* B */
+ "!852+1633/100,!0/100", /* C */
+ "!941+1633/100,!0/100", /* D */
+ "!941+1209/100,!0/100", /* * */
+ "!941+1477/100,!0/100" }; /* # */
+
+ if (digit >= '0' && digit <='9')
+ ast_playtones_start(ast,0,dtmf_tones[digit-'0'], 0);
+ else if (digit >= 'A' && digit <= 'D')
+ ast_playtones_start(ast,0,dtmf_tones[digit-'A'+10], 0);
+ else if (digit == '*')
+ ast_playtones_start(ast,0,dtmf_tones[14], 0);
+ else if (digit == '#')
+ ast_playtones_start(ast,0,dtmf_tones[15], 0);
+ else {
+ /* not handled */
CDEBUG(NULL, ast, "Unable to handle DTMF tone "
"'%c' for '%s'\n", digit, ast->name);
- }
+ }
}
#ifdef LCR_FOR_ASTERISK
@@ -1992,7 +2368,7 @@ static int lcr_digit_begin(struct ast_channel *ast, char digit)
static int lcr_digit(struct ast_channel *ast, char digit)
#endif
{
- struct chan_call *call;
+ struct chan_call *call;
union parameter newparam;
char buf[]="x";
@@ -2005,7 +2381,7 @@ static int lcr_digit(struct ast_channel *ast, char digit)
return 0;
ast_mutex_lock(&chan_lock);
- call = ast->tech_pvt;
+ call = ast->tech_pvt;
if (!call) {
CERROR(NULL, ast, "Received digit from Asterisk, but no call instance exists.\n");
ast_mutex_unlock(&chan_lock);
@@ -2043,17 +2419,17 @@ static int lcr_digit(struct ast_channel *ast, char digit)
static int lcr_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
int inband_dtmf = 0;
- struct chan_call *call;
+ struct chan_call *call;
#endif
ast_mutex_lock(&chan_lock);
- call = ast->tech_pvt;
+ call = ast->tech_pvt;
if (!call) {
- CERROR(NULL, ast,
- "Received digit from Asterisk, "
- "but no call instance exists.\n");
+ CERROR(NULL, ast,
+ "Received digit from Asterisk, "
+ "but no call instance exists.\n");
ast_mutex_unlock(&chan_lock);
return -1;
}
@@ -2077,18 +2453,18 @@ static int lcr_digit_end(struct ast_channel *ast, char digit, unsigned int durat
static int lcr_answer(struct ast_channel *ast)
{
union parameter newparam;
- struct chan_call *call;
+ struct chan_call *call;
ast_mutex_lock(&chan_lock);
- call = ast->tech_pvt;
+ call = ast->tech_pvt;
if (!call) {
CERROR(NULL, ast, "Received answer from Asterisk, but no call instance exists.\n");
ast_mutex_unlock(&chan_lock);
return -1;
}
-
+
CDEBUG(call, ast, "Received answer from Asterisk (maybe during lcr_bridge).\n");
-
+
/* copy connectinfo, if bridged */
if (call->bridge_call)
memcpy(&call->connectinfo, &call->bridge_call->connectinfo, sizeof(struct connect_info));
@@ -2110,20 +2486,20 @@ static int lcr_answer(struct ast_channel *ast)
/* enable keypad */
// memset(&newparam, 0, sizeof(union parameter));
// send_message(MESSAGE_ENABLEKEYPAD, call->ref, &newparam);
-
- ast_mutex_unlock(&chan_lock);
- return 0;
+
+ ast_mutex_unlock(&chan_lock);
+ return 0;
}
static int lcr_hangup(struct ast_channel *ast)
{
- struct chan_call *call;
+ struct chan_call *call;
pthread_t tid = pthread_self();
if (!pthread_equal(tid, chan_tid)) {
ast_mutex_lock(&chan_lock);
}
- call = ast->tech_pvt;
+ call = ast->tech_pvt;
if (!call) {
CERROR(NULL, ast, "Received hangup from Asterisk, but no call instance exists.\n");
if (!pthread_equal(tid, chan_tid)) {
@@ -2165,7 +2541,7 @@ static int lcr_hangup(struct ast_channel *ast)
call->state = CHAN_LCR_STATE_RELEASE;
call->ast = NULL;
}
- }
+ }
if (!pthread_equal(tid, chan_tid)) {
ast_mutex_unlock(&chan_lock);
}
@@ -2174,23 +2550,35 @@ static int lcr_hangup(struct ast_channel *ast)
static int lcr_write(struct ast_channel *ast, struct ast_frame *fr)
{
- struct chan_call *call;
+ struct chan_call *call;
struct ast_frame * f = fr;
+#ifdef AST_1_8_OR_HIGHER
+ if (!f->subclass.integer)
+#else
if (!f->subclass)
+#endif
CDEBUG(NULL, ast, "No subclass\n");
+#ifdef AST_1_8_OR_HIGHER
+ if (!(f->subclass.integer & ast->nativeformats)) {
+#else
if (!(f->subclass & ast->nativeformats)) {
+#endif
CDEBUG(NULL, ast,
- "Unexpected format. "
+ "Unexpected format. "
"Activating emergency conversion...\n");
+#ifdef AST_1_8_OR_HIGHER
+ ast_set_write_format(ast, f->subclass.integer);
+#else
ast_set_write_format(ast, f->subclass);
+#endif
f = (ast->writetrans) ? ast_translate(
ast->writetrans, fr, 0) : fr;
}
ast_mutex_lock(&chan_lock);
- call = ast->tech_pvt;
+ call = ast->tech_pvt;
if (!call) {
ast_mutex_unlock(&chan_lock);
if (f != fr) {
@@ -2210,11 +2598,11 @@ static int lcr_write(struct ast_channel *ast, struct ast_frame *fr)
static struct ast_frame *lcr_read(struct ast_channel *ast)
{
- struct chan_call *call;
+ struct chan_call *call;
int len = 0;
ast_mutex_lock(&chan_lock);
- call = ast->tech_pvt;
+ call = ast->tech_pvt;
if (!call) {
ast_mutex_unlock(&chan_lock);
return NULL;
@@ -2235,11 +2623,11 @@ static struct ast_frame *lcr_read(struct ast_channel *ast)
#ifdef LCR_FOR_ASTERISK
return &ast_null_frame;
#endif
-
+
#ifdef LCR_FOR_CALLWEAVER
return &nullframe;
#endif
-
+
}
if (len <= 0) {
close(call->pipe[0]);
@@ -2255,7 +2643,11 @@ static struct ast_frame *lcr_read(struct ast_channel *ast)
}
call->read_fr.frametype = AST_FRAME_VOICE;
+#ifdef AST_1_8_OR_HIGHER
+ call->read_fr.subclass.integer = ast->nativeformats;
+#else
call->read_fr.subclass = ast->nativeformats;
+#endif
if (call->rebuffer) {
call->read_fr.datalen = call->framepos;
call->read_fr.samples = call->framepos;
@@ -2274,20 +2666,20 @@ static struct ast_frame *lcr_read(struct ast_channel *ast)
static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, size_t datalen)
{
union parameter newparam;
- int res = 0;
- struct chan_call *call;
+ int res = 0;
+ struct chan_call *call;
const struct tone_zone_sound *ts = NULL;
ast_mutex_lock(&chan_lock);
- call = ast->tech_pvt;
+ call = ast->tech_pvt;
if (!call) {
CERROR(NULL, ast, "Received indicate from Asterisk, but no call instance exists.\n");
ast_mutex_unlock(&chan_lock);
return -1;
}
- switch (cond) {
- case AST_CONTROL_BUSY:
+ switch (cond) {
+ case AST_CONTROL_BUSY:
CDEBUG(call, ast, "Received indicate AST_CONTROL_BUSY from Asterisk.\n");
ast_setstate(ast, AST_STATE_BUSY);
if (call->state != CHAN_LCR_STATE_OUT_DISCONNECT) {
@@ -2303,7 +2695,7 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz
ts = ast_get_indication_tone(ast->zone, "busy");
}
break;
- case AST_CONTROL_CONGESTION:
+ case AST_CONTROL_CONGESTION:
CDEBUG(call, ast, "Received indicate AST_CONTROL_CONGESTION from Asterisk. (cause %d)\n", ast->hangupcause);
if (call->state != CHAN_LCR_STATE_OUT_DISCONNECT) {
/* send message to lcr */
@@ -2318,7 +2710,7 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz
ts = ast_get_indication_tone(ast->zone, "congestion");
}
break;
- case AST_CONTROL_PROCEEDING:
+ case AST_CONTROL_PROCEEDING:
CDEBUG(call, ast, "Received indicate AST_CONTROL_PROCEEDING from Asterisk.\n");
if (call->state == CHAN_LCR_STATE_IN_SETUP
|| call->state == CHAN_LCR_STATE_IN_DIALING) {
@@ -2329,7 +2721,7 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz
call->state = CHAN_LCR_STATE_IN_PROCEEDING;
}
break;
- case AST_CONTROL_RINGING:
+ case AST_CONTROL_RINGING:
CDEBUG(call, ast, "Received indicate AST_CONTROL_RINGING from Asterisk.\n");
ast_setstate(ast, AST_STATE_RING);
if (call->state == CHAN_LCR_STATE_IN_SETUP
@@ -2355,35 +2747,35 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz
send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
}
break;
- case -1:
+ case -1:
CDEBUG(call, ast, "Received indicate -1.\n");
ast_playtones_stop(ast);
- res = -1;
+ res = -1;
break;
- case AST_CONTROL_VIDUPDATE:
+ case AST_CONTROL_VIDUPDATE:
CDEBUG(call, ast, "Received indicate AST_CONTROL_VIDUPDATE.\n");
- res = -1;
- break;
- case AST_CONTROL_HOLD:
+ res = -1;
+ break;
+ case AST_CONTROL_HOLD:
CDEBUG(call, ast, "Received indicate AST_CONTROL_HOLD from Asterisk.\n");
/* send message to lcr */
memset(&newparam, 0, sizeof(union parameter));
newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
send_message(MESSAGE_NOTIFY, call->ref, &newparam);
-
+
/*start music onhold*/
#ifdef LCR_FOR_ASTERISK
ast_moh_start(ast,data,ast->musicclass);
#endif
-
+
#ifdef LCR_FOR_CALLWEAVER
ast_moh_start(ast, NULL);
#endif
-
+
call->on_hold = 1;
- break;
- case AST_CONTROL_UNHOLD:
+ break;
+ case AST_CONTROL_UNHOLD:
CDEBUG(call, ast, "Received indicate AST_CONTROL_UNHOLD from Asterisk.\n");
/* send message to lcr */
memset(&newparam, 0, sizeof(union parameter));
@@ -2391,21 +2783,21 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz
send_message(MESSAGE_NOTIFY, call->ref, &newparam);
/*stop moh*/
- ast_moh_stop(ast);
+ ast_moh_stop(ast);
call->on_hold = 0;
- break;
+ break;
#ifdef AST_CONTROL_SRCUPDATE
- case AST_CONTROL_SRCUPDATE:
+ case AST_CONTROL_SRCUPDATE:
#else
- case 20:
+ case 20:
#endif
CDEBUG(call, ast, "Received AST_CONTROL_SRCUPDATE from Asterisk.\n");
- break;
- default:
+ break;
+ default:
CERROR(call, ast, "Received indicate from Asterisk with unknown condition %d.\n", cond);
- res = -1;
+ res = -1;
break;
- }
+ }
if (ts && ts->data[0]) {
ast_playtones_start(ast, 0, ts->data, 1);
@@ -2413,7 +2805,7 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz
/* return */
ast_mutex_unlock(&chan_lock);
- return res;
+ return res;
}
/*
@@ -2421,7 +2813,7 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz
*/
static int lcr_fixup(struct ast_channel *oldast, struct ast_channel *ast)
{
- struct chan_call *call;
+ struct chan_call *call;
if (!ast) {
return -1;
@@ -2446,7 +2838,7 @@ static int lcr_fixup(struct ast_channel *oldast, struct ast_channel *ast)
*/
static int lcr_send_text(struct ast_channel *ast, const char *text)
{
- struct chan_call *call;
+ struct chan_call *call;
union parameter newparam;
ast_mutex_lock(&chan_lock);
@@ -2495,15 +2887,15 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
return AST_BRIDGE_COMPLETE;
}
- /* join, if both call instances uses dsp
+ /* join, if both call instances uses dsp
ignore the case of fax detection here it may be benificial for ISDN fax machines or pass through.
- */
+ */
if (!call1->nodsp && !call2->nodsp) {
CDEBUG(NULL, NULL, "Both calls use DSP, bridging via DSP.\n");
/* get bridge id and join */
bridge_id = new_bridge_id();
-
+
call1->bridge_id = bridge_id;
if (call1->bchannel)
bchannel_join(call1->bchannel, bridge_id);
@@ -2557,9 +2949,9 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
call2->on_hold = 0;
}
-
+
ast_mutex_unlock(&chan_lock);
-
+
while(1) {
to = -1;
who = ast_waitfor_n(carr, 2, &to);
@@ -2569,7 +2961,7 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
break;
}
f = ast_read(who);
-
+
if (!f || f->frametype == AST_FRAME_CONTROL) {
if (!f)
CDEBUG(NULL, NULL, "Got hangup.\n");
@@ -2580,14 +2972,14 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
*rc=who;
break;
}
-
+
if ( f->frametype == AST_FRAME_DTMF ) {
CDEBUG(NULL, NULL, "Got DTMF.\n");
*fo=f;
*rc=who;
break;
}
-
+
if (who == ast1) {
ast_write(ast2,f);
@@ -2595,9 +2987,9 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
else {
ast_write(ast1,f);
}
-
+
}
-
+
CDEBUG(NULL, NULL, "Releasing bridge.\n");
/* split channels */
@@ -2640,7 +3032,7 @@ static struct ast_channel_tech lcr_tech = {
#endif
.call = lcr_call,
- .bridge = lcr_bridge,
+ .bridge = lcr_bridge,
.hangup = lcr_hangup,
.answer = lcr_answer,
.read = lcr_read,
@@ -2743,8 +3135,12 @@ static struct ast_cli_entry cli_port_unload =
#ifdef LCR_FOR_ASTERISK
+#ifdef AST_1_8_OR_HIGHER
+static int lcr_config_exec(struct ast_channel *ast, const char *data)
+#else
static int lcr_config_exec(struct ast_channel *ast, void *data)
#endif
+#endif
#ifdef LCR_FOR_CALLWEAVER
static int lcr_config_exec(struct ast_channel *ast, void *data, char **argv)
@@ -2757,11 +3153,11 @@ static int lcr_config_exec(struct ast_channel *ast, void *data, char **argv)
#ifdef LCR_FOR_ASTERISK
CDEBUG(NULL, ast, "Received lcr_config (data=%s)\n", (char *)data);
#endif
-
+
#ifdef LCR_FOR_CALLWEAVER
CDEBUG(NULL, ast, "Received lcr_config (data=%s)\n", argv[0]);
#endif
-
+
/* find channel */
call = call_first;
while(call) {
@@ -2770,12 +3166,12 @@ static int lcr_config_exec(struct ast_channel *ast, void *data, char **argv)
call = call->next;
}
if (call)
-
+
#ifdef LCR_FOR_ASTERISK
apply_opt(call, (char *)data);
- #endif
-
- #ifdef LCR_FOR_CALLWEAVER
+ #endif
+
+ #ifdef LCR_FOR_CALLWEAVER
apply_opt(call, (char *)argv[0]);
#endif
@@ -2804,12 +3200,12 @@ int load_module(void)
#ifdef LCR_FOR_ASTERISK
return AST_MODULE_LOAD_DECLINE;
- #endif
-
+ #endif
+
#ifdef LCR_FOR_CALLWEAVER
return 0;
#endif
-
+
}
ast_mutex_init(&chan_lock);
@@ -2818,11 +3214,11 @@ int load_module(void)
if (bchannel_initialize()) {
CERROR(NULL, NULL, "Unable to open mISDN device\n");
close_socket();
-
+
#ifdef LCR_FOR_ASTERISK
return AST_MODULE_LOAD_DECLINE;
- #endif
-
+ #endif
+
#ifdef LCR_FOR_CALLWEAVER
return 0;
#endif
@@ -2837,29 +3233,29 @@ int load_module(void)
#ifdef LCR_FOR_ASTERISK
return AST_MODULE_LOAD_DECLINE;
- #endif
-
+ #endif
+
#ifdef LCR_FOR_CALLWEAVER
return 0;
#endif
}
ast_register_application("lcr_config", lcr_config_exec, "lcr_config",
-
+
#ifdef LCR_FOR_ASTERISK
"lcr_config(<opt><optarg>:<opt>:...)\n"
#endif
-
+
#ifdef LCR_FOR_CALLWEAVER
- "lcr_config(<opt><optarg>:<opt>:...)\n",
+ "lcr_config(<opt><optarg>:<opt>:...)\n",
#endif
-
+
"Sets LCR opts. and optargs\n"
"\n"
"The available options are:\n"
" d - Send display text on called phone, text is the optarg.\n"
" n - Don't detect dtmf tones on called channel.\n"
- " h - Force data call (HDLC).\n"
+ " h - Force data call (HDLC).\n"
" t - Disable mISDN_dsp features (required for fax application).\n"
" q - Add queue to make fax stream seamless (required for fax app).\n"
" Use queue size in miliseconds for optarg. (try 250)\n"
@@ -2882,8 +3278,8 @@ int load_module(void)
"options: \"n:t:q250\" for seamless audio transmission.\n"
);
-
-#if 0
+
+#if 0
ast_cli_register(&cli_show_lcr);
ast_cli_register(&cli_show_calls);
ast_cli_register(&cli_reload_routing);
@@ -2893,7 +3289,6 @@ int load_module(void)
ast_cli_register(&cli_port_unload);
#endif
- quit = 0;
if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0)) {
/* failed to create thread */
bchannel_deinitialize();
@@ -2902,12 +3297,12 @@ int load_module(void)
#ifdef LCR_FOR_ASTERISK
return AST_MODULE_LOAD_DECLINE;
- #endif
-
+ #endif
+
#ifdef LCR_FOR_CALLWEAVER
return 0;
#endif
-
+
}
return 0;
}
@@ -2915,15 +3310,23 @@ int load_module(void)
int unload_module(void)
{
/* First, take us out of the channel loop */
- CDEBUG(NULL, NULL, "-- Unregistering mISDN Channel Driver --\n");
+ CDEBUG(NULL, NULL, "-- Unregistering Linux-Call-Router Channel Driver --\n");
- quit = 1;
- pthread_join(chan_tid, NULL);
-
- ast_channel_unregister(&lcr_tech);
+ pthread_cancel(chan_tid);
+
+ close_socket();
- ast_unregister_application("lcr_config");
+ del_timer(&socket_retry);
+
+ unregister_fd(&wake_fd);
+ close(wake_pipe[0]);
+ close(wake_pipe[1]);
+
+// ast_mutex_unlock(&chan_lock);
+
+ ast_channel_unregister(&lcr_tech);
+ ast_unregister_application("lcr_config");
if (mISDN_created) {
bchannel_deinitialize();
diff --git a/chan_lcr.h b/chan_lcr.h
index e7ea0f5..8caa48e 100644
--- a/chan_lcr.h
+++ b/chan_lcr.h
@@ -29,6 +29,8 @@ struct chan_call {
/* queue dialing prior setup ack */
char oad[64];/* caller id in number format */
+ struct caller_info callerinfo;
+ struct redir_info redirinfo;
struct connect_info connectinfo;
/* store connectinfo form lcr */
int bridge_id;
@@ -45,9 +47,11 @@ struct chan_call {
/* LCR interface name for setup */
char dialstring[64];
/* cached dial string for setup */
+#ifndef AST_PARTY_CALLER
char cid_num[64]; /* cached cid for setup */
char cid_name[64]; /* cached cid for setup */
char cid_rdnis[64]; /* cached cid for setup */
+#endif
char display[128];
/* display for setup */
int dsp_dtmf;
diff --git a/config.h.in b/config.h.in
deleted file mode 100644
index b871dc3..0000000
--- a/config.h.in
+++ /dev/null
@@ -1,252 +0,0 @@
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if you have the <assert.h> header file. */
-#undef HAVE_ASSERT_H
-
-/* Define to 1 if you have the <asterisk/compiler.h> header file. */
-#undef HAVE_ASTERISK_COMPILER_H
-
-/* Define to 1 if you have the <ctype.h> header file. */
-#undef HAVE_CTYPE_H
-
-/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
- */
-#undef HAVE_DIRENT_H
-
-/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
-#undef HAVE_DOPRNT
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
-
-/* Define to 1 if you have the `fork' function. */
-#undef HAVE_FORK
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#undef HAVE_GETTIMEOFDAY
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define if you have libcrypto */
-#undef HAVE_LIBCRYPTO
-
-/* Define to 1 if you have the `m' library (-lm). */
-#undef HAVE_LIBM
-
-/* Define to 1 if you have the `ncurses' library (-lncurses). */
-#undef HAVE_LIBNCURSES
-
-/* Define to 1 if you have the `pthread' library (-lpthread). */
-#undef HAVE_LIBPTHREAD
-
-/* Define to 1 if `lstat' has the bug that it succeeds when given the
- zero-length file name argument. */
-#undef HAVE_LSTAT_EMPTY_STRING_BUG
-
-/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
- to 0 otherwise. */
-#undef HAVE_MALLOC
-
-/* Define to 1 if you have the `memmove' function. */
-#undef HAVE_MEMMOVE
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the `memset' function. */
-#undef HAVE_MEMSET
-
-/* Define to 1 if you have the <mISDNuser/mbuffer.h> header file. */
-#undef HAVE_MISDNUSER_MBUFFER_H
-
-/* Define to 1 if you have the `mkdir' function. */
-#undef HAVE_MKDIR
-
-/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
-#undef HAVE_NDIR_H
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#undef HAVE_NETINET_IN_H
-
-/* Define to 1 if you have the <openssl/rsa.h> header file. */
-#undef HAVE_OPENSSL_RSA_H
-
-/* Define to 1 if you have the `socket' function. */
-#undef HAVE_SOCKET
-
-/* Define to 1 if stdbool.h conforms to C99. */
-#undef HAVE_STDBOOL_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#undef HAVE_STRCASECMP
-
-/* Define to 1 if you have the `strchr' function. */
-#undef HAVE_STRCHR
-
-/* Define to 1 if you have the `strerror' function. */
-#undef HAVE_STRERROR
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the `strncasecmp' function. */
-#undef HAVE_STRNCASECMP
-
-/* Define to 1 if you have the `strstr' function. */
-#undef HAVE_STRSTR
-
-/* Define to 1 if you have the `strtol' function. */
-#undef HAVE_STRTOL
-
-/* Define to 1 if you have the `strtoul' function. */
-#undef HAVE_STRTOUL
-
-/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
- */
-#undef HAVE_SYS_DIR_H
-
-/* Define to 1 if you have the <sys/file.h> header file. */
-#undef HAVE_SYS_FILE_H
-
-/* Define to 1 if you have the <sys/ioctl.h> header file. */
-#undef HAVE_SYS_IOCTL_H
-
-/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
- */
-#undef HAVE_SYS_NDIR_H
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#undef HAVE_SYS_SOCKET_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
-#undef HAVE_SYS_WAIT_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if you have the `vfork' function. */
-#undef HAVE_VFORK
-
-/* Define to 1 if you have the <vfork.h> header file. */
-#undef HAVE_VFORK_H
-
-/* Define to 1 if you have the `vprintf' function. */
-#undef HAVE_VPRINTF
-
-/* Define to 1 if `fork' works. */
-#undef HAVE_WORKING_FORK
-
-/* Define to 1 if `vfork' works. */
-#undef HAVE_WORKING_VFORK
-
-/* Define to 1 if the system has the type `_Bool'. */
-#undef HAVE__BOOL
-
-/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
- slash. */
-#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
-
-/* Name of package */
-#undef PACKAGE
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#undef RETSIGTYPE
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
-/* Define to 1 if your <sys/time.h> declares `struct tm'. */
-#undef TM_IN_SYS_TIME
-
-/* Enable extensions on AIX 3, Interix. */
-#ifndef _ALL_SOURCE
-# undef _ALL_SOURCE
-#endif
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# undef _GNU_SOURCE
-#endif
-/* Enable threading extensions on Solaris. */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# undef _POSIX_PTHREAD_SEMANTICS
-#endif
-/* Enable extensions on HP NonStop. */
-#ifndef _TANDEM_SOURCE
-# undef _TANDEM_SOURCE
-#endif
-/* Enable general extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
-#endif
-
-
-/* Version number of package */
-#undef VERSION
-
-/* Define to 1 if on MINIX. */
-#undef _MINIX
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
- this defined. */
-#undef _POSIX_1_SOURCE
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-#undef _POSIX_SOURCE
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
- calls it, or to nothing if 'inline' is not supported under any name. */
-#ifndef __cplusplus
-#undef inline
-#endif
-
-/* Define to rpl_malloc if the replacement function should be used. */
-#undef malloc
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef pid_t
-
-/* Define as `fork' if `vfork' does not work. */
-#undef vfork
diff --git a/configure b/configure
index 5ccc9cf..4c24728 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.65 for lcr 1.7.
+# Generated by GNU Autoconf 2.65 for lcr 1.8.
#
# Report bugs to <andreas@eversberg.eu>.
#
@@ -552,8 +552,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='lcr'
PACKAGE_TARNAME='lcr'
-PACKAGE_VERSION='1.7'
-PACKAGE_STRING='lcr 1.7'
+PACKAGE_VERSION='1.8'
+PACKAGE_STRING='lcr 1.8'
PACKAGE_BUGREPORT='andreas@eversberg.eu'
PACKAGE_URL=''
@@ -1260,7 +1260,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures lcr 1.7 to adapt to many kinds of systems.
+\`configure' configures lcr 1.8 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1326,7 +1326,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of lcr 1.7:";;
+ short | recursive ) echo "Configuration of lcr 1.8:";;
esac
cat <<\_ACEOF
@@ -1430,7 +1430,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-lcr configure 1.7
+lcr configure 1.8
generated by GNU Autoconf 2.65
Copyright (C) 2009 Free Software Foundation, Inc.
@@ -1893,7 +1893,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by lcr $as_me 1.7, which was
+It was created by lcr $as_me 1.8, which was
generated by GNU Autoconf 2.65. Invocation command line was
$ $0 $@
@@ -4022,7 +4022,7 @@ fi
# Define the identity of the package.
PACKAGE=lcr
- VERSION=1.7
+ VERSION=1.8
cat >>confdefs.h <<_ACEOF
@@ -5326,6 +5326,7 @@ fi
if test "x$with_asterisk" = "xyes"; then
ast_tone_zone_sound=
+ ast_1_8_or_higher=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct tone_zone_sound in asterisk/indications.h" >&5
$as_echo_n "checking for struct tone_zone_sound in asterisk/indications.h... " >&6; }
@@ -5392,7 +5393,35 @@ as_fn_error "No ast_tone_zone_sound, confused...
See \`config.log' for more details." "$LINENO" 5; }
fi
- AST_CFLAGS="-Dtone_zone_sound=$ast_tone_zone_sound"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct ast_party_caller in asterisk/channel.h" >&5
+$as_echo_n "checking for struct ast_party_caller in asterisk/channel.h... " >&6; }
+ apc_test_result=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <asterisk.h>,
+ #include <asterisk/channel.h>
+int
+main ()
+{
+struct ast_party_caller * caller = NULL; (void) caller->id;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ apc_test_result=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $apc_test_result" >&5
+$as_echo "$apc_test_result" >&6; }
+
+ if test "x$apc_test_result" = "xyes"; then
+ ast_1_8_or_higher="-DAST_1_8_OR_HIGHER"
+ fi
+
+ AST_CFLAGS="-Dtone_zone_sound=$ast_tone_zone_sound $ast_1_8_or_higher"
+
fi
@@ -7682,7 +7711,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by lcr $as_me 1.7, which was
+This file was extended by lcr $as_me 1.8, which was
generated by GNU Autoconf 2.65. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -7748,7 +7777,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-lcr config.status 1.7
+lcr config.status 1.8
configured by $0, generated by GNU Autoconf 2.65,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 81eb404..5e01e41 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,7 +25,7 @@ dnl Boston, MA 02110-1301, USA.
dnl This keeps being the first instruction.
dnl Change the 2nd argument if the version increases
dnl 1st + 2nd argument is used for distribution package name
-AC_INIT(lcr, 1.7, andreas@eversberg.eu)
+AC_INIT(lcr, 1.8, andreas@eversberg.eu)
AC_PREREQ(2.59)
AC_CONFIG_SRCDIR([main.c])
AM_CONFIG_HEADER(config.h)
@@ -33,7 +33,7 @@ AM_CONFIG_HEADER(config.h)
# fix warnings from autoconf + automake
AC_GNU_SOURCE
# AC_USE_SYSTEM_EXTENSIONS
-AM_INIT_AUTOMAKE(lcr,1.7)
+AM_INIT_AUTOMAKE(lcr,1.8)
@@ -71,6 +71,7 @@ AS_IF([test "x$with_asterisk" != xno],
if test "x$with_asterisk" = "xyes"; then
ast_tone_zone_sound=
+ ast_1_8_or_higher=
AC_MSG_CHECKING([for struct tone_zone_sound in asterisk/indications.h])
tzs_test_result=no
@@ -108,7 +109,22 @@ if test "x$with_asterisk" = "xyes"; then
AC_MSG_FAILURE([No ast_tone_zone_sound, confused...])
fi
- AST_CFLAGS="-Dtone_zone_sound=$ast_tone_zone_sound"
+ AC_MSG_CHECKING([for struct ast_party_caller in asterisk/channel.h])
+ apc_test_result=no
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM(
+ [[#include <asterisk.h>],
+ [#include <asterisk/channel.h>]],
+ [[struct ast_party_caller * caller = NULL; (void) caller->id;]])],
+ [apc_test_result=yes])
+ AC_MSG_RESULT([$apc_test_result])
+
+ if test "x$apc_test_result" = "xyes"; then
+ ast_1_8_or_higher="-DAST_1_8_OR_HIGHER"
+ fi
+
+ AST_CFLAGS="-Dtone_zone_sound=$ast_tone_zone_sound $ast_1_8_or_higher"
+
AC_SUBST([AST_CFLAGS])
fi
diff --git a/default/gsm.conf b/default/gsm.conf
deleted file mode 100644
index 148513b..0000000
--- a/default/gsm.conf
+++ /dev/null
@@ -1,39 +0,0 @@
-# LCR GSM options
-#################
-
-# Two Loopback interfaces for audio transfer between OpenBSC and mISDN.
-# They are also used for any Osmocom-BB interface, if exists.
-# The first interface must provide B-channelis for each call mobile call.
-# The seond interface links them to LCR.
-# Use 30 B-channels unless you need more due to many TRXs or mobile stations.
-# -> Load with: "modprobe mISDN_l1loop pri=1 nchannel=30"
-# By default "mISDN_l1loop.1" and "mISDN_l1loop.2" is used.
-#interface-bsc mISDN_l1loop.1
-#interface-lcr mISDN_l1loop.2
-
-# Enable debugging of OpenBSC library.
-# Refer to OpenBSC project for debugging options.
-# By default, debugging is turned off.
-#debug DRLL:DCC:DMM:DRR:DRSL:DNM:DSMS:DMNCC:DMNSMS:DPAG:DMUX:DMEAS
-
-# Give openbsc.cnf config file
-# It will be located at /usr/local/lcr by default.
-#config openbsc.cfg
-
-# Give database of Home Location Register (HLR)
-# HLR stores all subscribers. It will be used to grant access to the network.
-# It is an Sqlite3 database. Refer to OpenBSC project for handling.
-# The database is located at /usr/local/lcr by default.
-#hlr hlr.sqlite3
-
-# To keep layer 2 connection to BS11 when quitting, use this option.
-# It is only usefull for developing. TRX will stay on.
-# Also changes in frequency, mcc, mnc, lac while keeping layer 2 will cause
-# malefunction of BSC.
-# Warning: Keeping layer 2 link may prevent emergency calls. (See below)
-#keep-l2
-
-# Write BTS-Link traffic to PCAP file.
-#pcapfile pcap
-
-
diff --git a/default/interface.conf b/default/interface.conf
index 6e19538..004df59 100644
--- a/default/interface.conf
+++ b/default/interface.conf
@@ -180,7 +180,7 @@
# of LCR. The actual interface is defined in gsm.conf.
# You may add 'extern' to make this interface the external line by default.
#[GSM]
-#gsm-ms 1 /tmp/osmocom_l2
+#gsm-ms 1
#layer1hold no
#layer2hold no
#tones no
@@ -191,6 +191,20 @@
##external
+# Use chan_lcr (Asterisk PBX interface) as internal interface.
+# The interface requires mISDN_l1loop.ko to be loaded:
+# modprobe mISDN_l1loop nchannel=8 # use up to 8 b-channels
+# The caller ID is used as extension, if "extension" parameter is given.
+# Use "screen-in % xxx" to modify any caller id to xxx.
+# An internal extension does not receive tones ("earlyb"), but sends them.
+#[ast]
+#remote asterisk
+#extension
+##screen-in % 209
+#earlyb no
+#tones yes
+
+
# Hint: Enter "lcr interface" for quick help on interface options.
diff --git a/default/options.conf b/default/options.conf
index e0e93a0..d1f4d6b 100644
--- a/default/options.conf
+++ b/default/options.conf
@@ -105,9 +105,8 @@
#socketgroup asterisk
# Enable GSM network capability.
-# This option turns LCR into a GSM network. Additional options are specified
-# in 'gsm.conf'. You also need openbsc at compile time and of yourse -
-# a base station transceiver. For more refer to LCR home page.
+# This option turns LCR into a GSM network.
+# For more refer to LCR home page and the OpenBSC page.
#
# !!! DANGER !!!
# Running a GSM network may disturb other networks and may be prossecuted by
@@ -120,3 +119,13 @@
# Enable polling in main loop.
# This feature is temporarily for test purpose. Don't enable it
#polling
+
+# Two Loopback interfaces for audio transfer between GSM/Asterisk and mISDN.
+# The first interface must provide B-channels for each GSM call or channel
+# instance, the seond interface links them to LCR.
+# Use 30 B-channels unless you need more due to more instances.
+# -> Load with: "modprobe mISDN_l1loop pri=1 nchannel=30"
+# By default "mISDN_l1loop.1" and "mISDN_l1loop.2" is used.
+#loopback-ext mISDN_l1loop.1
+#loopback-lcr mISDN_l1loop.2
+
diff --git a/depcomp b/depcomp
deleted file mode 100755
index ca5ea4e..0000000
--- a/depcomp
+++ /dev/null
@@ -1,584 +0,0 @@
-#! /bin/sh
-# depcomp - compile a program generating dependencies as side-effects
-
-scriptversion=2006-10-15.18
-
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
-# Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
-
-case $1 in
- '')
- echo "$0: No command. Try \`$0 --help' for more information." 1>&2
- exit 1;
- ;;
- -h | --h*)
- cat <<\EOF
-Usage: depcomp [--help] [--version] PROGRAM [ARGS]
-
-Run PROGRAMS ARGS to compile a file, generating dependencies
-as side-effects.
-
-Environment variables:
- depmode Dependency tracking mode.
- source Source file read by `PROGRAMS ARGS'.
- object Object file output by `PROGRAMS ARGS'.
- DEPDIR directory where to store dependencies.
- depfile Dependency file to output.
- tmpdepfile Temporary file to use when outputing dependencies.
- libtool Whether libtool is used (yes/no).
-
-Report bugs to <bug-automake@gnu.org>.
-EOF
- exit $?
- ;;
- -v | --v*)
- echo "depcomp $scriptversion"
- exit $?
- ;;
-esac
-
-if test -z "$depmode" || test -z "$source" || test -z "$object"; then
- echo "depcomp: Variables source, object and depmode must be set" 1>&2
- exit 1
-fi
-
-# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
-depfile=${depfile-`echo "$object" |
- sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
-tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
-
-rm -f "$tmpdepfile"
-
-# Some modes work just like other modes, but use different flags. We
-# parameterize here, but still list the modes in the big case below,
-# to make depend.m4 easier to write. Note that we *cannot* use a case
-# here, because this file can only contain one case statement.
-if test "$depmode" = hp; then
- # HP compiler uses -M and no extra arg.
- gccflag=-M
- depmode=gcc
-fi
-
-if test "$depmode" = dashXmstdout; then
- # This is just like dashmstdout with a different argument.
- dashmflag=-xM
- depmode=dashmstdout
-fi
-
-case "$depmode" in
-gcc3)
-## gcc 3 implements dependency tracking that does exactly what
-## we want. Yay! Note: for some reason libtool 1.4 doesn't like
-## it if -MD -MP comes after the -MF stuff. Hmm.
-## Unfortunately, FreeBSD c89 acceptance of flags depends upon
-## the command line argument order; so add the flags where they
-## appear in depend2.am. Note that the slowdown incurred here
-## affects only configure: in makefiles, %FASTDEP% shortcuts this.
- for arg
- do
- case $arg in
- -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
- *) set fnord "$@" "$arg" ;;
- esac
- shift # fnord
- shift # $arg
- done
- "$@"
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- mv "$tmpdepfile" "$depfile"
- ;;
-
-gcc)
-## There are various ways to get dependency output from gcc. Here's
-## why we pick this rather obscure method:
-## - Don't want to use -MD because we'd like the dependencies to end
-## up in a subdir. Having to rename by hand is ugly.
-## (We might end up doing this anyway to support other compilers.)
-## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
-## -MM, not -M (despite what the docs say).
-## - Using -M directly means running the compiler twice (even worse
-## than renaming).
- if test -z "$gccflag"; then
- gccflag=-MD,
- fi
- "$@" -Wp,"$gccflag$tmpdepfile"
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- rm -f "$depfile"
- echo "$object : \\" > "$depfile"
- alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
-## The second -e expression handles DOS-style file names with drive letters.
- sed -e 's/^[^:]*: / /' \
- -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
-## This next piece of magic avoids the `deleted header file' problem.
-## The problem is that when a header file which appears in a .P file
-## is deleted, the dependency causes make to die (because there is
-## typically no way to rebuild the header). We avoid this by adding
-## dummy dependencies for each header file. Too bad gcc doesn't do
-## this for us directly.
- tr ' ' '
-' < "$tmpdepfile" |
-## Some versions of gcc put a space before the `:'. On the theory
-## that the space means something, we add a space to the output as
-## well.
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-hp)
- # This case exists only to let depend.m4 do its work. It works by
- # looking at the text of this script. This case will never be run,
- # since it is checked for above.
- exit 1
- ;;
-
-sgi)
- if test "$libtool" = yes; then
- "$@" "-Wp,-MDupdate,$tmpdepfile"
- else
- "$@" -MDupdate "$tmpdepfile"
- fi
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- rm -f "$depfile"
-
- if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
- echo "$object : \\" > "$depfile"
-
- # Clip off the initial element (the dependent). Don't try to be
- # clever and replace this with sed code, as IRIX sed won't handle
- # lines with more than a fixed number of characters (4096 in
- # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
- # the IRIX cc adds comments like `#:fec' to the end of the
- # dependency line.
- tr ' ' '
-' < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
- tr '
-' ' ' >> $depfile
- echo >> $depfile
-
- # The second pass generates a dummy entry for each header file.
- tr ' ' '
-' < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
- >> $depfile
- else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
-
-aix)
- # The C for AIX Compiler uses -M and outputs the dependencies
- # in a .u file. In older versions, this file always lives in the
- # current directory. Also, the AIX compiler puts `$object:' at the
- # start of each line; $object doesn't have directory information.
- # Version 6 uses the directory in both cases.
- stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
- tmpdepfile="$stripped.u"
- if test "$libtool" = yes; then
- "$@" -Wc,-M
- else
- "$@" -M
- fi
- stat=$?
-
- if test -f "$tmpdepfile"; then :
- else
- stripped=`echo "$stripped" | sed 's,^.*/,,'`
- tmpdepfile="$stripped.u"
- fi
-
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
-
- if test -f "$tmpdepfile"; then
- outname="$stripped.o"
- # Each line is of the form `foo.o: dependent.h'.
- # Do two passes, one to just change these to
- # `$object: dependent.h' and one to simply `dependent.h:'.
- sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
- sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
- else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
-
-icc)
- # Intel's C compiler understands `-MD -MF file'. However on
- # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
- # ICC 7.0 will fill foo.d with something like
- # foo.o: sub/foo.c
- # foo.o: sub/foo.h
- # which is wrong. We want:
- # sub/foo.o: sub/foo.c
- # sub/foo.o: sub/foo.h
- # sub/foo.c:
- # sub/foo.h:
- # ICC 7.1 will output
- # foo.o: sub/foo.c sub/foo.h
- # and will wrap long lines using \ :
- # foo.o: sub/foo.c ... \
- # sub/foo.h ... \
- # ...
-
- "$@" -MD -MF "$tmpdepfile"
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- rm -f "$depfile"
- # Each line is of the form `foo.o: dependent.h',
- # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
- # Do two passes, one to just change these to
- # `$object: dependent.h' and one to simply `dependent.h:'.
- sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
- # Some versions of the HPUX 10.20 sed can't process this invocation
- # correctly. Breaking it into two sed invocations is a workaround.
- sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
- sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-hp2)
- # The "hp" stanza above does not work with aCC (C++) and HP's ia64
- # compilers, which have integrated preprocessors. The correct option
- # to use with these is +Maked; it writes dependencies to a file named
- # 'foo.d', which lands next to the object file, wherever that
- # happens to be.
- # Much of this is similar to the tru64 case; see comments there.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
- if test "$libtool" = yes; then
- tmpdepfile1=$dir$base.d
- tmpdepfile2=$dir.libs/$base.d
- "$@" -Wc,+Maked
- else
- tmpdepfile1=$dir$base.d
- tmpdepfile2=$dir$base.d
- "$@" +Maked
- fi
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile1" "$tmpdepfile2"
- exit $stat
- fi
-
- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
- do
- test -f "$tmpdepfile" && break
- done
- if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
- # Add `dependent.h:' lines.
- sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
- else
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile" "$tmpdepfile2"
- ;;
-
-tru64)
- # The Tru64 compiler uses -MD to generate dependencies as a side
- # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
- # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
- # dependencies in `foo.d' instead, so we check for that too.
- # Subdirectories are respected.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
-
- if test "$libtool" = yes; then
- # With Tru64 cc, shared objects can also be used to make a
- # static library. This mechanism is used in libtool 1.4 series to
- # handle both shared and static libraries in a single compilation.
- # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
- #
- # With libtool 1.5 this exception was removed, and libtool now
- # generates 2 separate objects for the 2 libraries. These two
- # compilations output dependencies in $dir.libs/$base.o.d and
- # in $dir$base.o.d. We have to check for both files, because
- # one of the two compilations can be disabled. We should prefer
- # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
- # automatically cleaned when .libs/ is deleted, while ignoring
- # the former would cause a distcleancheck panic.
- tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
- tmpdepfile2=$dir$base.o.d # libtool 1.5
- tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
- tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
- "$@" -Wc,-MD
- else
- tmpdepfile1=$dir$base.o.d
- tmpdepfile2=$dir$base.d
- tmpdepfile3=$dir$base.d
- tmpdepfile4=$dir$base.d
- "$@" -MD
- fi
-
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- exit $stat
- fi
-
- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- do
- test -f "$tmpdepfile" && break
- done
- if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- # That's a tab and a space in the [].
- sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
- else
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
-
-#nosideeffect)
- # This comment above is used by automake to tell side-effect
- # dependency tracking mechanisms from slower ones.
-
-dashmstdout)
- # Important note: in order to support this mode, a compiler *must*
- # always write the preprocessed file to stdout, regardless of -o.
- "$@" || exit $?
-
- # Remove the call to Libtool.
- if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
- shift
- done
- shift
- fi
-
- # Remove `-o $object'.
- IFS=" "
- for arg
- do
- case $arg in
- -o)
- shift
- ;;
- $object)
- shift
- ;;
- *)
- set fnord "$@" "$arg"
- shift # fnord
- shift # $arg
- ;;
- esac
- done
-
- test -z "$dashmflag" && dashmflag=-M
- # Require at least two characters before searching for `:'
- # in the target name. This is to cope with DOS-style filenames:
- # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
- "$@" $dashmflag |
- sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
- rm -f "$depfile"
- cat < "$tmpdepfile" > "$depfile"
- tr ' ' '
-' < "$tmpdepfile" | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-dashXmstdout)
- # This case only exists to satisfy depend.m4. It is never actually
- # run, as this mode is specially recognized in the preamble.
- exit 1
- ;;
-
-makedepend)
- "$@" || exit $?
- # Remove any Libtool call
- if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
- shift
- done
- shift
- fi
- # X makedepend
- shift
- cleared=no
- for arg in "$@"; do
- case $cleared in
- no)
- set ""; shift
- cleared=yes ;;
- esac
- case "$arg" in
- -D*|-I*)
- set fnord "$@" "$arg"; shift ;;
- # Strip any option that makedepend may not understand. Remove
- # the object too, otherwise makedepend will parse it as a source file.
- -*|$object)
- ;;
- *)
- set fnord "$@" "$arg"; shift ;;
- esac
- done
- obj_suffix="`echo $object | sed 's/^.*\././'`"
- touch "$tmpdepfile"
- ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
- rm -f "$depfile"
- cat < "$tmpdepfile" > "$depfile"
- sed '1,2d' "$tmpdepfile" | tr ' ' '
-' | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile" "$tmpdepfile".bak
- ;;
-
-cpp)
- # Important note: in order to support this mode, a compiler *must*
- # always write the preprocessed file to stdout.
- "$@" || exit $?
-
- # Remove the call to Libtool.
- if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
- shift
- done
- shift
- fi
-
- # Remove `-o $object'.
- IFS=" "
- for arg
- do
- case $arg in
- -o)
- shift
- ;;
- $object)
- shift
- ;;
- *)
- set fnord "$@" "$arg"
- shift # fnord
- shift # $arg
- ;;
- esac
- done
-
- "$@" -E |
- sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
- -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
- sed '$ s: \\$::' > "$tmpdepfile"
- rm -f "$depfile"
- echo "$object : \\" > "$depfile"
- cat < "$tmpdepfile" >> "$depfile"
- sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-msvisualcpp)
- # Important note: in order to support this mode, a compiler *must*
- # always write the preprocessed file to stdout, regardless of -o,
- # because we must use -o when running libtool.
- "$@" || exit $?
- IFS=" "
- for arg
- do
- case "$arg" in
- "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
- set fnord "$@"
- shift
- shift
- ;;
- *)
- set fnord "$@" "$arg"
- shift
- shift
- ;;
- esac
- done
- "$@" -E |
- sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
- rm -f "$depfile"
- echo "$object : \\" > "$depfile"
- . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
- echo " " >> "$depfile"
- . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-none)
- exec "$@"
- ;;
-
-*)
- echo "Unknown depmode $depmode" 1>&2
- exit 1
- ;;
-esac
-
-exit 0
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/gsm.cpp b/gsm.cpp
index 7245632..119f0f5 100644
--- a/gsm.cpp
+++ b/gsm.cpp
@@ -24,6 +24,167 @@ struct lcr_gsm *gsm = NULL;
int new_callref = 1;
+/* names of MNCC-SAP */
+static const struct _value_string {
+ int msg_type;
+ const char *name;
+} mncc_names[] = {
+#if defined(MNCC_SETUP_REQ)
+ { MNCC_SETUP_REQ, "MNCC_SETUP_REQ" },
+#endif
+#if defined(MNCC_SETUP_IND)
+ { MNCC_SETUP_IND, "MNCC_SETUP_IND" },
+#endif
+#if defined(MNCC_SETUP_RSP)
+ { MNCC_SETUP_RSP, "MNCC_SETUP_RSP" },
+#endif
+#if defined(MNCC_SETUP_CNF)
+ { MNCC_SETUP_CNF, "MNCC_SETUP_CNF" },
+#endif
+#if defined(MNCC_SETUP_COMPL_REQ)
+ { MNCC_SETUP_COMPL_REQ, "MNCC_SETUP_COMPL_REQ" },
+#endif
+#if defined(MNCC_SETUP_COMPL_IND)
+ { MNCC_SETUP_COMPL_IND, "MNCC_SETUP_COMPL_IND" },
+#endif
+#if defined(MNCC_CALL_CONF_IND)
+ { MNCC_CALL_CONF_IND, "MNCC_CALL_CONF_IND" },
+#endif
+#if defined(MNCC_CALL_PROC_REQ)
+ { MNCC_CALL_PROC_REQ, "MNCC_CALL_PROC_REQ" },
+#endif
+#if defined(MNCC_PROGRESS_REQ)
+ { MNCC_PROGRESS_REQ, "MNCC_PROGRESS_REQ" },
+#endif
+#if defined(MNCC_ALERT_REQ)
+ { MNCC_ALERT_REQ, "MNCC_ALERT_REQ" },
+#endif
+#if defined(MNCC_ALERT_IND)
+ { MNCC_ALERT_IND, "MNCC_ALERT_IND" },
+#endif
+#if defined(MNCC_NOTIFY_REQ)
+ { MNCC_NOTIFY_REQ, "MNCC_NOTIFY_REQ" },
+#endif
+#if defined(MNCC_NOTIFY_IND)
+ { MNCC_NOTIFY_IND, "MNCC_NOTIFY_IND" },
+#endif
+#if defined(MNCC_DISC_REQ)
+ { MNCC_DISC_REQ, "MNCC_DISC_REQ" },
+#endif
+#if defined(MNCC_DISC_IND)
+ { MNCC_DISC_IND, "MNCC_DISC_IND" },
+#endif
+#if defined(MNCC_REL_REQ)
+ { MNCC_REL_REQ, "MNCC_REL_REQ" },
+#endif
+#if defined(MNCC_REL_IND)
+ { MNCC_REL_IND, "MNCC_REL_IND" },
+#endif
+#if defined(MNCC_REL_CNF)
+ { MNCC_REL_CNF, "MNCC_REL_CNF" },
+#endif
+#if defined(MNCC_FACILITY_REQ)
+ { MNCC_FACILITY_REQ, "MNCC_FACILITY_REQ" },
+#endif
+#if defined(MNCC_FACILITY_IND)
+ { MNCC_FACILITY_IND, "MNCC_FACILITY_IND" },
+#endif
+#if defined(MNCC_START_DTMF_IND)
+ { MNCC_START_DTMF_IND, "MNCC_START_DTMF_IND" },
+#endif
+#if defined(MNCC_START_DTMF_RSP)
+ { MNCC_START_DTMF_RSP, "MNCC_START_DTMF_RSP" },
+#endif
+#if defined(MNCC_START_DTMF_REJ)
+ { MNCC_START_DTMF_REJ, "MNCC_START_DTMF_REJ" },
+#endif
+#if defined(MNCC_STOP_DTMF_IND)
+ { MNCC_STOP_DTMF_IND, "MNCC_STOP_DTMF_IND" },
+#endif
+#if defined(MNCC_STOP_DTMF_RSP)
+ { MNCC_STOP_DTMF_RSP, "MNCC_STOP_DTMF_RSP" },
+#endif
+#if defined(MNCC_MODIFY_REQ)
+ { MNCC_MODIFY_REQ, "MNCC_MODIFY_REQ" },
+#endif
+#if defined(MNCC_MODIFY_IND)
+ { MNCC_MODIFY_IND, "MNCC_MODIFY_IND" },
+#endif
+#if defined(MNCC_MODIFY_RSP)
+ { MNCC_MODIFY_RSP, "MNCC_MODIFY_RSP" },
+#endif
+#if defined(MNCC_MODIFY_CNF)
+ { MNCC_MODIFY_CNF, "MNCC_MODIFY_CNF" },
+#endif
+#if defined(MNCC_MODIFY_REJ)
+ { MNCC_MODIFY_REJ, "MNCC_MODIFY_REJ" },
+#endif
+#if defined(MNCC_HOLD_IND)
+ { MNCC_HOLD_IND, "MNCC_HOLD_IND" },
+#endif
+#if defined(MNCC_HOLD_CNF)
+ { MNCC_HOLD_CNF, "MNCC_HOLD_CNF" },
+#endif
+#if defined(MNCC_HOLD_REJ)
+ { MNCC_HOLD_REJ, "MNCC_HOLD_REJ" },
+#endif
+#if defined(MNCC_RETRIEVE_IND)
+ { MNCC_RETRIEVE_IND, "MNCC_RETRIEVE_IND" },
+#endif
+#if defined(MNCC_RETRIEVE_CNF)
+ { MNCC_RETRIEVE_CNF, "MNCC_RETRIEVE_CNF" },
+#endif
+#if defined(MNCC_RETRIEVE_REJ)
+ { MNCC_RETRIEVE_REJ, "MNCC_RETRIEVE_REJ" },
+#endif
+#if defined(MNCC_USERINFO_REQ)
+ { MNCC_USERINFO_REQ, "MNCC_USERINFO_REQ" },
+#endif
+#if defined(MNCC_USERINFO_IND)
+ { MNCC_USERINFO_IND, "MNCC_USERINFO_IND" },
+#endif
+#if defined(MNCC_REJ_REQ)
+ { MNCC_REJ_REQ, "MNCC_REJ_REQ" },
+#endif
+#if defined(MNCC_REJ_IND)
+ { MNCC_REJ_IND, "MNCC_REJ_IND" },
+#endif
+#if defined(MNCC_PROGRESS_IND)
+ { MNCC_PROGRESS_IND, "MNCC_PROGRESS_IND" },
+#endif
+#if defined(MNCC_CALL_PROC_IND)
+ { MNCC_CALL_PROC_IND, "MNCC_CALL_PROC_IND" },
+#endif
+#if defined(MNCC_CALL_CONF_REQ)
+ { MNCC_CALL_CONF_REQ, "MNCC_CALL_CONF_REQ" },
+#endif
+#if defined(MNCC_START_DTMF_REQ)
+ { MNCC_START_DTMF_REQ, "MNCC_START_DTMF_REQ" },
+#endif
+#if defined(MNCC_STOP_DTMF_REQ)
+ { MNCC_STOP_DTMF_REQ, "MNCC_STOP_DTMF_REQ" },
+#endif
+#if defined(MNCC_HOLD_REQ)
+ { MNCC_HOLD_REQ, "MNCC_HOLD_REQ " },
+#endif
+#if defined(MNCC_RETRIEVE_REQ)
+ { MNCC_RETRIEVE_REQ, "MNCC_RETRIEVE_REQ" },
+#endif
+ { 0, NULL }
+};
+
+const char *mncc_name(int value)
+{
+ int i = 0;
+
+ while (mncc_names[i].name) {
+ if (mncc_names[i].msg_type == value)
+ return mncc_names[i].name;
+ i++;
+ }
+ return "unknown";
+}
+
/*
* create and send mncc message
*/
@@ -38,14 +199,16 @@ struct gsm_mncc *create_mncc(int msg_type, unsigned int callref)
}
int send_and_free_mncc(void *instance, unsigned int msg_type, void *data)
{
- int ret;
+ int ret = 0;
+ if (instance) {
#ifdef WITH_GSM_BS
- ret = mncc_send((struct gsm_network *)instance, msg_type, data);
+ ret = mncc_send((struct gsm_network *)instance, msg_type, data);
#endif
#ifdef WITH_GSM_MS
- ret = mncc_send((struct osmocom_ms *)instance, msg_type, data);
+ ret = mncc_send((struct osmocom_ms *)instance, msg_type, data);
#endif
+ }
free(data);
return ret;
@@ -119,7 +282,7 @@ void Pgsm::bchannel_close(void)
static int b_handler(struct lcr_fd *fd, unsigned int what, void *instance, int index);
-/* open bsc side bchannel */
+/* open external side bchannel */
int Pgsm::bchannel_open(int index)
{
int ret;
@@ -145,7 +308,7 @@ int Pgsm::bchannel_open(int index)
/* bind socket to bchannel */
addr.family = AF_ISDN;
- addr.dev = gsm->gsm_port;
+ addr.dev = mISDNloop.port;
addr.channel = index+1+(index>15);
ret = bind(p_m_g_gsm_b_sock, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
@@ -257,13 +420,13 @@ void Pgsm::frame_receive(void *arg)
/*
* create trace
- **/
+ */
void gsm_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg_type, int direction)
{
char msgtext[64];
/* select message and primitive text */
- SCPY(msgtext, get_mncc_name(msg_type));
+ SCPY(msgtext, mncc_name(msg_type));
/* add direction */
if (port) {
@@ -295,70 +458,10 @@ void gsm_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned
msgtext);
}
-/* select bchannel */
+/* select free bchannel from loopback interface */
int Pgsm::hunt_bchannel(void)
{
- int channel;
- int i;
- char map[p_m_mISDNport->b_num];
- struct interface *interface;
- struct interface_port *ifport;
-
- chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (setup)", DIRECTION_NONE);
- add_trace("channel", "reserved", "%d", p_m_mISDNport->b_reserved);
- if (p_m_mISDNport->b_reserved >= p_m_mISDNport->b_num) { // of out chan..
- add_trace("conclusion", NULL, "all channels are reserved");
- end_trace();
- return(-34); // no channel
- }
-
- /* map all used ports of shared loopback interface */
- memset(map, 0, sizeof(map));
- interface = interface_first;
- while(interface) {
- ifport = interface->ifport;
- while(ifport) {
-#if defined WITH_GSM_BS && defined WITH_GSM_MS
- if ((ifport->gsm_bs || ifport->gsm_ms) && ifport->mISDNport) {
-#else
-#ifdef WITH_GSM_BS
- if (ifport->gsm_bs && ifport->mISDNport) {
-#endif
-#ifdef WITH_GSM_MS
- if (ifport->gsm_ms && ifport->mISDNport) {
-#endif
-#endif
- i = 0;
- while(i < p_m_mISDNport->b_num) {
- if (p_m_mISDNport->b_port[i])
- map[i] = 1;
- i++;
- }
- }
- ifport = ifport->next;
- }
- interface = interface->next;
- }
-
- /* find channel */
- i = 0;
- channel = 0;
- while(i < p_m_mISDNport->b_num) {
- if (!map[i]) {
- channel = i+1+(i>=15);
- break;
- }
- i++;
- }
- if (!channel) {
- add_trace("conclusion", NULL, "no channel available");
- end_trace();
- return(-6); // channel unacceptable
- }
- add_trace("conclusion", NULL, "channel available");
- add_trace("connect", "channel", "%d", channel);
- end_trace();
- return(channel);
+ return loop_hunt_bchannel(this, p_m_mISDNport);
}
/* PROCEEDING INDICATION */
@@ -884,87 +987,10 @@ static int b_handler(struct lcr_fd *fd, unsigned int what, void *instance, int i
return 0;
}
-static void gsm_sock_close(void)
-{
- if (gsm->gsm_sock > -1)
- close(gsm->gsm_sock);
- gsm->gsm_sock = -1;
-}
-
-static int gsm_sock_open(char *portname)
-{
- int ret;
- int cnt;
- unsigned long on = 1;
- struct sockaddr_mISDN addr;
- struct mISDN_devinfo devinfo;
- int pri, bri;
-
- /* check port counts */
- ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
- if (ret < 0) {
- fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
- return(ret);
- }
-
- if (cnt <= 0) {
- PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
- return -EIO;
- }
- gsm->gsm_port = mISDN_getportbyname(mISDNsocket, cnt, portname);
- if (gsm->gsm_port < 0) {
- PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", portname);
- return gsm->gsm_port;
- }
- /* get protocol */
- bri = pri = 0;
- devinfo.id = gsm->gsm_port;
- ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
- if (ret < 0) {
- PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", gsm->gsm_port, ret);
- return ret;
- }
- if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
- bri = 1;
- }
- if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
- pri = 1;
- }
- if (!pri && !pri) {
- PERROR_RUNTIME("GSM port %d does not support TE PRI or TE BRI.\n", gsm->gsm_port);
- }
- /* open socket */
- if ((gsm->gsm_sock = socket(PF_ISDN, SOCK_DGRAM, (pri)?ISDN_P_TE_E1:ISDN_P_TE_S0)) < 0) {
- PERROR_RUNTIME("GSM port %d failed to open socket.\n", gsm->gsm_port);
- gsm_sock_close();
- return gsm->gsm_sock;
- }
- /* set nonblocking io */
- if ((ret = ioctl(gsm->gsm_sock, FIONBIO, &on)) < 0) {
- PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", gsm->gsm_port);
- gsm_sock_close();
- return ret;
- }
- /* bind socket to dchannel */
- memset(&addr, 0, sizeof(addr));
- addr.family = AF_ISDN;
- addr.dev = gsm->gsm_port;
- addr.channel = 0;
- if ((ret = bind(gsm->gsm_sock, (struct sockaddr *)&addr, sizeof(addr))) < 0) {
- PERROR_RUNTIME("GSM port %d failed to bind socket. (name = %s errno=%d)\n", gsm->gsm_port, portname, errno);
- gsm_sock_close();
- return (ret);
- }
-
- return 0;
-}
-
int gsm_exit(int rc)
{
/* free gsm instance */
if (gsm) {
- if (gsm->gsm_sock > -1)
- gsm_sock_close();
free(gsm);
gsm = NULL;
}
@@ -974,31 +1000,11 @@ int gsm_exit(int rc)
int gsm_init(void)
{
- char conf_error[256] = "";
-
/* seed the PRNG */
srand(time(NULL));
/* create gsm instance */
gsm = (struct lcr_gsm *)MALLOC(sizeof(struct lcr_gsm));
- gsm->gsm_sock = -1;
-
- /* parse options */
- if (!gsm_conf(&gsm->conf, conf_error)) {
- PERROR("%s", conf_error);
-#ifdef WITH_GSM_BS
- gsm_bs_exit(-EINVAL);
-#endif
-#ifdef WITH_GSM_MS
- gsm_ms_exit(-EINVAL);
-#endif
- return gsm_exit(-EINVAL);
- }
-
- /* open gsm loop interface */
- if (gsm_sock_open(gsm->conf.interface_bsc)) {
- return gsm_exit(-1);
- }
return 0;
}
diff --git a/gsm.h b/gsm.h
index 71ed759..c12baa0 100644
--- a/gsm.h
+++ b/gsm.h
@@ -1,24 +1,22 @@
+
+#include <sys/un.h>
+
extern int new_callref;
-struct gsm_conf {
- char debug[128]; /* debug info */
- char interface_bsc[64]; /* loopback interface BSC side */
- char interface_lcr[64]; /* loopback interface LCR side */
- char openbsc_cfg[128]; /* openbsc config file */
- char short_name[64]; /* short network name */
- char long_name[64]; /* long network name */
- char hlr[64]; /* database name */
- int allow_all; /* accept unknown subscribers */
- int keep_l2; /* keep layer 2 after exit */
- char pcapfile[128]; /* open capture file for BS11 links */
- int reject_cause; /* reject cause for unsubcribed IMSIs */
+struct mncc_q_entry {
+ struct mncc_q_entry *next;
+ unsigned int len;
+ char data[0]; /* struct gsm_mncc */
};
struct lcr_gsm {
void *network; /* OpenBSC network handle */
- struct gsm_conf conf; /* gsm.conf options */
- int gsm_sock; /* loopback interface GSM side */
- int gsm_port; /* loopback interface port number */
+
+ struct lcr_fd mncc_lfd; /* Unix domain socket to OpenBSC MNCC */
+ struct mncc_q_entry *mncc_q_hd;
+ struct mncc_q_entry *mncc_q_tail;
+ struct lcr_timer socket_retry; /* Timer to re-try connecting to BSC socket */
+ struct sockaddr_un sun; /* Socket address of MNCC socket */
};
extern struct lcr_gsm *gsm;
diff --git a/gsm_bs.cpp b/gsm_bs.cpp
index 584b7e2..22ac70c 100644
--- a/gsm_bs.cpp
+++ b/gsm_bs.cpp
@@ -16,75 +16,46 @@
#define _GNU_SOURCE
#endif
extern "C" {
+#include <assert.h>
#include <getopt.h>
-#include <openbsc/db.h>
-#include <osmocore/select.h>
-#include <openbsc/debug.h>
-#include <openbsc/e1_input.h>
-#include <osmocore/talloc.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
#include <openbsc/mncc.h>
#include <openbsc/trau_frame.h>
-#include <openbsc/osmo_msc.h>
-//#include <osmocom/vty/command.h>
-struct gsm_network *bsc_gsmnet = 0;
-extern int ipacc_rtp_direct;
-extern int bsc_bootstrap_network(int (*mmc_rev)(struct gsm_network *, int, void *),
- const char *cfg_file);
-extern int bsc_shutdown_net(struct gsm_network *net);
-void talloc_ctx_init(void);
-void on_dso_load_token(void);
-void on_dso_load_rrlp(void);
-void on_dso_load_ho_dec(void);
-int bts_model_unknown_init(void);
-int bts_model_bs11_init(void);
-int bts_model_nanobts_init(void);
-static struct log_target *stderr_target;
-extern const char *openbsc_copyright;
-
-/* timer to store statistics */
-#define DB_SYNC_INTERVAL 60, 0
-static struct timer_list db_sync_timer;
-
-/* FIXME: copied from the include file, because it will con compile with C++ */
-struct vty_app_info {
- const char *name;
- const char *version;
- const char *copyright;
- void *tall_ctx;
- int (*go_parent_cb)(struct vty *vty);
- int (*is_config_node)(struct vty *vty, int node);
-};
-
-extern int bsc_vty_go_parent(struct vty *vty);
-extern int bsc_vty_is_config_node(struct vty *vty, int node);
-static struct vty_app_info vty_info = {
- "OpenBSC",
- PACKAGE_VERSION,
- NULL,
- NULL,
- bsc_vty_go_parent,
- bsc_vty_is_config_node,
-};
-
-void vty_init(struct vty_app_info *app_info);
-int bsc_vty_init(void);
-
}
-/* timer handling */
-static int _db_store_counter(struct counter *counter, void *data)
-{
- return db_store_counter(counter);
-}
+#define SOCKET_RETRY_TIMER 5
+
+/*
+ * DTMF stuff
+ */
+unsigned char dtmf_samples[16][8000];
+static int dtmf_x[4] = { 1209, 1336, 1477, 1633 };
+static int dtmf_y[4] = { 697, 770, 852, 941 };
-static void db_sync_timer_cb(void *data)
+void generate_dtmf(void)
{
- /* store counters to database and re-schedule */
- counters_for_each(_db_store_counter, NULL);
- bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
+ double fx, fy, sample;
+ int i, x, y;
+ unsigned char *law;
+
+ for (y = 0; y < 4; y++) {
+ fy = 2 * 3.1415927 * ((double)dtmf_y[y]) / 8000.0;
+ for (x = 0; x < 4; x++) {
+ fx = 2 * 3.1415927 * ((double)dtmf_x[x]) / 8000.0;
+ law = dtmf_samples[y << 2 | x];
+ for (i = 0; i < 8000; i++) {
+ sample = sin(fy * ((double)i)) * 0.251 * 32767.0; /* -6 dB */
+ sample += sin(fx * ((double)i)) * 0.158 * 32767.0; /* -8 dB */
+ *law++ = audio_s16_to_law[(int)sample & 0xffff];
+ }
+ }
+ }
}
+
/*
* DTMF stuff
*/
@@ -150,6 +121,7 @@ void Pgsm_bs::start_dtmf_ind(unsigned int msg_type, unsigned int callref, struct
add_trace("keypad", NULL, "%c", mncc->keypad);
end_trace();
resp = create_mncc(MNCC_START_DTMF_RSP, p_m_g_callref);
+ resp->fields |= MNCC_F_KEYPAD;
resp->keypad = mncc->keypad;
send_and_free_mncc(p_m_g_instance, resp->msg_type, resp);
@@ -620,6 +592,20 @@ void Pgsm_bs::message_setup(unsigned int epoint_id, int message_id, union parame
memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
+ /* no GSM MNCC connection */
+ if (gsm->mncc_lfd.fd < 0) {
+ gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
+ add_trace("failure", NULL, "No MNCC connection.");
+ end_trace();
+ message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
+ message->param.disconnectinfo.cause = 27; // temp. unavail.
+ message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+ message_put(message);
+ new_state(PORT_STATE_RELEASE);
+ trigger_work(&p_m_g_delete);
+ return;
+ }
+
/* no number */
if (!p_dialinginfo.id[0]) {
gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
@@ -838,6 +824,7 @@ int Pgsm_bs::message_epoint(unsigned int epoint_id, int message_id, union parame
int gsm_bs_exit(int rc)
{
+#if 0
/* free gsm instance */
if (gsm) {
/* shutdown network */
@@ -848,110 +835,211 @@ int gsm_bs_exit(int rc)
// free((struct gsm_network *)gsm->network); /* TBD */
// }
}
-
+#endif
return(rc);
}
-int gsm_bs_init(void)
+extern "C" {
+
+static int mncc_q_enqueue(struct gsm_mncc *mncc, unsigned int len)
{
- char hlr[128], cfg[128], filename[128];
- mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
- int pcapfd, rc;
-
- vty_info.copyright = openbsc_copyright;
-
- log_init(&log_info);
- tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
- talloc_ctx_init();
- on_dso_load_token();
- on_dso_load_rrlp();
- on_dso_load_ho_dec();
- stderr_target = log_target_create_stderr();
- log_add_target(stderr_target);
-
- bts_model_unknown_init();
- bts_model_bs11_init();
- bts_model_nanobts_init();
-
- /* enable filters */
- log_set_all_filter(stderr_target, 1);
-
- /* Init VTY (need to preceed options) */
- vty_init(&vty_info);
- bsc_vty_init();
-
- /* set debug */
- if (gsm->conf.debug[0])
- log_parse_category_mask(stderr_target, gsm->conf.debug);
-
- /* open pcap file */
- if (gsm->conf.pcapfile[0]) {
- if (gsm->conf.pcapfile[0] == '/')
- SCPY(filename, gsm->conf.pcapfile);
- else
- SPRINT(filename, "%s/%s", CONFIG_DATA, gsm->conf.pcapfile);
- pcapfd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, mode);
- if (pcapfd < 0) {
- PERROR("Failed to open file for pcap\n");
- return gsm_exit(-1);
- }
- e1_set_pcap_fd(pcapfd);
- }
+ struct mncc_q_entry *qe;
- /* use RTP proxy for audio streaming */
- ipacc_rtp_direct = 0;
+ qe = (struct mncc_q_entry *) MALLOC(sizeof(*qe)+sizeof(*mncc)+len);
+ if (!qe)
+ return -ENOMEM;
- /* bootstrap network */
- if (gsm->conf.openbsc_cfg[0] == '/')
- SCPY(cfg, gsm->conf.openbsc_cfg);
- else
- SPRINT(cfg, "%s/%s", CONFIG_DATA, gsm->conf.openbsc_cfg);
- rc = bsc_bootstrap_network(&message_bsc, cfg);
- if (rc < 0) {
- PERROR("Failed to bootstrap GSM network.\n");
- return gsm_exit(-1);
+ qe->next = NULL;
+ qe->len = len;
+ memcpy(qe->data, mncc, len);
+
+ /* in case of empty list ... */
+ if (!gsm->mncc_q_hd && !gsm->mncc_q_tail) {
+ /* the list head and tail both point to the new qe */
+ gsm->mncc_q_hd = gsm->mncc_q_tail = qe;
+ } else {
+ /* append to tail of list */
+ gsm->mncc_q_tail->next = qe;
+ gsm->mncc_q_tail = qe;
}
- bsc_api_init(bsc_gsmnet, msc_bsc_api());
- gsm->network = bsc_gsmnet;
- /* init database */
- if (gsm->conf.hlr[0] == '/')
- SCPY(hlr, gsm->conf.hlr);
- else
- SPRINT(hlr, "%s/%s", CONFIG_DATA, gsm->conf.hlr);
- if (db_init(hlr)) {
- PERROR("GSM DB: Failed to init database '%s'. Please check the option settings.\n", hlr);
- return gsm_exit(-1);
+ gsm->mncc_lfd.when |= LCR_FD_WRITE;
+
+ return 0;
+}
+
+static struct mncc_q_entry *mncc_q_dequeue(void)
+{
+ struct mncc_q_entry *qe = gsm->mncc_q_hd;
+ if (!qe)
+ return NULL;
+
+ /* dequeue the successfully sent message */
+ gsm->mncc_q_hd = qe->next;
+ if (!qe)
+ return NULL;
+ if (qe == gsm->mncc_q_tail)
+ gsm->mncc_q_tail = NULL;
+
+ return qe;
+}
+
+/* routine called by LCR code if it wants to send a message to OpenBSC */
+int mncc_send(struct gsm_network *instance, int msg_type, void *data)
+{
+ int len = 0;
+
+ /* FIXME: the caller should provide this */
+ switch (msg_type) {
+ case GSM_TCHF_FRAME:
+ len = sizeof(struct gsm_data_frame) + 33;
+ break;
+ default:
+ len = sizeof(struct gsm_mncc);
+ break;
}
- printf("DB: Database initialized.\n");
- if (db_prepare()) {
- PERROR("GSM DB: Failed to prepare database.\n");
- return gsm_exit(-1);
+
+ return mncc_q_enqueue((struct gsm_mncc *)data, len);
+}
+
+} // extern "C"
+
+/* close MNCC socket */
+static int mncc_fd_close(struct lcr_fd *lfd)
+{
+ class Port *port;
+ class Pgsm_bs *pgsm_bs = NULL;
+ struct lcr_msg *message;
+
+ PERROR("Lost MNCC socket, retrying in %u seconds\n", SOCKET_RETRY_TIMER);
+ close(lfd->fd);
+ unregister_fd(lfd);
+ lfd->fd = -1;
+
+ /* free all the calls that were running through the MNCC interface */
+ port = port_first;
+ while(port) {
+ if ((port->p_type & PORT_CLASS_GSM_MASK) == PORT_CLASS_GSM_BS) {
+ pgsm_bs = (class Pgsm_bs *)port;
+ message = message_create(pgsm_bs->p_serial, ACTIVE_EPOINT(pgsm_bs->p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
+ message->param.disconnectinfo.cause = 27; // temp. unavail.
+ message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+ message_put(message);
+ pgsm_bs->new_state(PORT_STATE_RELEASE);
+ trigger_work(&pgsm_bs->p_m_g_delete);
+ }
+ port = port->next;
}
- printf("DB: Database prepared.\n");
- /* setup the timer */
- db_sync_timer.cb = db_sync_timer_cb;
- db_sync_timer.data = NULL;
- bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
+ /* flush the queue */
+ while (mncc_q_dequeue())
+ ;
+
+ /* start the re-connect timer */
+ schedule_timer(&gsm->socket_retry, SOCKET_RETRY_TIMER, 0);
generate_dtmf();
return 0;
}
-/*
- * handles bsc select function within LCR's main loop
- */
-int handle_gsm_bs(void)
+/* read from OpenBSC via MNCC socket */
+static int mncc_fd_write(struct lcr_fd *lfd, void *inst, int idx)
+{
+ struct mncc_q_entry *qe, *qe2;
+ int rc;
+
+ while (1) {
+ qe = gsm->mncc_q_hd;
+ if (!qe) {
+ lfd->when &= ~LCR_FD_WRITE;
+ break;
+ }
+ rc = write(lfd->fd, qe->data, qe->len);
+ if (rc == 0)
+ return mncc_fd_close(lfd);
+ if (rc < 0)
+ return rc;
+ if (rc < (int)qe->len)
+ return -1;
+ /* dequeue the successfully sent message */
+ qe2 = mncc_q_dequeue();
+ assert(qe == qe2);
+ free(qe);
+ }
+ return 0;
+}
+
+/* read from OpenBSC via MNCC socket */
+static int mncc_fd_read(struct lcr_fd *lfd, void *inst, int idx)
+{
+ int rc;
+ static char buf[sizeof(struct gsm_mncc)+1024];
+ struct gsm_mncc *mncc_prim = (struct gsm_mncc *) buf;
+
+ memset(buf, 0, sizeof(buf));
+ rc = recv(lfd->fd, buf, sizeof(buf), 0);
+ if (rc == 0)
+ return mncc_fd_close(lfd);
+ if (rc < 0)
+ return rc;
+
+ /* Hand the MNCC message into LCR */
+ return message_bsc(NULL, mncc_prim->msg_type, mncc_prim);
+}
+
+/* file descriptor callback if we can read or write form MNCC socket */
+static int mncc_fd_cb(struct lcr_fd *lfd, unsigned int what, void *instance, int idx)
+{
+ int rc = 0;
+
+ if (what & LCR_FD_READ)
+ rc = mncc_fd_read(lfd, instance, idx);
+ if (rc < 0)
+ return rc;
+
+ if (what & LCR_FD_WRITE)
+ rc = mncc_fd_write(lfd, instance, idx);
+
+ return rc;
+}
+
+static int socket_retry_cb(struct lcr_timer *timer, void *instance, int index)
{
- int ret1, ret2;
+ int fd, rc;
+
+ fd = socket(PF_UNIX, SOCK_SEQPACKET, 0);
+ if (fd < 0) {
+ PERROR("Cannot create SEQPACKET socket, giving up!\n");
+ return fd;
+ }
+
+ rc = connect(fd, (struct sockaddr *) &gsm->sun,
+ sizeof(gsm->sun));
+ if (rc < 0) {
+ PERROR("Could not connect to MNCC socket, "
+ "retrying in %u seconds\n", SOCKET_RETRY_TIMER);
+ close(fd);
+ schedule_timer(&gsm->socket_retry, SOCKET_RETRY_TIMER, 0);
+ } else {
+ PDEBUG(DEBUG_GSM, "Connected to MNCC socket!\n");
+ gsm->mncc_lfd.fd = fd;
+ register_fd(&gsm->mncc_lfd, LCR_FD_READ, &mncc_fd_cb, NULL, 0);
+ }
- ret1 = bsc_upqueue((struct gsm_network *)gsm->network);
- log_reset_context();
- ret2 = bsc_select_main(1); /* polling */
- if (ret1 || ret2)
- return 1;
return 0;
}
+int gsm_bs_init(void)
+{
+ gsm->sun.sun_family = AF_UNIX;
+ SCPY(gsm->sun.sun_path, "/tmp/bsc_mncc");
+
+ memset(&gsm->socket_retry, 0, sizeof(gsm->socket_retry));
+ add_timer(&gsm->socket_retry, socket_retry_cb, NULL, 0);
+
+ /* do the initial connect */
+ socket_retry_cb(&gsm->socket_retry, NULL, 0);
+
+ return 0;
+}
diff --git a/gsm_bs.h b/gsm_bs.h
index fd56efe..8a55213 100644
--- a/gsm_bs.h
+++ b/gsm_bs.h
@@ -25,3 +25,7 @@ int handle_gsm_bs(void);
int gsm_bs_conf(struct gsm_conf *gsm_conf, char *conf_error);
int gsm_bs_exit(int rc);
int gsm_bs_init(void);
+
+extern "C" {
+int mncc_send(struct gsm_network *instance, int msg_type, void *data);
+};
diff --git a/gsm_conf.c b/gsm_conf.c
deleted file mode 100644
index a64f2ff..0000000
--- a/gsm_conf.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*****************************************************************************\
-** **
-** PBX4Linux **
-** **
-**---------------------------------------------------------------------------**
-** Copyright: Andreas Eversberg **
-** **
-** reading options.conf and filling structure **
-** **
-\*****************************************************************************/
-
-#include "main.h"
-
-
-/* read options
- *
- * read options from options.conf
- */
-int gsm_conf(struct gsm_conf *gsm_conf, char *conf_error)
-{
- FILE *fp=NULL;
- char filename[128];
- char *p;
- char option[32];
- char params[11][256];
- int pnum;
- unsigned int line,i;
- char buffer[256];
-
- /* set defaults */
- SCPY(gsm_conf->debug, "");
- SCPY(gsm_conf->interface_bsc, "mISDN_l1loop.1");
- SCPY(gsm_conf->interface_lcr, "mISDN_l1loop.2");
- SCPY(gsm_conf->hlr, "hlr.sqlite3");
- SCPY(gsm_conf->openbsc_cfg, "openbsc.cfg");
- gsm_conf->reject_cause = 0;
- gsm_conf->keep_l2 = 0;
-
- SPRINT(filename, "%s/gsm.conf", CONFIG_DATA);
-
- if (!(fp=fopen(filename,"r"))) {
- UPRINT(conf_error, "Cannot open %s\n",filename);
- return(0);
- }
-
- line=0;
- while((GETLINE(buffer, fp))) {
- line++;
- p=buffer;
-
- while(*p <= 32) { /* skip spaces */
- if (*p == 0)
- break;
- p++;
- }
- if (*p==0 || *p=='#') /* ignore comments and empty line */
- continue;
-
- option[0]=0;
- i=0; /* read option */
- while(*p > 32) {
- if (i+1 >= sizeof(option)) {
- UPRINT(conf_error, "Error in %s (line %d): option too long.\n",filename,line);
- goto error;
- }
- option[i+1] = '\0';
- option[i++] = *p++;
- }
-
- while(*p <= 32) { /* skip spaces */
- if (*p == 0)
- break;
- p++;
- }
-
- params[0][0] = 0;
- pnum = 0;
- while(*p!=0 && *p!='#' && pnum < 10) { /* param */
- i=0; /* read param */
- while(*p > 32) {
- if (i+1 >= sizeof(params[pnum])) {
- UPRINT(conf_error, "Error in %s (line %d): param too long.\n",filename,line);
- goto error;
- }
- params[pnum][i+1] = '\0';
- params[pnum][i++] = *p++;
- }
- while(*p <= 32) { /* skip spaces */
- if (*p == 0)
- break;
- p++;
- }
- pnum++;
- params[pnum][0] = 0;
- }
-
- /* at this point we have option and param */
-
- /* check option */
- if (!strcmp(option,"debug")) {
- if (params[0][0]==0) {
- UPRINT(conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line,option);
- goto error;
- }
- SCPY(gsm_conf->debug, params[0]);
-
- } else
- if (!strcmp(option,"interface-bsc")) {
- if (params[0][0]==0) {
- UPRINT(conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
- goto error;
- }
- SCPY(gsm_conf->interface_bsc, params[0]);
-
- } else
- if (!strcmp(option,"interface-lcr")) {
- if (params[0][0]==0) {
- UPRINT(conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
- goto error;
- }
- SCPY(gsm_conf->interface_lcr, params[0]);
-
- } else
- if (!strcmp(option,"config")) {
- if (params[0][0]==0) {
- UPRINT(conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
- goto error;
- }
- SCPY(gsm_conf->openbsc_cfg, params[0]);
-
- } else
- if (!strcmp(option,"hlr")) {
- if (params[0][0]==0) {
- UPRINT(conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
- goto error;
- }
- SCPY(gsm_conf->hlr, params[0]);
-
- } else
- if (!strcmp(option,"reject-cause")) {
- UPRINT(conf_error, "Option '%s' in gsm.conf has moved to openbsc.cfg", option);
- goto error;
- } else
- if (!strcmp(option,"allow-all")) {
- gsm_conf->allow_all = 1;
- } else
- if (!strcmp(option,"keep-l2")) {
- gsm_conf->keep_l2 = 1;
-
- } else
- if (!strcmp(option,"pcapfile")) {
- if (params[0][0]==0) {
- UPRINT(conf_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
- goto error;
- }
- SCPY(gsm_conf->pcapfile, params[0]);
- } else {
- UPRINT(conf_error, "Error in %s (line %d): wrong option keyword %s.\n", filename,line,option);
- goto error;
- }
- }
-
- if (fp) fclose(fp);
- return(1);
-error:
- if (fp) fclose(fp);
- return(0);
-}
-
-
diff --git a/gsm_ms.cpp b/gsm_ms.cpp
index 551fcad..c8292f9 100644
--- a/gsm_ms.cpp
+++ b/gsm_ms.cpp
@@ -16,24 +16,26 @@
#endif
extern "C" {
#include <getopt.h>
+#include <arpa/inet.h>
#include <osmocore/select.h>
#include <osmocore/talloc.h>
+#include <osmocore/gsmtap_util.h>
#include <osmocom/bb/common/osmocom_data.h>
#include <osmocom/bb/common/logging.h>
#include <osmocom/bb/common/l1l2_interface.h>
-#include <osmocom/bb/common/l23_app.h>
+#include <osmocom/bb/mobile/app_mobile.h>
}
-const char *openbsc_copyright = "";
+static const char *config_file = "/etc/osmocom/osmocom.cfg";
short vty_port = 4247;
struct llist_head ms_list;
struct log_target *stderr_target;
void *l23_ctx = NULL;
-int (*l23_app_work) (struct osmocom_ms *ms) = NULL;
-int (*l23_app_exit) (struct osmocom_ms *ms) = NULL;
+
+static int dtmf_timeout(struct lcr_timer *timer, void *instance, int index);
static int dtmf_timeout(struct lcr_timer *timer, void *instance, int index);
@@ -54,8 +56,11 @@ Pgsm_ms::Pgsm_ms(int type, struct mISDNport *mISDNport, char *portname, struct p
}
}
- if (!p_m_g_instance)
- FATAL("MS name %s does not exists. Please fix!");
+ p_m_g_dtmf_state = DTMF_ST_IDLE;
+ p_m_g_dtmf_index = 0;
+ p_m_g_dtmf[0] = '\0';
+ memset(&p_m_g_dtmf_timer, 0, sizeof(p_m_g_dtmf_timer));
+ add_timer(&p_m_g_dtmf_timer, dtmf_timeout, this, 0);
p_m_g_dtmf_state = DTMF_ST_IDLE;
p_m_g_dtmf_index = 0;
@@ -391,7 +396,31 @@ static int message_ms(struct osmocom_ms *ms, int msg_type, void *arg)
struct mISDNport *mISDNport;
/* Special messages */
- if (msg_type) {
+ switch (msg_type) {
+ case MS_NEW:
+ PDEBUG(DEBUG_GSM, "MS %s comes available\n", ms->name);
+ return 0;
+ case MS_DELETE:
+ PDEBUG(DEBUG_GSM, "MS %s is removed\n", ms->name);
+ port = port_first;
+ while(port) {
+ if ((port->p_type & PORT_CLASS_GSM_MASK) == PORT_CLASS_GSM_MS) {
+ pgsm_ms = (class Pgsm_ms *)port;
+ if (pgsm_ms->p_m_g_instance == ms) {
+ struct lcr_msg *message;
+
+ pgsm_ms->p_m_g_instance = 0;
+ message = message_create(pgsm_ms->p_serial, ACTIVE_EPOINT(pgsm_ms->p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
+ message->param.disconnectinfo.cause = 27;
+ message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+ message_put(message);
+ pgsm_ms->new_state(PORT_STATE_RELEASE);
+ trigger_work(&pgsm_ms->p_m_g_delete);
+ }
+ }
+ port = port->next;
+ }
+ return 0;
}
/* find callref */
@@ -508,6 +537,20 @@ void Pgsm_ms::message_setup(unsigned int epoint_id, int message_id, union parame
memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
+ /* no instance */
+ if (!p_m_g_instance) {
+ gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
+ add_trace("failure", NULL, "MS %s instance is unavailable", p_m_mISDNport->ifport->gsm_ms_name);
+ end_trace();
+ message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
+ message->param.disconnectinfo.cause = 27;
+ message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+ message_put(message);
+ new_state(PORT_STATE_RELEASE);
+ trigger_work(&p_m_g_delete);
+ return;
+ }
+
/* no number */
if (!p_dialinginfo.id[0]) {
gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
@@ -782,6 +825,7 @@ int Pgsm_ms::message_epoint(unsigned int epoint_id, int message_id, union parame
int gsm_ms_exit(int rc)
{
+ l23_app_exit();
return(rc);
}
@@ -796,50 +840,40 @@ int gsm_ms_init(void)
l23_ctx = talloc_named_const(NULL, 1, "layer2 context");
- return 0;
-}
-
-/* add a new GSM mobile instance */
-int gsm_ms_new(const char *name, const char *socket_path)
-{
- struct osmocom_ms *ms = NULL;
- int rc;
-
- PDEBUG(DEBUG_GSM, "GSM: creating new instance '%s' on '%s'\n", name, socket_path);
+ log_parse_category_mask(stderr_target, "DCS:DPLMN:DRR:DMM:DSIM:DCC:DMNCC:DPAG:DSUM");
+ log_set_log_level(stderr_target, LOGL_INFO);
- ms = talloc_zero(l23_ctx, struct osmocom_ms);
- if (!ms) {
- FATAL("Failed to allocate MS\n");
+#if 0
+ if (gsmtap_ip) {
+ rc = gsmtap_init(gsmtap_ip);
+ if (rc < 0) {
+ fprintf(stderr, "Failed during gsmtap_init()\n");
+ exit(1);
+ }
}
- /* must add here, because other init processes may search in the list */
- llist_add_tail(&ms->entity, &ms_list);
-
+#endif
- SPRINT(ms->name, name);
+ l23_app_init(message_ms, config_file, vty_port);
- rc = layer2_open(ms, socket_path);
- if (rc < 0) {
- FATAL("Failed during layer2_open()\n");
- }
-
- lapdm_init(&ms->l2_entity.lapdm_dcch, ms);
- lapdm_init(&ms->l2_entity.lapdm_acch, ms);
+ return 0;
+}
- rc = l23_app_init(ms);
- if (rc < 0) {
- FATAL("Failed to init layer23\n");
- }
- ms->mncc_entity.mncc_recv = message_ms;
+/* add a new GSM mobile instance */
+int gsm_ms_new(const char *name)
+{
+ PDEBUG(DEBUG_GSM, "GSM: interface for MS '%s' is up\n", name);
return 0;
}
int gsm_ms_delete(const char *name)
{
- struct osmocom_ms *ms = NULL;
+ struct osmocom_ms *ms;
int found = 0;
+ class Port *port;
+ class Pgsm_ms *pgsm_ms = NULL;
- PDEBUG(DEBUG_GSM, "GSM: destroying instance '%s'\n", name);
+ PDEBUG(DEBUG_GSM, "GSM: interface for MS '%s' is down\n", name);
llist_for_each_entry(ms, &ms_list, entity) {
if (!strcmp(ms->name, name)) {
@@ -848,15 +882,29 @@ int gsm_ms_delete(const char *name)
}
}
- if (!found) {
- FATAL("Failed delete layer23, instance '%s' not found\n", name);
- }
-
- l23_app_exit(ms);
- lapdm_exit(&ms->l2_entity.lapdm_dcch);
- lapdm_exit(&ms->l2_entity.lapdm_acch);
+ if (!found)
+ return 0;
- llist_del(&ms->entity);
+ port = port_first;
+ while(port) {
+ if ((port->p_type & PORT_CLASS_GSM_MASK) == PORT_CLASS_GSM_MS) {
+ pgsm_ms = (class Pgsm_ms *)port;
+ if (pgsm_ms->p_m_g_instance == ms && pgsm_ms->p_m_g_callref) {
+ struct gsm_mncc *rej;
+
+ rej = create_mncc(MNCC_REL_REQ, pgsm_ms->p_m_g_callref);
+ rej->fields |= MNCC_F_CAUSE;
+ rej->cause.coding = 3;
+ rej->cause.location = 1;
+ rej->cause.value = 27;
+ gsm_trace_header(NULL, NULL, MNCC_REJ_REQ, DIRECTION_OUT);
+ add_trace("cause", "coding", "%d", rej->cause.coding);
+ add_trace("cause", "location", "%d", rej->cause.location);
+ add_trace("cause", "value", "%d", rej->cause.value);
+ end_trace();
+ }
+ }
+ }
return 0;
}
@@ -864,18 +912,17 @@ int gsm_ms_delete(const char *name)
/*
* handles bsc select function within LCR's main loop
*/
-int handle_gsm_ms(void)
+int handle_gsm_ms(int *_quit)
{
- struct osmocom_ms *ms = NULL;
- int work = 0;
-
- llist_for_each_entry(ms, &ms_list, entity) {
- if (l23_app_work(ms))
- work = 1;
-// debug_reset_context();
- if (bsc_select_main(1)) /* polling */
- work = 1;
- }
+ int work = 0, quit = 0;
+
+ if (l23_app_work(&quit))
+ work = 1;
+ if (quit && llist_empty(&ms_list))
+ *_quit = 1;
+// debug_reset_context();
+ if (bsc_select_main(1)) /* polling */
+ work = 1;
return work;
}
diff --git a/gsm_ms.h b/gsm_ms.h
index 3e9794f..822f0a6 100644
--- a/gsm_ms.h
+++ b/gsm_ms.h
@@ -23,10 +23,10 @@ class Pgsm_ms : public Pgsm
int message_epoint(unsigned int epoint_id, int message_id, union parameter *param);
};
-int handle_gsm_ms(void);
+int handle_gsm_ms(int *quit);
int gsm_ms_conf(struct gsm_conf *gsm_conf, char *conf_error);
int gsm_ms_exit(int rc);
int gsm_ms_init(void);
-int gsm_ms_new(const char *name, const char *socket_path);
+int gsm_ms_new(const char *name);
int gsm_ms_delete(const char *name);
diff --git a/install-sh b/install-sh
deleted file mode 100755
index 4fbbae7..0000000
--- a/install-sh
+++ /dev/null
@@ -1,507 +0,0 @@
-#!/bin/sh
-# install - install a program, script, or datafile
-
-scriptversion=2006-10-14.15
-
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-
-nl='
-'
-IFS=" "" $nl"
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-if test -z "$doit"; then
- doit_exec=exec
-else
- doit_exec=$doit
-fi
-
-# Put in absolute file names if you don't have them in your path;
-# or use environment vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-posix_glob=
-posix_mkdir=
-
-# Desired mode of installed file.
-mode=0755
-
-chmodcmd=$chmodprog
-chowncmd=
-chgrpcmd=
-stripcmd=
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=
-dst=
-dir_arg=
-dstarg=
-no_target_directory=
-
-usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
- or: $0 [OPTION]... SRCFILES... DIRECTORY
- or: $0 [OPTION]... -t DIRECTORY SRCFILES...
- or: $0 [OPTION]... -d DIRECTORIES...
-
-In the 1st form, copy SRCFILE to DSTFILE.
-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
-In the 4th, create DIRECTORIES.
-
-Options:
--c (ignored)
--d create directories instead of installing files.
--g GROUP $chgrpprog installed files to GROUP.
--m MODE $chmodprog installed files to MODE.
--o USER $chownprog installed files to USER.
--s $stripprog installed files.
--t DIRECTORY install into DIRECTORY.
--T report an error if DSTFILE is a directory.
---help display this help and exit.
---version display version info and exit.
-
-Environment variables override the default commands:
- CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
-"
-
-while test $# -ne 0; do
- case $1 in
- -c) shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- --help) echo "$usage"; exit $?;;
-
- -m) mode=$2
- shift
- shift
- case $mode in
- *' '* | *' '* | *'
-'* | *'*'* | *'?'* | *'['*)
- echo "$0: invalid mode: $mode" >&2
- exit 1;;
- esac
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd=$stripprog
- shift
- continue;;
-
- -t) dstarg=$2
- shift
- shift
- continue;;
-
- -T) no_target_directory=true
- shift
- continue;;
-
- --version) echo "$0 $scriptversion"; exit $?;;
-
- --) shift
- break;;
-
- -*) echo "$0: invalid option: $1" >&2
- exit 1;;
-
- *) break;;
- esac
-done
-
-if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
- # When -d is used, all remaining arguments are directories to create.
- # When -t is used, the destination is already specified.
- # Otherwise, the last argument is the destination. Remove it from $@.
- for arg
- do
- if test -n "$dstarg"; then
- # $@ is not empty: it contains at least $arg.
- set fnord "$@" "$dstarg"
- shift # fnord
- fi
- shift # arg
- dstarg=$arg
- done
-fi
-
-if test $# -eq 0; then
- if test -z "$dir_arg"; then
- echo "$0: no input file specified." >&2
- exit 1
- fi
- # It's OK to call `install-sh -d' without argument.
- # This can happen when creating conditional directories.
- exit 0
-fi
-
-if test -z "$dir_arg"; then
- trap '(exit $?); exit' 1 2 13 15
-
- # Set umask so as not to create temps with too-generous modes.
- # However, 'strip' requires both read and write access to temps.
- case $mode in
- # Optimize common cases.
- *644) cp_umask=133;;
- *755) cp_umask=22;;
-
- *[0-7])
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw='% 200'
- fi
- cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
- *)
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw=,u+rw
- fi
- cp_umask=$mode$u_plus_rw;;
- esac
-fi
-
-for src
-do
- # Protect names starting with `-'.
- case $src in
- -*) src=./$src ;;
- esac
-
- if test -n "$dir_arg"; then
- dst=$src
- dstdir=$dst
- test -d "$dstdir"
- dstdir_status=$?
- else
-
- # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
- # might cause directories to be created, which would be especially bad
- # if $src (and thus $dsttmp) contains '*'.
- if test ! -f "$src" && test ! -d "$src"; then
- echo "$0: $src does not exist." >&2
- exit 1
- fi
-
- if test -z "$dstarg"; then
- echo "$0: no destination specified." >&2
- exit 1
- fi
-
- dst=$dstarg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst ;;
- esac
-
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
- if test -d "$dst"; then
- if test -n "$no_target_directory"; then
- echo "$0: $dstarg: Is a directory" >&2
- exit 1
- fi
- dstdir=$dst
- dst=$dstdir/`basename "$src"`
- dstdir_status=0
- else
- # Prefer dirname, but fall back on a substitute if dirname fails.
- dstdir=`
- (dirname "$dst") 2>/dev/null ||
- expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$dst" : 'X\(//\)[^/]' \| \
- X"$dst" : 'X\(//\)$' \| \
- X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
- echo X"$dst" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'
- `
-
- test -d "$dstdir"
- dstdir_status=$?
- fi
- fi
-
- obsolete_mkdir_used=false
-
- if test $dstdir_status != 0; then
- case $posix_mkdir in
- '')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
- # With -d, create the new directory with the user-specified mode.
- # Otherwise, rely on $mkdir_umask.
- if test -n "$dir_arg"; then
- mkdir_mode=-m$mode
- else
- mkdir_mode=
- fi
-
- posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- if (umask $mkdir_umask &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writeable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- ls_ld_tmpdir=`ls -ld "$tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/d" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
- fi
- trap '' 0;;
- esac;;
- esac
-
- if
- $posix_mkdir && (
- umask $mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
- )
- then :
- else
-
- # The umask is ridiculous, or mkdir does not conform to POSIX,
- # or it failed possibly due to a race condition. Create the
- # directory the slow way, step by step, checking for races as we go.
-
- case $dstdir in
- /*) prefix=/ ;;
- -*) prefix=./ ;;
- *) prefix= ;;
- esac
-
- case $posix_glob in
- '')
- if (set -f) 2>/dev/null; then
- posix_glob=true
- else
- posix_glob=false
- fi ;;
- esac
-
- oIFS=$IFS
- IFS=/
- $posix_glob && set -f
- set fnord $dstdir
- shift
- $posix_glob && set +f
- IFS=$oIFS
-
- prefixes=
-
- for d
- do
- test -z "$d" && continue
-
- prefix=$prefix$d
- if test -d "$prefix"; then
- prefixes=
- else
- if $posix_mkdir; then
- (umask=$mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
- # Don't fail if two instances are running concurrently.
- test -d "$prefix" || exit 1
- else
- case $prefix in
- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
- *) qprefix=$prefix;;
- esac
- prefixes="$prefixes '$qprefix'"
- fi
- fi
- prefix=$prefix/
- done
-
- if test -n "$prefixes"; then
- # Don't fail if two instances are running concurrently.
- (umask $mkdir_umask &&
- eval "\$doit_exec \$mkdirprog $prefixes") ||
- test -d "$dstdir" || exit 1
- obsolete_mkdir_used=true
- fi
- fi
- fi
-
- if test -n "$dir_arg"; then
- { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
- { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
- test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
- else
-
- # Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
-
- # Trap to clean up those temp files at exit.
- trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
-
- # Copy the file name to the temp name.
- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
-
- # and set any options; do chmod last to preserve setuid bits.
- #
- # If any of these fail, we abort the whole thing. If we want to
- # ignore errors from any of these, just make sure not to ignore
- # errors from the above "$doit $cpprog $src $dsttmp" command.
- #
- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
- && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
- && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
- && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
- # Now rename the file to the real destination.
- { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
- || {
- # The rename failed, perhaps because mv can't rename something else
- # to itself, or perhaps because mv is so ancient that it does not
- # support -f.
-
- # Now remove or move aside any old file at destination location.
- # We try this two ways since rm can't unlink itself on some
- # systems and the destination file might be busy for other
- # reasons. In this case, the final cleanup might fail but the new
- # file should still install successfully.
- {
- if test -f "$dst"; then
- $doit $rmcmd -f "$dst" 2>/dev/null \
- || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
- && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
- || {
- echo "$0: cannot unlink or rename $dst" >&2
- (exit 1); exit 1
- }
- else
- :
- fi
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dst"
- }
- } || exit 1
-
- trap '' 0
- fi
-done
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/interface.c b/interface.c
index 09e0067..4e432af 100644
--- a/interface.c
+++ b/interface.c
@@ -325,11 +325,9 @@ static int inter_portname(struct interface *interface, char *filename, int line,
ifport = ifport->next;
}
- /* check for port already assigned, but not for shared gsm interface */
+ /* check for port already assigned, but not for shared loop interface */
searchif = interface_newlist;
-#if defined WITH_GSM_BS || defined WITH_GSM_MS
- if (options.gsm && !strcmp(value, gsm->conf.interface_lcr))
-#endif
+ if (!!strcmp(value, options.loopback_lcr))
{
while(searchif) {
ifport = searchif->ifport;
@@ -918,7 +916,7 @@ static int inter_gsm_bs(struct interface *interface, char *filename, int line, c
}
/* set portname */
- if (inter_portname(interface, filename, line, (char *)"portname", gsm->conf.interface_lcr))
+ if (inter_portname(interface, filename, line, (char *)"portname", options.loopback_lcr))
return(-1);
/* goto end of chain again to set gsmflag */
@@ -947,7 +945,7 @@ static int inter_gsm_ms(struct interface *interface, char *filename, int line, c
}
/* set portname */
- if (inter_portname(interface, filename, line, (char *)"portname", gsm->conf.interface_lcr))
+ if (inter_portname(interface, filename, line, (char *)"portname", options.loopback_lcr))
return(-1);
/* goto end of chain again to set gsmflag and socket */
@@ -963,21 +961,15 @@ static int inter_gsm_ms(struct interface *interface, char *filename, int line, c
return(-1);
}
SCPY(ifport->gsm_ms_name, element);
- element = strsep(&value, " ");
- if (!element || !element[0]) {
- SPRINT(interface_error, "Error in %s (line %d): Missing socket name after MS name.\n", filename, line);
- return(-1);
- }
- SCPY(ifport->gsm_ms_socket, element);
- /* check if socket is used multiple times */
+ /* check if name is used multiple times */
searchif = interface_newlist;
while(searchif) {
searchifport = searchif->ifport;
while(searchifport) {
if (searchifport != ifport
- && !strcmp(searchifport->gsm_ms_socket, ifport->gsm_ms_socket)) {
- SPRINT(interface_error, "Error in %s (line %d): mobile '%s' already uses the given socket '%s', choose a different one.\n", filename, line, ifport->gsm_ms_name, searchifport->gsm_ms_socket);
+ && !strcmp(searchifport->gsm_ms_name, ifport->gsm_ms_name)) {
+ SPRINT(interface_error, "Error in %s (line %d): mobile '%s' already uses the given MS name '%s', choose a different one.\n", filename, line, ifport->gsm_ms_name, searchifport->gsm_ms_name);
return(-1);
}
searchifport = searchifport->next;
@@ -1054,6 +1046,42 @@ static int inter_ss5(struct interface *interface, char *filename, int line, char
return(0);
}
#endif
+static int inter_remote(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
+ struct interface_port *ifport;
+ struct interface *searchif;
+
+ if (!value[0]) {
+ SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects application name as value.\n", filename, line, parameter);
+ return(-1);
+ }
+ searchif = interface_newlist;
+ while(searchif) {
+ ifport = searchif->ifport;
+ while(ifport) {
+ if (ifport->remote && !strcmp(ifport->remote_app, value)) {
+ SPRINT(interface_error, "Error in %s (line %d): port '%s' already uses remote application '%s'.\n", filename, line, ifport->portname, value);
+ return(-1);
+ }
+ ifport = ifport->next;
+ }
+ searchif = searchif->next;
+ }
+
+ /* set portname */
+ if (inter_portname(interface, filename, line, (char *)"portname", options.loopback_lcr))
+ return(-1);
+
+ /* goto end of chain again to set application name */
+ ifport = interface->ifport;
+ while(ifport->next)
+ ifport = ifport->next;
+ ifport->remote = 1;
+ SCPY(ifport->remote_app, value);
+
+
+ return(0);
+}
/*
@@ -1215,6 +1243,10 @@ struct interface_param interface_param[] = {
" suppress - Suppress received tones, as they will be recognized."},
#endif
+ {"remote", &inter_remote, "<application>",
+ "Sets up an interface that communicates with the remote application.\n"
+ "Use \"asterisk\" to use chan_lcr as remote application."},
+
{NULL, NULL, NULL, NULL}
};
@@ -1551,7 +1583,7 @@ void load_port(struct interface_port *ifport)
mISDNport_static(mISDNport);
#ifdef WITH_GSM_MS
if (ifport->gsm_ms)
- gsm_ms_new(ifport->gsm_ms_name, ifport->gsm_ms_socket);
+ gsm_ms_new(ifport->gsm_ms_name);
#endif
} else {
ifport->block = 2; /* not available */
diff --git a/interface.h b/interface.h
index d1bea04..f271080 100644
--- a/interface.h
+++ b/interface.h
@@ -57,10 +57,10 @@ struct interface_port {
#ifdef WITH_GSM_MS
int gsm_ms; /* interface is an GSM MS interface */
char gsm_ms_name[32]; /* name of ms */
- char gsm_ms_socket[128]; /* layer1 socket name */
- char gsm_ms_service; /* see GSM_SERVICE_* */
#endif
unsigned int ss5; /* set, if SS5 signalling enabled, also holds feature bits */
+ int remote; /* interface is a remote app interface */
+ char remote_app[32]; /* name of remote application */
int channel_force; /* forces channel by protocol */
int nodtmf; /* disables DTMF */
struct select_channel *out_channel; /* list of channels to select */
diff --git a/joinremote.cpp b/joinremote.cpp
index 167bbce..c02de8e 100644
--- a/joinremote.cpp
+++ b/joinremote.cpp
@@ -14,6 +14,7 @@
//#define __u16 unsigned short
//#define __u32 unsigned int
+extern unsigned int new_remote;
/*
* constructor for a new join
@@ -27,6 +28,7 @@ JoinRemote::JoinRemote(unsigned int serial, char *remote_name, int remote_id) :
SCPY(j_remote_name, remote_name);
j_remote_id = remote_id;
j_type = JOIN_TYPE_REMOTE;
+ j_remote_ref = new_remote++;
j_epoint_id = serial; /* this is the endpoint, if created by epoint */
if (j_epoint_id)
@@ -35,9 +37,8 @@ JoinRemote::JoinRemote(unsigned int serial, char *remote_name, int remote_id) :
/* send new ref to remote socket */
memset(&param, 0, sizeof(union parameter));
if (serial)
- param.direction = 1; /* new ref from lcr */
- /* the j_serial is assigned by Join() parent. this is sent as new ref */
- if (admin_message_from_join(j_remote_id, j_serial, MESSAGE_NEWREF, &param)<0)
+ param.newref.direction = 1; /* new ref from lcr */
+ if (admin_message_from_lcr(j_remote_id, j_remote_ref, MESSAGE_NEWREF, &param)<0)
FATAL("No socket with remote application '%s' found, this shall not happen. because we already created one.\n", j_remote_name);
}
@@ -56,7 +57,7 @@ void JoinRemote::message_epoint(unsigned int epoint_id, int message_type, union
return;
/* look for Remote's interface */
- if (admin_message_from_join(j_remote_id, j_serial, message_type, param)<0) {
+ if (admin_message_from_lcr(j_remote_id, j_remote_ref, message_type, param)<0) {
PERROR("No socket with remote application '%s' found, this shall not happen. Closing socket shall cause release of all joins.\n", j_remote_name);
return;
}
@@ -100,25 +101,5 @@ void JoinRemote::message_remote(int message_type, union parameter *param)
}
}
-void message_bchannel_to_remote(unsigned int remote_id, unsigned int ref, int type, unsigned int handle, int tx_gain, int rx_gain, char *pipeline, unsigned char *crypt, int crypt_len, int crypt_type)
-{
- union parameter param;
-
- memset(&param, 0, sizeof(union parameter));
- param.bchannel.type = type;
- param.bchannel.handle = handle;
- param.bchannel.tx_gain = tx_gain;
- param.bchannel.rx_gain = rx_gain;
- if (pipeline)
- SCPY(param.bchannel.pipeline, pipeline);
- if (crypt_len)
- memcpy(param.bchannel.crypt, crypt, crypt_len);
- param.bchannel.crypt_type = crypt_type;
- if (admin_message_from_join(remote_id, ref, MESSAGE_BCHANNEL, &param)<0) {
- PERROR("No socket with remote id %d found, this happens, if the socket is closed before all bchannels are imported.\n", remote_id);
- return;
- }
-}
-
diff --git a/joinremote.h b/joinremote.h
index 1582133..a933466 100644
--- a/joinremote.h
+++ b/joinremote.h
@@ -17,10 +17,10 @@ class JoinRemote : public Join
void message_epoint(unsigned int epoint_id, int message, union parameter *param);
void message_remote(int message_type, union parameter *param);
+ unsigned int j_remote_ref;
int j_remote_id;
char j_remote_name[32];
unsigned int j_epoint_id;
};
-void message_bchannel_to_remote(unsigned int remote_id, unsigned int ref, int type, unsigned int handle, int tx_gain, int rx_gain, char *pipeline, unsigned char *crypt, int crypt_len, int crypt_type);
diff --git a/loop.c b/loop.c
new file mode 100644
index 0000000..cbd82e5
--- /dev/null
+++ b/loop.c
@@ -0,0 +1,153 @@
+/*****************************************************************************\
+** **
+** LCR **
+** **
+**---------------------------------------------------------------------------**
+** Copyright: Andreas Eversberg **
+** **
+** loopback interface functions **
+** **
+\*****************************************************************************/
+
+#include "main.h"
+
+struct mISDNloop mISDNloop = { -1, 0 };
+
+void mISDNloop_close(void)
+{
+ if (mISDNloop.sock > -1)
+ close(mISDNloop.sock);
+ mISDNloop.sock = -1;
+}
+
+int mISDNloop_open()
+{
+ int ret;
+ int cnt;
+ unsigned long on = 1;
+ struct sockaddr_mISDN addr;
+ struct mISDN_devinfo devinfo;
+ int pri, bri;
+
+ /* already open */
+ if (mISDNloop.sock > -1)
+ return 0;
+
+ PDEBUG(DEBUG_PORT, "Open external interface of loopback.\n");
+
+ /* check port counts */
+ ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
+ if (ret < 0) {
+ fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
+ return(ret);
+ }
+
+ if (cnt <= 0) {
+ PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
+ return -EIO;
+ }
+ mISDNloop.port = mISDN_getportbyname(mISDNsocket, cnt, options.loopback_ext);
+ if (mISDNloop.port < 0) {
+ PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface?.\n", options.loopback_ext);
+ return mISDNloop.port;
+ }
+ /* get protocol */
+ bri = pri = 0;
+ devinfo.id = mISDNloop.port;
+ ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
+ if (ret < 0) {
+ PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", mISDNloop.port, ret);
+ return ret;
+ }
+ if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
+ bri = 1;
+ }
+ if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
+ pri = 1;
+ }
+ if (!bri && !pri) {
+ PERROR_RUNTIME("loop port %d does not support TE PRI or TE BRI.\n", mISDNloop.port);
+ }
+ /* open socket */
+ if ((mISDNloop.sock = socket(PF_ISDN, SOCK_DGRAM, (pri)?ISDN_P_TE_E1:ISDN_P_TE_S0)) < 0) {
+ PERROR_RUNTIME("loop port %d failed to open socket.\n", mISDNloop.port);
+ mISDNloop_close();
+ return mISDNloop.sock;
+ }
+ /* set nonblocking io */
+ if ((ret = ioctl(mISDNloop.sock, FIONBIO, &on)) < 0) {
+ PERROR_RUNTIME("loop port %d failed to set socket into nonblocking io.\n", mISDNloop.port);
+ mISDNloop_close();
+ return ret;
+ }
+ /* bind socket to dchannel */
+ memset(&addr, 0, sizeof(addr));
+ addr.family = AF_ISDN;
+ addr.dev = mISDNloop.port;
+ addr.channel = 0;
+ if ((ret = bind(mISDNloop.sock, (struct sockaddr *)&addr, sizeof(addr))) < 0) {
+ PERROR_RUNTIME("loop port %d failed to bind socket. (name = %s errno=%d)\n", mISDNloop.port, options.loopback_ext, errno);
+ mISDNloop_close();
+ return (ret);
+ }
+
+ return 0;
+}
+
+int loop_hunt_bchannel(class PmISDN *port, struct mISDNport *mISDNport)
+{
+ int channel;
+ int i;
+ char map[mISDNport->b_num];
+ struct interface *interface;
+ struct interface_port *ifport;
+
+ chan_trace_header(mISDNport, port, "CHANNEL SELECTION (setup)", DIRECTION_NONE);
+ add_trace("channel", "reserved", "%d", mISDNport->b_reserved);
+ if (mISDNport->b_reserved >= mISDNport->b_num) { // of out chan..
+ add_trace("conclusion", NULL, "all channels are reserved");
+ end_trace();
+ return(-34); // no channel
+ }
+
+ /* map all used ports of shared loopback interface */
+ memset(map, 0, sizeof(map));
+ interface = interface_first;
+ while(interface) {
+ ifport = interface->ifport;
+ while(ifport) {
+ if (!strcmp(ifport->portname, options.loopback_lcr)) {
+ i = 0;
+ while(i < mISDNport->b_num) {
+ if (mISDNport->b_port[i])
+ map[i] = 1;
+ i++;
+ }
+ }
+ ifport = ifport->next;
+ }
+ interface = interface->next;
+ }
+
+ /* find channel */
+ i = 0;
+ channel = 0;
+ while(i < mISDNport->b_num) {
+ if (!map[i]) {
+ channel = i+1+(i>=15);
+ break;
+ }
+ i++;
+ }
+ if (!channel) {
+ add_trace("conclusion", NULL, "no channel available");
+ end_trace();
+ return(-6); // channel unacceptable
+ }
+ add_trace("conclusion", NULL, "channel available");
+ add_trace("connect", "channel", "%d", channel);
+ end_trace();
+ return(channel);
+}
+
+
diff --git a/loop.h b/loop.h
new file mode 100644
index 0000000..cb2ad05
--- /dev/null
+++ b/loop.h
@@ -0,0 +1,12 @@
+
+struct mISDNloop {
+ int sock; /* loopback interface external side */
+ int port; /* port number for external side */
+};
+
+extern mISDNloop mISDNloop;
+
+void mISDNloop_close(void);
+int mISDNloop_open();
+int loop_hunt_bchannel(class PmISDN *port, struct mISDNport *mISDNport);
+
diff --git a/mISDN.cpp b/mISDN.cpp
index ee50bf1..50746ec 100644
--- a/mISDN.cpp
+++ b/mISDN.cpp
@@ -33,21 +33,6 @@ int __af_isdn = MISDN_AF_ISDN;
#define B_TIMER_ACTIVATING 1 // seconds
#define B_TIMER_DEACTIVATING 1 // seconds
-/* GSM condition */
-#if defined WITH_GSM_BS && defined WITH_GSM_MS
- #define MISDNPORT_GSM (mISDNport->gsm_bs || mISDNport->gsm_ms)
-#else
- #ifdef WITH_GSM_BS
- #define MISDNPORT_GSM (mISDNport->gsm_bs)
- #endif
- #ifdef WITH_GSM_MS
- #define MISDNPORT_GSM (mISDNport->gsm_ms)
- #endif
-#endif
-#ifndef MISDNPORT_GSM
- #define MISDNPORT_GSM (0)
-#endif
-
/* list of mISDN ports */
struct mISDNport *mISDNport_first;
@@ -671,7 +656,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
case B_STATE_IDLE:
if (p_m_remote_ref) {
/* export bchannel */
- message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
+ message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "assign");
add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
@@ -719,7 +704,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
/* in case, the bchannel is exported right after seize_bchannel */
/* export bchannel */
/* p_m_remote_id is set, when this event happens. */
- message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
+ message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "assign");
add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
@@ -774,7 +759,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
case B_STATE_REMOTE:
/* bchannel is exported, so we re-import */
- message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
+ message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "remove");
add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
@@ -825,7 +810,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
* OR bchannel is not used anymore
* OR bchannel has been exported to an obsolete ref,
* so reimport, to later export to new remote */
- message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
+ message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "remove");
add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
@@ -861,7 +846,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
case B_STATE_REMOTE:
/* bchannel is exported, so we re-import */
- message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
+ message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "remove");
add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
@@ -892,7 +877,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
if (b_port) {
/* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
if (p_m_remote_ref) {
- message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
+ message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "assign");
add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
@@ -924,7 +909,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
if (b_port) {
/* bchannel is now imported, but is requied by Port class, so we reactivate / export */
if (p_m_remote_ref) {
- message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
+ message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "assign");
add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
@@ -1382,7 +1367,11 @@ void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len
if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
+ if (!p_m_dtmf)
+ add_trace("info", NULL, "DTMF is disabled");
end_trace();
+ if (!p_m_dtmf)
+ return;
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
message->param.dtmf = cont & DTMF_TONE_MASK;
PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
@@ -1856,7 +1845,7 @@ static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, i
mISDNport = mISDNport_first;
while(mISDNport) {
/* handle queued up-messages (d-channel) */
- if (!MISDNPORT_GSM) {
+ if (!mISDNport->isloopback) {
while ((mb = mdequeue(&mISDNport->upqueue))) {
l3m = &mb->l3;
switch(l3m->type) {
@@ -1932,7 +1921,7 @@ static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, i
if (!mISDNport->ntmode || mISDNport->ptp)
mISDNport->l2link = 0;
}
- if (!MISDNPORT_GSM && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
+ if (!mISDNport->isloopback && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
if (!mISDNport->l2establish.active && mISDNport->l2hold) {
PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
schedule_timer(&mISDNport->l2establish, 5, 0);
@@ -1959,7 +1948,7 @@ static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
{
struct mISDNport *mISDNport = (struct mISDNport *)instance;
- if (!MISDNPORT_GSM && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
+ if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
// PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
@@ -2119,7 +2108,7 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport)
int force_nt = ifport->nt;
int l1hold = ifport->l1hold;
int l2hold = ifport->l2hold;
- int gsm = 0;
+ int loop = 0;
int ss5 = ifport->ss5;
int i, cnt;
int pri, bri, pots;
@@ -2129,15 +2118,23 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport)
unsigned int protocol, prop;
#if defined WITH_GSM_BS && defined WITH_GSM_MS
- gsm = ifport->gsm_ms | ifport->gsm_bs;
+ loop = ifport->gsm_ms | ifport->gsm_bs;
#else
#ifdef WITH_GSM_BS
- gsm = ifport->gsm_bs;
+ loop = ifport->gsm_bs;
#endif
#ifdef WITH_GSM_MS
- gsm = ifport->gsm_ms;
+ loop = ifport->gsm_ms;
#endif
#endif
+//printf("%s == %s\n", ifport->portname, options.loopback_int);
+ if (!strcmp(ifport->portname, options.loopback_lcr))
+ loop = 1;
+
+ if (loop) {
+ if (mISDNloop_open())
+ return NULL;
+ }
/* check port counts */
ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
@@ -2153,8 +2150,8 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport)
if (port < 0) {
port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
if (port < 0) {
- if (gsm)
- PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", ifport->portname);
+ if (loop)
+ PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface?.\n", ifport->portname);
else
PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
return(NULL);
@@ -2270,8 +2267,8 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport)
mISDNportp = &((*mISDNportp)->next);
mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
- if (gsm | ss5) {
- /* gsm/ss5 link is always active */
+ if (loop | ss5) {
+ /* loop/ss5 link is always active */
mISDNport->l1link = 1;
mISDNport->l2link = 1;
} else {
@@ -2284,6 +2281,7 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport)
#ifdef WITH_GSM_MS
mISDNport->gsm_ms = ifport->gsm_ms;
#endif
+ mISDNport->isloopback = loop;
pmemuse++;
*mISDNportp = mISDNport;
@@ -2325,25 +2323,24 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport)
if (l2hold) // supports layer 2 hold
prop |= (1 << MISDN_FLG_L2_HOLD);
/* open layer 3 and init upqueue */
- if (gsm) {
-#if defined WITH_GSM_BS || defined WITH_GSM_MS
+ if (loop) {
unsigned long on = 1;
struct sockaddr_mISDN addr;
if (devinfo.nrbchan < 8) {
- PERROR_RUNTIME("GSM port %d must have at least 8 b-channels.\n", port);
- mISDNport_close(mISDNport);
- return(NULL);
+ printf("loop port %d has a low number of bchannels. (only %d) remember that all interfaces that requires a loopback could run out of channels\n", port, devinfo.nrbchan);
+// mISDNport_close(mISDNport);
+// return(NULL);
}
- if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_NT_S0)) < 0) {
- PERROR_RUNTIME("GSM port %d failed to open socket.\n", port);
+ if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, (bri) ? ISDN_P_TE_S0 : ISDN_P_TE_E1)) < 0) {
+ PERROR_RUNTIME("loop port %d failed to open socket.\n", port);
mISDNport_close(mISDNport);
return(NULL);
}
/* set nonblocking io */
if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
- PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", port);
+ PERROR_RUNTIME("loop port %d failed to set socket into nonblocking io.\n", port);
mISDNport_close(mISDNport);
return(NULL);
}
@@ -2353,11 +2350,10 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport)
addr.dev = port;
addr.channel = 0;
if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- PERROR_RUNTIME("GSM port %d failed to bind socket. (errno %d)\n", port, errno);
+ PERROR_RUNTIME("loop port %d failed to bind socket. (errno %d)\n", port, errno);
mISDNport_close(mISDNport);
return(NULL);
}
-#endif
} else {
/* queue must be initializes, because l3-thread may send messages during open_layer3() */
mqueue_init(&mISDNport->upqueue);
@@ -2398,7 +2394,7 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport)
}
/* if ptp, pull up the link */
- if (!MISDNPORT_GSM && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
+ if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
add_trace("tei", NULL, "%d", 0);
@@ -2511,19 +2507,17 @@ void mISDNport_close(struct mISDNport *mISDNport)
del_timer(&mISDNport->l2establish);
/* close layer 3, if open */
- if (!MISDNPORT_GSM && mISDNport->ml3) {
+ if (!mISDNport->isloopback && mISDNport->ml3) {
close_layer3(mISDNport->ml3);
}
-#if defined WITH_GSM_BS || defined WITH_GSM_MS
/* close gsm socket, if open */
- if (MISDNPORT_GSM && mISDNport->lcr_sock > -1) {
+ if (mISDNport->isloopback && mISDNport->lcr_sock > -1) {
close(mISDNport->lcr_sock);
}
-#endif
/* purge upqueue */
- if (!MISDNPORT_GSM)
+ if (!mISDNport->isloopback)
mqueue_purge(&mISDNport->upqueue);
/* remove from list */
diff --git a/mISDN.h b/mISDN.h
index 644658b..de223c8 100644
--- a/mISDN.h
+++ b/mISDN.h
@@ -71,9 +71,8 @@ struct mISDNport {
#ifdef WITH_GSM_MS
int gsm_ms; /* this is the an GSM MS interface */
#endif
-#if defined WITH_GSM_BS || defined WITH_GSM_MS
int lcr_sock; /* socket of loopback on LCR side */
-#endif
+ int isloopback; /* will be set on open, in case it is a loopback if */
/* ss5 */
unsigned int ss5; /* set, if SS5 signalling enabled, also holds feature bits */
diff --git a/mail.c b/mail.c
index 445e268..0e34b77 100644
--- a/mail.c
+++ b/mail.c
@@ -99,7 +99,8 @@ static void *mail_child(void *arg)
fprintf(ph, "\n * date: %s %d %d %d:%02d\n\n", months[mon], mday, year+1900, hour, min);
/* attach audio file */
- if ((filename[0]) && ((fh = open(filename, O_RDONLY)))) {
+ if (filename[0]) {
+ if ((fh = open(filename, O_RDONLY))) {
while(strchr(filename, '/'))
filename = strchr(filename, '/')+1;
fprintf(ph, "--next_part\n");
@@ -144,11 +145,12 @@ static void *mail_child(void *arg)
fprintf(ph, "\n\n");
close(fh);
- } else {
+ } else {
SPRINT(buffer, "-Error- Failed to read audio file: '%s'.\n\n", filename);
fprintf(ph, "%s", buffer);
PERROR("%s", buffer);
- }
+ }
+ }
/* finish mail */
fprintf(ph, ".\n");
diff --git a/main.c b/main.c
index d293f7f..1aa2d8b 100644
--- a/main.c
+++ b/main.c
@@ -11,6 +11,11 @@
#include "main.h"
#include "config.h"
+#ifdef WITH_GSM_MS
+extern "C" {
+#include <osmocore/signal.h>
+}
+#endif
//MESSAGES
@@ -138,11 +143,23 @@ void _printerror(const char *function, int line, const char *fmt, ...)
void sighandler(int sigset)
{
struct sched_param schedp;
+#ifdef WITH_GSM_MS
+ int wait_ms = 0;
+#endif
if (sigset == SIGHUP)
return;
if (sigset == SIGPIPE)
return;
+ fprintf(stderr, "LCR: Signal received: %d\n", sigset);
+ PDEBUG(DEBUG_LOG, "Signal received: %d\n", sigset);
+#ifdef WITH_GSM_MS
+ if (!wait_ms) {
+ wait_ms = 1;
+ dispatch_signal(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
+ return;
+ }
+#endif
if (!quit) {
quit = sigset;
/* set scheduler & priority */
@@ -151,8 +168,6 @@ void sighandler(int sigset)
schedp.sched_priority = 0;
sched_setscheduler(0, SCHED_OTHER, &schedp);
}
- fprintf(stderr, "LCR: Signal received: %d\n", sigset);
- PDEBUG(DEBUG_LOG, "Signal received: %d\n", sigset);
}
}
@@ -469,12 +484,8 @@ int main(int argc, char *argv[])
if (options.gsm) {
if (handle_gsm())
all_idle = 0;
-#ifdef WITH_GSM_BS
- if (handle_gsm_bs())
- all_idle = 0;
-#endif
#ifdef WITH_GSM_MS
- if (handle_gsm_ms())
+ if (handle_gsm_ms(&quit))
all_idle = 0;
#endif
}
@@ -602,6 +613,10 @@ free:
#endif
}
+ /* close loopback, if used by GSM or remote */
+ if (mISDNloop.sock > -1)
+ mISDNloop_close();
+
/* display memory leak */
#define MEMCHECK(a, b) \
if (b) { \
diff --git a/main.h b/main.h
index 8e45581..7aad3c2 100644
--- a/main.h
+++ b/main.h
@@ -148,6 +148,8 @@ extern "C" {
#include "port.h"
#include "mISDN.h"
#include "dss1.h"
+#include "loop.h"
+#include "remote.h"
#if defined WITH_GSM_BS || defined WITH_GSM_MS
#include "gsm.h"
#endif
diff --git a/message.h b/message.h
index 471e2c8..c2076af 100644
--- a/message.h
+++ b/message.h
@@ -324,6 +324,7 @@ struct param_hello {
struct param_bchannel {
int type; /* BCHANNEL_* */
unsigned int handle; /* bchannel stack/portid */
+ int isloopback; /* in this case the application behaves like an interface, dsp should not be used */
int tx_gain, rx_gain;
char pipeline[256];
unsigned char crypt[128];
@@ -331,6 +332,11 @@ struct param_bchannel {
int crypt_type; /* 1 = blowfish */
};
+struct param_newref {
+ int direction; /* who requests a refe? */
+ int mode; /* 0 = direct-mode, 1 = PBX mode */
+};
+
/* structure of message parameter */
union parameter {
struct param_tone tone; /* MESSAGE_TONE */
@@ -355,7 +361,7 @@ union parameter {
struct param_crypt crypt; /* MESSAGE_CRYPT */
struct param_hello hello; /* MESSAGE_HELLO */
struct param_bchannel bchannel; /* MESSAGE_BCHANNEL */
- int direction; /* MESSAGE_NEWREF */
+ struct param_newref newref; /* MESSAGE_NEWREF */
};
enum { /* message flow */
@@ -428,6 +434,7 @@ enum { /* messages between entities */
"MESSAGE_RELEASE", \
"MESSAGE_TIMEOUT", \
"MESSAGE_NOTIFY", \
+ "MESSAGE_PROGRESS", \
"MESSAGE_FACILITY", \
"MESSAGE_SUSPEND", \
"MESSAGE_RESUME", \
diff --git a/missing b/missing
deleted file mode 100755
index 1c8ff70..0000000
--- a/missing
+++ /dev/null
@@ -1,367 +0,0 @@
-#! /bin/sh
-# Common stub for a few missing GNU programs while installing.
-
-scriptversion=2006-05-10.23
-
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
-# Free Software Foundation, Inc.
-# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-if test $# -eq 0; then
- echo 1>&2 "Try \`$0 --help' for more information"
- exit 1
-fi
-
-run=:
-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
-sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
-
-# In the cases where this matters, `missing' is being run in the
-# srcdir already.
-if test -f configure.ac; then
- configure_ac=configure.ac
-else
- configure_ac=configure.in
-fi
-
-msg="missing on your system"
-
-case $1 in
---run)
- # Try to run requested program, and just exit if it succeeds.
- run=
- shift
- "$@" && exit 0
- # Exit code 63 means version mismatch. This often happens
- # when the user try to use an ancient version of a tool on
- # a file that requires a minimum version. In this case we
- # we should proceed has if the program had been absent, or
- # if --run hadn't been passed.
- if test $? = 63; then
- run=:
- msg="probably too old"
- fi
- ;;
-
- -h|--h|--he|--hel|--help)
- echo "\
-$0 [OPTION]... PROGRAM [ARGUMENT]...
-
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
-
-Options:
- -h, --help display this help and exit
- -v, --version output version information and exit
- --run try to run the given command, and emulate it if it fails
-
-Supported PROGRAM values:
- aclocal touch file \`aclocal.m4'
- autoconf touch file \`configure'
- autoheader touch file \`config.h.in'
- autom4te touch the output file, or create a stub one
- automake touch all \`Makefile.in' files
- bison create \`y.tab.[ch]', if possible, from existing .[ch]
- flex create \`lex.yy.c', if possible, from existing .c
- help2man touch the output file
- lex create \`lex.yy.c', if possible, from existing .c
- makeinfo touch the output file
- tar try tar, gnutar, gtar, then tar without non-portable flags
- yacc create \`y.tab.[ch]', if possible, from existing .[ch]
-
-Send bug reports to <bug-automake@gnu.org>."
- exit $?
- ;;
-
- -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
- echo "missing $scriptversion (GNU Automake)"
- exit $?
- ;;
-
- -*)
- echo 1>&2 "$0: Unknown \`$1' option"
- echo 1>&2 "Try \`$0 --help' for more information"
- exit 1
- ;;
-
-esac
-
-# Now exit if we have it, but it failed. Also exit now if we
-# don't have it and --version was passed (most likely to detect
-# the program).
-case $1 in
- lex|yacc)
- # Not GNU programs, they don't have --version.
- ;;
-
- tar)
- if test -n "$run"; then
- echo 1>&2 "ERROR: \`tar' requires --run"
- exit 1
- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
- exit 1
- fi
- ;;
-
- *)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
- # Could not run --version or --help. This is probably someone
- # running `$TOOL --version' or `$TOOL --help' to check whether
- # $TOOL exists and not knowing $TOOL uses missing.
- exit 1
- fi
- ;;
-esac
-
-# If it does not exist, or fails to run (possibly an outdated version),
-# try to emulate it.
-case $1 in
- aclocal*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acinclude.m4' or \`${configure_ac}'. You might want
- to install the \`Automake' and \`Perl' packages. Grab them from
- any GNU archive site."
- touch aclocal.m4
- ;;
-
- autoconf)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`${configure_ac}'. You might want to install the
- \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
- archive site."
- touch configure
- ;;
-
- autoheader)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acconfig.h' or \`${configure_ac}'. You might want
- to install the \`Autoconf' and \`GNU m4' packages. Grab them
- from any GNU archive site."
- files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
- test -z "$files" && files="config.h"
- touch_files=
- for f in $files; do
- case $f in
- *:*) touch_files="$touch_files "`echo "$f" |
- sed -e 's/^[^:]*://' -e 's/:.*//'`;;
- *) touch_files="$touch_files $f.in";;
- esac
- done
- touch $touch_files
- ;;
-
- automake*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
- You might want to install the \`Automake' and \`Perl' packages.
- Grab them from any GNU archive site."
- find . -type f -name Makefile.am -print |
- sed 's/\.am$/.in/' |
- while read f; do touch "$f"; done
- ;;
-
- autom4te)
- echo 1>&2 "\
-WARNING: \`$1' is needed, but is $msg.
- You might have modified some files without having the
- proper tools for further handling them.
- You can get \`$1' as part of \`Autoconf' from any GNU
- archive site."
-
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo "#! /bin/sh"
- echo "# Created by GNU Automake missing as a replacement of"
- echo "# $ $@"
- echo "exit 0"
- chmod +x $file
- exit 1
- fi
- ;;
-
- bison|yacc)
- echo 1>&2 "\
-WARNING: \`$1' $msg. You should only need it if
- you modified a \`.y' file. You may need the \`Bison' package
- in order for those modifications to take effect. You can get
- \`Bison' from any GNU archive site."
- rm -f y.tab.c y.tab.h
- if test $# -ne 1; then
- eval LASTARG="\${$#}"
- case $LASTARG in
- *.y)
- SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.c
- fi
- SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.h
- fi
- ;;
- esac
- fi
- if test ! -f y.tab.h; then
- echo >y.tab.h
- fi
- if test ! -f y.tab.c; then
- echo 'main() { return 0; }' >y.tab.c
- fi
- ;;
-
- lex|flex)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.l' file. You may need the \`Flex' package
- in order for those modifications to take effect. You can get
- \`Flex' from any GNU archive site."
- rm -f lex.yy.c
- if test $# -ne 1; then
- eval LASTARG="\${$#}"
- case $LASTARG in
- *.l)
- SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" lex.yy.c
- fi
- ;;
- esac
- fi
- if test ! -f lex.yy.c; then
- echo 'main() { return 0; }' >lex.yy.c
- fi
- ;;
-
- help2man)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a dependency of a manual page. You may need the
- \`Help2man' package in order for those modifications to take
- effect. You can get \`Help2man' from any GNU archive site."
-
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo ".ab help2man is required to generate this page"
- exit 1
- fi
- ;;
-
- makeinfo)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.texi' or \`.texinfo' file, or any other file
- indirectly affecting the aspect of the manual. The spurious
- call might also be the consequence of using a buggy \`make' (AIX,
- DU, IRIX). You might want to install the \`Texinfo' package or
- the \`GNU make' package. Grab either from any GNU archive site."
- # The file to touch is that specified with -o ...
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -z "$file"; then
- # ... or it is the one specified with @setfilename ...
- infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
- file=`sed -n '
- /^@setfilename/{
- s/.* \([^ ]*\) *$/\1/
- p
- q
- }' $infile`
- # ... or it is derived from the source name (dir/f.texi becomes f.info)
- test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
- fi
- # If the file does not exist, the user really needs makeinfo;
- # let's fail without touching anything.
- test -f $file || exit 1
- touch $file
- ;;
-
- tar)
- shift
-
- # We have already tried tar in the generic part.
- # Look for gnutar/gtar before invocation to avoid ugly error
- # messages.
- if (gnutar --version > /dev/null 2>&1); then
- gnutar "$@" && exit 0
- fi
- if (gtar --version > /dev/null 2>&1); then
- gtar "$@" && exit 0
- fi
- firstarg="$1"
- if shift; then
- case $firstarg in
- *o*)
- firstarg=`echo "$firstarg" | sed s/o//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- case $firstarg in
- *h*)
- firstarg=`echo "$firstarg" | sed s/h//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- fi
-
- echo 1>&2 "\
-WARNING: I can't seem to be able to run \`tar' with the given arguments.
- You may want to install GNU tar or Free paxutils, or check the
- command line arguments."
- exit 1
- ;;
-
- *)
- echo 1>&2 "\
-WARNING: \`$1' is needed, and is $msg.
- You might have modified some files without having the
- proper tools for further handling them. Check the \`README' file,
- it often tells you about the needed prerequisites for installing
- this package. You may also peek at any GNU archive site, in case
- some other package would contain this missing \`$1' program."
- exit 1
- ;;
-esac
-
-exit 0
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/options.c b/options.c
index 88f6424..7fb9bcb 100644
--- a/options.c
+++ b/options.c
@@ -36,7 +36,9 @@ struct options options = {
-1, /* socket user (-1= no change) */
-1, /* socket group (-1= no change) */
0, /* enable gsm */
- 1 /* use polling of main loop */
+ 1, /* use polling of main loop */
+ "mISDN_l1loop.1", /* GSM/Asterisk side */
+ "mISDN_l1loop.2", /* LCR side */
};
char options_error[256];
@@ -239,6 +241,22 @@ int read_options(char *options_error)
} else
if (!strcmp(option,"polling")) {
options.polling = 1;
+ } else
+ if (!strcmp(option,"loopback-ext")) {
+ if (param[0]==0) {
+ UPRINT(options_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
+ goto error;
+ }
+ SCPY(options.loopback_ext, param);
+
+ } else
+ if (!strcmp(option,"loopback-lcr")) {
+ if (param[0]==0) {
+ UPRINT(options_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option);
+ goto error;
+ }
+ SCPY(options.loopback_lcr, param);
+
} else {
UPRINT(options_error, "Error in %s (line %d): wrong option keyword %s.\n", filename,line,option);
goto error;
diff --git a/options.h b/options.h
index c13ee2c..c7f9f8f 100644
--- a/options.h
+++ b/options.h
@@ -31,6 +31,8 @@ struct options {
int socketgroup; /* socket chgrp to this group */
int gsm; /* enable gsm support */
int polling;
+ char loopback_ext[64]; /* loopback interface GSM side */
+ char loopback_lcr[64]; /* loopback interface LCR side */
};
extern struct options options;
diff --git a/port.h b/port.h
index d7c0580..a4da7de 100644
--- a/port.h
+++ b/port.h
@@ -22,10 +22,14 @@
#define PORT_CLASS_GSM_BS 0x1210
#define PORT_CLASS_GSM_MS 0x1220
#define PORT_CLASS_SS5 0x1300
+#define PORT_CLASS_REMOTE 0x1400
#define PORT_CLASS_MASK 0xf000
#define PORT_CLASS_mISDN_MASK 0xff00
#define PORT_CLASS_DSS1_MASK 0xfff0
#define PORT_CLASS_GSM_MASK 0xfff0
+#define PORT_CLASS_DIR_MASK 0x000f
+#define PORT_CLASS_DIR_IN 0x0001
+#define PORT_CLASS_DIR_OUT 0x0002
/* nt-mode */
#define PORT_TYPE_DSS1_NT_IN 0x1111
#define PORT_TYPE_DSS1_NT_OUT 0x1112
@@ -41,6 +45,9 @@
#define PORT_TYPE_SS5_IN 0x1311
#define PORT_TYPE_SS5_OUT 0x1312
#define PORT_TYPE_SS5_IDLE 0x1313
+ /* remote */
+#define PORT_TYPE_REMOTE_IN 0x1411
+#define PORT_TYPE_REMOTE_OUT 0x1412
/* answering machine */
#define PORT_TYPE_VBOX_OUT 0x3111
diff --git a/remote.cpp b/remote.cpp
new file mode 100644
index 0000000..e14c8e3
--- /dev/null
+++ b/remote.cpp
@@ -0,0 +1,221 @@
+/*****************************************************************************\
+** **
+** LCR **
+** **
+**---------------------------------------------------------------------------**
+** Copyright: Andreas Eversberg **
+** **
+** mISDN remote **
+** **
+\*****************************************************************************/
+
+#include "main.h"
+
+unsigned int new_remote = 0x00000001;
+
+/*
+ * constructor
+ */
+Premote::Premote(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode, int remote_id) : PmISDN(type, mISDNport, portname, settings, channel, exclusive, mode)
+{
+ union parameter param;
+
+ p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
+ p_m_r_ref = new_remote++;
+ SCPY(p_m_r_remote_app, mISDNport->ifport->remote_app);
+ p_m_r_handle = 0;
+
+ /* send new ref to remote socket */
+ memset(&param, 0, sizeof(union parameter));
+ if (type == PORT_TYPE_REMOTE_OUT)
+ param.newref.direction = 1; /* new ref from lcr */
+ p_m_r_remote_id = remote_id;
+ if (admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_NEWREF, &param) < 0)
+ FATAL("No socket with remote application '%s' found, this shall not happen. because we already created one.\n", mISDNport->ifport->remote_app);
+
+ PDEBUG(DEBUG_GSM, "Created new RemotePort(%s).\n", portname);
+
+}
+
+/*
+ * destructor
+ */
+Premote::~Premote()
+{
+ /* need to remote (import) external channel from remote application */
+ if (p_m_r_handle) {
+ message_bchannel_to_remote(p_m_r_remote_id, p_m_r_ref, BCHANNEL_REMOVE, p_m_r_handle, 0, 0, 0, 0, 0, 0, 1);
+ chan_trace_header(p_m_mISDNport, this, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, "remove");
+ add_trace("channel", NULL, "%d.%d", p_m_r_handle>>8, p_m_r_handle&0xff);
+ end_trace();
+ }
+
+ PDEBUG(DEBUG_GSM, "Destroyed Remote process(%s).\n", p_name);
+
+}
+
+/*
+ * endpoint sends messages to the port
+ */
+int Premote::message_epoint(unsigned int epoint_id, int message_type, union parameter *param)
+{
+ struct lcr_msg *message;
+ int channel;
+ int ret;
+ struct epoint_list *epointlist;
+
+ if (PmISDN::message_epoint(epoint_id, message_type, param))
+ return 1;
+
+ if (message_type == MESSAGE_SETUP) {
+ ret = channel = hunt_bchannel();
+ if (ret < 0)
+ goto no_channel;
+ /* open channel */
+ ret = seize_bchannel(channel, 1);
+ if (ret < 0) {
+ no_channel:
+ message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
+ message->param.disconnectinfo.cause = 34;
+ message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+ message_put(message);
+ new_state(PORT_STATE_RELEASE);
+ delete this;
+ return 0;
+ }
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
+
+ /* attach only if not already */
+ epointlist = p_epointlist;
+ while(epointlist) {
+ if (epointlist->epoint_id == epoint_id)
+ break;
+ epointlist = epointlist->next;
+ }
+ if (!epointlist)
+ epointlist_new(epoint_id);
+
+ /* set context to pbx */
+ SCPY(param->setup.context, "pbx");
+ }
+
+ /* look for Remote's interface */
+ if (admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, message_type, param)<0) {
+ PERROR("No socket with remote application '%s' found, this shall not happen. Closing socket shall cause release of all remote ports.\n", p_m_mISDNport->ifport->remote_app);
+ return 0;
+ }
+
+ /* enable audio path */
+ if (message_type == MESSAGE_SETUP) {
+ union parameter newparam;
+ memset(&newparam, 0, sizeof(union parameter));
+ admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_PATTERN, &newparam);
+ newparam.audiopath = 1;
+ admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_AUDIOPATH, &newparam);
+ }
+
+ if (message_type == MESSAGE_RELEASE) {
+ new_state(PORT_STATE_RELEASE);
+ delete this;
+ return 0;
+ }
+
+ return 0;
+}
+
+void Premote::message_remote(int message_type, union parameter *param)
+{
+ class Endpoint *epoint;
+ struct lcr_msg *message;
+ int channel;
+ int ret;
+
+ if (message_type == MESSAGE_SETUP) {
+ /* enable audio path */
+ union parameter newparam;
+ memset(&newparam, 0, sizeof(union parameter));
+ admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_PATTERN, &newparam);
+ newparam.audiopath = 1;
+ admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_AUDIOPATH, &newparam);
+
+ /* set source interface */
+ param->setup.callerinfo.itype = p_callerinfo.itype;
+ param->setup.callerinfo.isdn_port = p_m_portnum;
+ SCPY(param->setup.callerinfo.interface, p_m_mISDNport->ifport->interface->name);
+
+ ret = channel = hunt_bchannel();
+ if (ret < 0)
+ goto no_channel;
+
+ /* open channel */
+ ret = seize_bchannel(channel, 1);
+ if (ret < 0) {
+ no_channel:
+ message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
+ message->param.disconnectinfo.cause = 34;
+ message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+ message_put(message);
+ new_state(PORT_STATE_RELEASE);
+ delete this;
+ return;
+ }
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
+
+ /* create endpoint */
+ if (p_epointlist)
+ FATAL("Incoming call but already got an endpoint.\n");
+ if (!(epoint = new Endpoint(p_serial, 0)))
+ FATAL("No memory for Endpoint instance\n");
+ if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming
+ FATAL("No memory for Endpoint Application instance\n");
+
+ epointlist_new(epoint->ep_serial);
+ }
+
+ /* set serial on bchannel message
+ * also ref is given, so we send message with ref */
+ if (message_type == MESSAGE_BCHANNEL) {
+ int i = p_m_b_index;
+ unsigned int portid = (mISDNloop.port<<8) + i+1+(i>=15);
+ switch (param->bchannel.type) {
+ case BCHANNEL_REQUEST:
+ p_m_r_handle = portid;
+ message_bchannel_to_remote(p_m_r_remote_id, p_m_r_ref, BCHANNEL_ASSIGN, portid, 0, 0, 0, 0, 0, 0, 1);
+ chan_trace_header(p_m_mISDNport, this, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, "assign");
+ add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
+ end_trace();
+ break;
+ case BCHANNEL_RELEASE:
+ p_m_r_handle = 0;
+ message_bchannel_to_remote(p_m_r_remote_id, p_m_r_ref, BCHANNEL_REMOVE, portid, 0, 0, 0, 0, 0, 0, 1);
+ chan_trace_header(p_m_mISDNport, this, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, "remove");
+ add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
+ end_trace();
+ break;
+ }
+ return;
+ }
+
+ /* cannot just forward, because param is not of container "struct lcr_msg" */
+ message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, message_type);
+ memcpy(&message->param, param, sizeof(message->param));
+ message_put(message);
+
+ if (message_type == MESSAGE_RELEASE) {
+ new_state(PORT_STATE_RELEASE);
+ delete this;
+ return;
+ }
+}
+
+/* select free bchannel from loopback interface */
+int Premote::hunt_bchannel(void)
+{
+ return loop_hunt_bchannel(this, p_m_mISDNport);
+}
+
+
+
diff --git a/remote.h b/remote.h
new file mode 100644
index 0000000..f39245b
--- /dev/null
+++ b/remote.h
@@ -0,0 +1,20 @@
+
+/* GSM port class */
+class Premote : public PmISDN
+{
+ public:
+ Premote(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode, int remote_id);
+ ~Premote();
+
+ unsigned int p_m_r_ref;
+ int p_m_r_remote_id; /* remote instance (socket) */
+ char p_m_r_remote_app[32];
+ unsigned int p_m_r_handle; /* 0, if no bchannel is exported */
+
+ int message_epoint(unsigned int epoint_id, int message_id, union parameter *param);
+ void message_remote(int message_type, union parameter *param);
+
+ int hunt_bchannel(void);
+};
+
+
diff --git a/route.c b/route.c
index f72d6b0..8217ff1 100644
--- a/route.c
+++ b/route.c
@@ -1902,6 +1902,7 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
struct admin_list *admin;
time_t now;
struct tm *now_tm;
+ int pid2;
/* reset timeout action */
e_match_to_action = NULL;
@@ -2071,9 +2072,11 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
case MATCH_EXECUTE:
j = 0;
+#if 0
argv[j++] = (char *)"/bin/sh";
argv[j++] = (char *)"-c";
argv[j++] = cond->string_value;
+#endif
argv[j++] = cond->string_value;
argv[j++] = e_extdialing;
argv[j++] = (char *)numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype, options.national, options.international);
@@ -2083,8 +2086,11 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
argv[j++] = isdn_port;
argv[j++] = e_callerinfo.imsi;
argv[j++] = NULL; /* check also number of args above */
- if (execve("/bin/sh", argv, environ) == 0)
- istrue = 1;
+ if (fork() == 0) {
+ if ((pid2 = fork()) == 0) {
+ execve(cond->string_value, argv, environ);
+ }
+ }
break;
case MATCH_DEFAULT:
diff --git a/socket_server.c b/socket_server.c
index e84fa5e..32c6e71 100644
--- a/socket_server.c
+++ b/socket_server.c
@@ -84,6 +84,8 @@ void free_connection(struct admin_list *admin)
struct mISDNport *mISDNport;
int i, ii;
struct admin_list **adminp;
+ class Port *port, *portnext;
+ class Premote *remote;
/* free remote joins */
if (admin->remote_name[0]) {
@@ -126,6 +128,22 @@ void free_connection(struct admin_list *admin)
}
join = joinnext;
}
+ /* release remote port */
+ port = port_first;
+ while(port) {
+ portnext = port->next;
+ if ((port->p_type & PORT_CLASS_MASK) == PORT_CLASS_REMOTE) {
+ remote = (class Premote *) port;
+ if (remote->p_m_r_remote_id == admin->sock) {
+ memset(&param, 0, sizeof(param));
+ param.disconnectinfo.cause = CAUSE_OUTOFORDER;
+ param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+ remote->message_remote(MESSAGE_RELEASE, &param);
+ /* port is now destroyed, so we go to next join */
+ }
+ }
+ port = portnext;
+ }
}
if (admin->sock >= 0) {
@@ -586,9 +604,13 @@ void admin_call_response(int adminid, int message, const char *connected, int ca
/*
* send data to the remote socket join instance
*/
-int admin_message_to_join(struct admin_msg *msg, struct admin_list *admin)
+int admin_message_to_lcr(struct admin_msg *msg, struct admin_list *admin)
{
+ struct mISDNport *mISDNport;
class Join *join;
+ class JoinRemote *joinremote = NULL; /* make GCC happy */
+ class Port *port;
+ class Premote *remote = NULL; /* make GCC happy */
struct admin_list *temp;
/* hello message */
@@ -629,13 +651,44 @@ int admin_message_to_join(struct admin_msg *msg, struct admin_list *admin)
return(-1);
}
- /* new join */
+ /* new join. the reply (NEWREF assignment) is sent from constructor */
if (msg->type == MESSAGE_NEWREF) {
- /* create new join instance */
- join = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected
- if (!join) {
- FATAL("No memory for remote join instance\n");
- return(-1);
+ if (msg->param.newref.mode) {
+ char name[32];
+ /* find remote port */
+ mISDNport = mISDNport_first;
+ while(mISDNport) {
+ if (mISDNport->ifport->remote && !strcmp(mISDNport->ifport->remote_app, admin->remote_name))
+ break;
+ mISDNport = mISDNport->next;
+ }
+ if (!mISDNport) {
+ union parameter param;
+
+ /* create new join instance */
+ join = joinremote = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected
+ if (!join) {
+ FATAL("No memory for remote join instance\n");
+ return(-1);
+ }
+ memset(&param, 0, sizeof(union parameter));
+ param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+ param.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
+ admin_message_from_lcr(joinremote->j_remote_id, joinremote->j_remote_ref, MESSAGE_RELEASE, &param);
+ return 0;
+ }
+ /* creating port object, transparent until setup with hdlc */
+ SPRINT(name, "%s-%s-in", mISDNport->ifport->interface->name, mISDNport->ifport->remote_app);
+ if (!(remote = new Premote(PORT_TYPE_REMOTE_IN, mISDNport, name, NULL, 0, 0, B_MODE_TRANSPARENT, admin->sock)))
+
+ FATAL("Cannot create Port instance.\n");
+ } else {
+ /* create new join instance */
+ join = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected
+ if (!join) {
+ FATAL("No memory for remote join instance\n");
+ return(-1);
+ }
}
return(0);
}
@@ -660,36 +713,56 @@ int admin_message_to_join(struct admin_msg *msg, struct admin_list *admin)
/* find join instance */
join = join_first;
while(join) {
- if (join->j_serial == msg->ref)
- break;
+ if (join->j_type == JOIN_TYPE_REMOTE) {
+ joinremote = (class JoinRemote *)join;
+ if (joinremote->j_remote_ref == msg->ref)
+ break;
+ }
join = join->next;
}
- if (!join) {
- PDEBUG(DEBUG_LOG, "No join found with serial %d. (May have been already released.)\n", msg->ref);
+ if (join) {
+ if (admin->sock != joinremote->j_remote_id) {
+ PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, joinremote->j_remote_name, admin->remote_name);
+ return(-1);
+ }
+ /* send message */
+ joinremote->message_remote(msg->type, &msg->param);
+
return(0);
}
- /* check application */
- if (join->j_type != JOIN_TYPE_REMOTE) {
- PERROR("Ref %d does not belong to a remote join instance.\n", msg->ref);
- return(-1);
- }
- if (admin->sock != ((class JoinRemote *)join)->j_remote_id) {
- PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, ((class JoinRemote *)join)->j_remote_name, admin->remote_name);
- return(-1);
+ /* find port instance */
+ port = port_first;
+ while(port) {
+ if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_REMOTE) {
+ remote = (class Premote *) port;
+ if (remote->p_m_r_ref == msg->ref)
+ break;
+ }
+ port = port->next;
}
+ if (port) {
+ if (admin->sock != remote->p_m_r_remote_id) {
+ PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, remote->p_m_r_remote_app, admin->remote_name);
+ return(-1);
+ }
+
+ /* send message */
+ remote->message_remote(msg->type, &msg->param);
- /* send message */
- ((class JoinRemote *)join)->message_remote(msg->type, &msg->param);
+ return(0);
+ }
+ PDEBUG(DEBUG_LOG, "No remote instance found with ref %d. (May have been already released.)\n", msg->ref);
return(0);
+
}
/*
* this function is called for every message to remote socket
*/
-int admin_message_from_join(int remote_id, unsigned int ref, int message_type, union parameter *param)
+int admin_message_from_lcr(int remote_id, unsigned int ref, int message_type, union parameter *param)
{
struct admin_list *admin;
struct admin_queue **responsep; /* response pointer */
@@ -1234,7 +1307,7 @@ int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int i
break;
case ADMIN_MESSAGE:
- if (admin_message_to_join(&msg.u.msg, admin) < 0) {
+ if (admin_message_to_lcr(&msg.u.msg, admin) < 0) {
PERROR("Failed to deliver message for socket %d.\n", admin->sock);
goto response_error;
}
@@ -1281,3 +1354,24 @@ int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int i
return 0;
}
+void message_bchannel_to_remote(unsigned int remote_id, unsigned int ref, int type, unsigned int handle, int tx_gain, int rx_gain, char *pipeline, unsigned char *crypt, int crypt_len, int crypt_type, int isloopback)
+{
+ union parameter param;
+
+ memset(&param, 0, sizeof(union parameter));
+ param.bchannel.isloopback = isloopback;
+ param.bchannel.type = type;
+ param.bchannel.handle = handle;
+ param.bchannel.tx_gain = tx_gain;
+ param.bchannel.rx_gain = rx_gain;
+ if (pipeline)
+ SCPY(param.bchannel.pipeline, pipeline);
+ if (crypt_len)
+ memcpy(param.bchannel.crypt, crypt, crypt_len);
+ param.bchannel.crypt_type = crypt_type;
+ if (admin_message_from_lcr(remote_id, ref, MESSAGE_BCHANNEL, &param)<0) {
+ PERROR("No socket with remote id %d found, this happens, if the socket is closed before all bchannels are imported.\n", remote_id);
+ return;
+ }
+}
+
diff --git a/socket_server.h b/socket_server.h
index b3ea89a..9a31b10 100644
--- a/socket_server.h
+++ b/socket_server.h
@@ -33,8 +33,9 @@ extern struct admin_list *admin_first;
int admin_init(void);
void admin_cleanup(void);
void admin_call_response(int adminid, int message, const char *connected, int cause, int location, int notify);
-int admin_message_to_join(struct admin_message *msg, int remote_id);
-int admin_message_from_join(int remote_id, unsigned int ref, int message_type, union parameter *param);
+int admin_message_to_lcr(struct admin_message *msg, int remote_id);
+int admin_message_from_lcr(int remote_id, unsigned int ref, int message_type, union parameter *param);
+void message_bchannel_to_remote(unsigned int remote_id, unsigned int ref, int type, unsigned int handle, int tx_gain, int rx_gain, char *pipeline, unsigned char *crypt, int crypt_len, int crypt_type, int isloopback);