Merge branch 'develop'
authorAndreas Eversberg <jolly@eversberg.eu>
Thu, 14 Jul 2011 12:25:42 +0000 (14:25 +0200)
committerAndreas Eversberg <jolly@eversberg.eu>
Thu, 14 Jul 2011 12:25:42 +0000 (14:25 +0200)
Conflicts:
Makefile.in
README
chan_lcr.c
configure
gsm_bs.cpp
gsm_ms.cpp
interface.c
route.c

46 files changed:
.gitignore
INSTALL
Makefile.am
Makefile.in
README
aclocal.m4 [deleted file]
action.cpp
apppbx.cpp
chan_lcr.c
chan_lcr.h
config.h.in [deleted file]
configure
configure.ac
default/gsm.conf [deleted file]
default/interface.conf
default/options.conf
depcomp [deleted file]
gsm.cpp
gsm.h
gsm_bs.cpp
gsm_bs.h
gsm_conf.c [deleted file]
gsm_ms.cpp
gsm_ms.h
install-sh [deleted file]
interface.c
interface.h
joinremote.cpp
joinremote.h
loop.c [new file with mode: 0644]
loop.h [new file with mode: 0644]
mISDN.cpp
mISDN.h
mail.c
main.c
main.h
message.h
missing [deleted file]
options.c
options.h
port.h
remote.cpp [new file with mode: 0644]
remote.h [new file with mode: 0644]
route.c
socket_server.c
socket_server.h

index f551c7f..570e576 100644 (file)
@@ -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 (file)
--- 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.
 
index d8ba3bf..f047c56 100644 (file)
@@ -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       \
index 067dfe1..5930a8e 100644 (file)
@@ -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 (file)
--- 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 (file)
index 61989b2..0000000
+++ /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])
index b7dfc58..352efb4 100644 (file)
@@ -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 */
index f92f167..fff80ce 100644 (file)
@@ -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;
index f4d8378..3904c9a 100644 (file)
@@ -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();
index e7ea0f5..8caa48e 100644 (file)
@@ -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 (file)
index b871dc3..0000000
+++ /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
index 5ccc9cf..4c24728 100755 (executable)
--- 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\\"
 
index 81eb404..5e01e41 100644 (file)
@@ -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 (file)
index 148513b..0000000
+++ /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
-
-
index 6e19538..004df59 100644 (file)
 # 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
 ##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.
 
 
index e0e93a0..d1f4d6b 100644 (file)
 #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
 # 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 (executable)
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 (file)
--- 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 (file)
--- 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;
index 584b7e2..22ac70c 100644 (file)
 #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;
+}
index fd56efe..8a55213 100644 (file)
--- 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 (file)
index a64f2ff..0000000
+++ /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);
-}
-
-
index 551fcad..c8292f9 100644 (file)
 #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;
 }
index 3e9794f..822f0a6 100644 (file)
--- 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 (executable)
index 4fbbae7..0000000
+++ /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:
index 09e0067..4e432af 100644 (file)
@@ -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 */
index d1bea04..f271080 100644 (file)
@@ -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 */
index 167bbce..c02de8e 100644 (file)
@@ -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;         
-       }
-}
-
 
 
index 1582133..a933466 100644 (file)
@@ -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 (file)
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 (file)
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);
+
index ee50bf1..50746ec 100644 (file)
--- 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 (file)
--- 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 (file)
--- 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 (file)
--- a/main.c
+++ b/main.c
 
 #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 (file)
--- 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
index 471e2c8..c2076af 100644 (file)
--- 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 (executable)
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:
index 88f6424..7fb9bcb 100644 (file)
--- 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;
index c13ee2c..c7f9f8f 100644 (file)
--- 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 (file)
--- a/port.h
+++ b/port.h
 #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 (file)
index 0000000..e14c8e3
--- /dev/null
@@ -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 (file)
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 (file)
--- 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:
index e84fa5e..32c6e71 100644 (file)
@@ -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;         
+       }
+}
+
index b3ea89a..9a31b10 100644 (file)
@@ -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);