First commit of a CAPI-FAX application.
This commit is contained in:
parent
63eee5197e
commit
172e405496
|
@ -0,0 +1,22 @@
|
|||
##
|
||||
## $Id: Makefile.am,v 1.1 1998/10/23 12:27:39 fritz Exp $
|
||||
##
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
CLEANFILES = *~
|
||||
MAINTAINERCLEANFILES = configure aclocal.m4 Makefile.in config.h.in \
|
||||
stamp-h.in
|
||||
|
||||
INCLUDES = -I../capi20 $(all_includes)
|
||||
CFLAGS = -Wall -O2
|
||||
LDFLAGS = -L../capi20 $(all_libraries)
|
||||
LDADD = -lcapi20
|
||||
|
||||
bin_PROGRAMS = capifax capifaxrcvd
|
||||
|
||||
common = c20msg.c capi.c connect.c contr.c data.c id.c init.c fax.c
|
||||
|
||||
capifax_SOURCES = $(common) capifax.c
|
||||
|
||||
capifaxrcvd_SOURCES = $(common) capifaxrcvd.c
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
all:
|
||||
@echo "Use make devel for development, make dist for distribution"
|
||||
|
||||
devel:
|
||||
aclocal
|
||||
autoheader
|
||||
automake
|
||||
autoconf
|
||||
touch stamp-h.in
|
||||
|
||||
dist:
|
||||
cat acinclude.m4.in libtool.m4.in > acinclude.m4
|
||||
aclocal
|
||||
autoheader
|
||||
automake --foreign --include-deps
|
||||
autoconf
|
||||
touch stamp-h.in
|
|
@ -0,0 +1,380 @@
|
|||
# Makefile.in generated automatically by automake 1.3 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
# This Makefile.in 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.
|
||||
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DISTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = .
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
CC = @CC@
|
||||
CONFIG_KERNELDIR = @CONFIG_KERNELDIR@
|
||||
CONFIG_MANDIR = @CONFIG_MANDIR@
|
||||
CONFIG_SBINDIR = @CONFIG_SBINDIR@
|
||||
DBMLIB = @DBMLIB@
|
||||
I4LCONFDIR = @I4LCONFDIR@
|
||||
I4LVERSION = @I4LVERSION@
|
||||
INSTALL = @INSTALL@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANDATE = @MANDATE@
|
||||
PACKAGE = @PACKAGE@
|
||||
VERSION = @VERSION@
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
CLEANFILES = *~
|
||||
MAINTAINERCLEANFILES = configure aclocal.m4 Makefile.in config.h.in \
|
||||
stamp-h.in
|
||||
|
||||
INCLUDES = -I../capi20 $(all_includes)
|
||||
CFLAGS = -Wall -O2
|
||||
LDFLAGS = -L../capi20 $(all_libraries)
|
||||
LDADD = -lcapi20
|
||||
|
||||
bin_PROGRAMS = capifax capifaxrcvd
|
||||
|
||||
common = c20msg.c capi.c connect.c contr.c data.c id.c init.c fax.c
|
||||
|
||||
capifax_SOURCES = $(common) capifax.c
|
||||
|
||||
capifaxrcvd_SOURCES = $(common) capifaxrcvd.c
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
PROGRAMS = $(bin_PROGRAMS)
|
||||
|
||||
|
||||
DEFS = @DEFS@ -I. -I$(srcdir) -I.
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LIBS = @LIBS@
|
||||
capifax_OBJECTS = c20msg.o capi.o connect.o contr.o data.o id.o init.o \
|
||||
fax.o capifax.o
|
||||
capifax_LDADD = $(LDADD)
|
||||
capifax_DEPENDENCIES =
|
||||
capifax_LDFLAGS =
|
||||
capifaxrcvd_OBJECTS = c20msg.o capi.o connect.o contr.o data.o id.o \
|
||||
init.o fax.o capifaxrcvd.o
|
||||
capifaxrcvd_LDADD = $(LDADD)
|
||||
capifaxrcvd_DEPENDENCIES =
|
||||
capifaxrcvd_LDFLAGS =
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
||||
LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
DIST_COMMON = Makefile.am Makefile.in acconfig.h aclocal.m4 config.h.in \
|
||||
configure configure.in install-sh missing mkinstalldirs stamp-h.in
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP = --best
|
||||
DEP_FILES = .deps/c20msg.P .deps/capi.P .deps/capifax.P \
|
||||
.deps/capifaxrcvd.P .deps/connect.P .deps/contr.P .deps/data.P \
|
||||
.deps/fax.P .deps/id.P .deps/init.P
|
||||
SOURCES = $(capifax_SOURCES) $(capifaxrcvd_SOURCES)
|
||||
OBJECTS = $(capifax_OBJECTS) $(capifaxrcvd_OBJECTS)
|
||||
|
||||
all: Makefile $(PROGRAMS) config.h
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .S .c .o .s
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
$(ACLOCAL_M4): configure.in
|
||||
cd $(srcdir) && $(ACLOCAL)
|
||||
|
||||
config.status: $(srcdir)/configure
|
||||
$(SHELL) ./config.status --recheck
|
||||
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
|
||||
cd $(srcdir) && $(AUTOCONF)
|
||||
|
||||
config.h: stamp-h
|
||||
@:
|
||||
stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES= CONFIG_HEADERS=config.h \
|
||||
$(SHELL) ./config.status
|
||||
@echo timestamp > stamp-h
|
||||
$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
|
||||
$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
|
||||
cd $(top_srcdir) && $(AUTOHEADER)
|
||||
@echo timestamp > $(srcdir)/stamp-h.in
|
||||
|
||||
mostlyclean-hdr:
|
||||
|
||||
clean-hdr:
|
||||
|
||||
distclean-hdr:
|
||||
-rm -f config.h
|
||||
|
||||
maintainer-clean-hdr:
|
||||
|
||||
mostlyclean-binPROGRAMS:
|
||||
|
||||
clean-binPROGRAMS:
|
||||
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
|
||||
|
||||
distclean-binPROGRAMS:
|
||||
|
||||
maintainer-clean-binPROGRAMS:
|
||||
|
||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(bindir)
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-binPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
|
||||
done
|
||||
|
||||
.s.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.S.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.o core *.core
|
||||
|
||||
clean-compile:
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
maintainer-clean-compile:
|
||||
|
||||
capifax: $(capifax_OBJECTS) $(capifax_DEPENDENCIES)
|
||||
@rm -f capifax
|
||||
$(LINK) $(capifax_LDFLAGS) $(capifax_OBJECTS) $(capifax_LDADD) $(LIBS)
|
||||
|
||||
capifaxrcvd: $(capifaxrcvd_OBJECTS) $(capifaxrcvd_DEPENDENCIES)
|
||||
@rm -f capifaxrcvd
|
||||
$(LINK) $(capifaxrcvd_LDFLAGS) $(capifaxrcvd_OBJECTS) $(capifaxrcvd_LDADD) $(LIBS)
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP)
|
||||
here=`pwd` && cd $(srcdir) \
|
||||
&& mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
|
||||
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
|
||||
|
||||
mostlyclean-tags:
|
||||
|
||||
clean-tags:
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID
|
||||
|
||||
maintainer-clean-tags:
|
||||
|
||||
distdir = $(PACKAGE)-$(VERSION)
|
||||
top_distdir = $(distdir)
|
||||
|
||||
# This target untars the dist file and tries a VPATH configuration. Then
|
||||
# it guarantees that the distribution is self-contained by making another
|
||||
# tarfile.
|
||||
distcheck: dist
|
||||
-rm -rf $(distdir)
|
||||
GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz
|
||||
mkdir $(distdir)/=build
|
||||
mkdir $(distdir)/=inst
|
||||
dc_install_base=`cd $(distdir)/=inst && pwd`; \
|
||||
cd $(distdir)/=build \
|
||||
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
|
||||
&& $(MAKE) \
|
||||
&& $(MAKE) dvi \
|
||||
&& $(MAKE) check \
|
||||
&& $(MAKE) install \
|
||||
&& $(MAKE) installcheck \
|
||||
&& $(MAKE) dist
|
||||
-rm -rf $(distdir)
|
||||
@echo "========================"; \
|
||||
echo "$(distdir).tar.gz is ready for distribution"; \
|
||||
echo "========================"
|
||||
dist: distdir
|
||||
-chmod -R a+r $(distdir)
|
||||
GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
|
||||
-rm -rf $(distdir)
|
||||
dist-all: distdir
|
||||
-chmod -R a+r $(distdir)
|
||||
GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
|
||||
-rm -rf $(distdir)
|
||||
distdir: $(DISTFILES)
|
||||
-rm -rf $(distdir)
|
||||
mkdir $(distdir)
|
||||
-chmod 777 $(distdir)
|
||||
here=`cd $(top_builddir) && pwd`; \
|
||||
top_distdir=`cd $(distdir) && pwd`; \
|
||||
distdir=`cd $(distdir) && pwd`; \
|
||||
cd $(top_srcdir) \
|
||||
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file; \
|
||||
done
|
||||
|
||||
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
|
||||
|
||||
-include $(DEP_FILES)
|
||||
|
||||
mostlyclean-depend:
|
||||
|
||||
clean-depend:
|
||||
|
||||
distclean-depend:
|
||||
|
||||
maintainer-clean-depend:
|
||||
-rm -rf .deps
|
||||
|
||||
%.o: %.c
|
||||
@echo '$(COMPILE) -c $<'; \
|
||||
$(COMPILE) -Wp,-MD,.deps/$(*F).P -c $<
|
||||
|
||||
%.lo: %.c
|
||||
@echo '$(LTCOMPILE) -c $<'; \
|
||||
$(LTCOMPILE) -Wp,-MD,.deps/$(*F).p -c $<
|
||||
@-sed -e 's/^\([^:]*\)\.o:/\1.lo \1.o:/' \
|
||||
< .deps/$(*F).p > .deps/$(*F).P
|
||||
@-rm -f .deps/$(*F).p
|
||||
info:
|
||||
dvi:
|
||||
check: all
|
||||
$(MAKE)
|
||||
installcheck:
|
||||
install-exec: install-binPROGRAMS
|
||||
@$(NORMAL_INSTALL)
|
||||
|
||||
install-data:
|
||||
@$(NORMAL_INSTALL)
|
||||
|
||||
install: install-exec install-data all
|
||||
@:
|
||||
|
||||
uninstall: uninstall-binPROGRAMS
|
||||
|
||||
install-strip:
|
||||
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DATADIR)$(bindir)
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(DISTCLEANFILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
mostlyclean: mostlyclean-hdr mostlyclean-binPROGRAMS \
|
||||
mostlyclean-compile mostlyclean-tags mostlyclean-depend \
|
||||
mostlyclean-generic
|
||||
|
||||
clean: clean-hdr clean-binPROGRAMS clean-compile clean-tags \
|
||||
clean-depend clean-generic mostlyclean
|
||||
|
||||
distclean: distclean-hdr distclean-binPROGRAMS distclean-compile \
|
||||
distclean-tags distclean-depend distclean-generic clean
|
||||
-rm -f config.status
|
||||
|
||||
maintainer-clean: maintainer-clean-hdr maintainer-clean-binPROGRAMS \
|
||||
maintainer-clean-compile maintainer-clean-tags \
|
||||
maintainer-clean-depend maintainer-clean-generic \
|
||||
distclean
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-rm -f config.status
|
||||
|
||||
.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
|
||||
mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
|
||||
maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
|
||||
mostlyclean-compile distclean-compile clean-compile \
|
||||
maintainer-clean-compile tags mostlyclean-tags distclean-tags \
|
||||
clean-tags maintainer-clean-tags distdir mostlyclean-depend \
|
||||
distclean-depend clean-depend maintainer-clean-depend info dvi \
|
||||
installcheck install-exec install-data install uninstall all \
|
||||
installdirs mostlyclean-generic distclean-generic clean-generic \
|
||||
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
#undef VERSION
|
||||
#undef PACKAGE
|
||||
#undef CONFIG_SBINDIR
|
||||
#undef CONFIG_MANDIR
|
|
@ -0,0 +1,136 @@
|
|||
dnl aclocal.m4 generated automatically by aclocal 1.3
|
||||
|
||||
dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
dnl This Makefile.in is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl This program is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
dnl PARTICULAR PURPOSE.
|
||||
|
||||
# Do all the work for Automake. 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.
|
||||
|
||||
# serial 1
|
||||
|
||||
dnl Usage:
|
||||
dnl AM_INIT_AUTOMAKE(package,version, [no-define])
|
||||
|
||||
AC_DEFUN(AM_INIT_AUTOMAKE,
|
||||
[AC_REQUIRE([AM_PROG_INSTALL])
|
||||
PACKAGE=[$1]
|
||||
AC_SUBST(PACKAGE)
|
||||
VERSION=[$2]
|
||||
AC_SUBST(VERSION)
|
||||
dnl test to see if srcdir already configured
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
|
||||
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||
fi
|
||||
ifelse([$3],,
|
||||
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$VERSION"))
|
||||
AC_REQUIRE([AM_SANITY_CHECK])
|
||||
AC_REQUIRE([AC_ARG_PROGRAM])
|
||||
dnl FIXME This is truly gross.
|
||||
missing_dir=`cd $ac_aux_dir && pwd`
|
||||
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
|
||||
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
|
||||
AC_REQUIRE([AC_PROG_MAKE_SET])])
|
||||
|
||||
|
||||
# serial 1
|
||||
|
||||
AC_DEFUN(AM_PROG_INSTALL,
|
||||
[AC_REQUIRE([AC_PROG_INSTALL])
|
||||
test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
|
||||
AC_SUBST(INSTALL_SCRIPT)dnl
|
||||
])
|
||||
|
||||
#
|
||||
# Check to make sure that the build environment is sane.
|
||||
#
|
||||
|
||||
AC_DEFUN(AM_SANITY_CHECK,
|
||||
[AC_MSG_CHECKING([whether build environment is sane])
|
||||
# Just in case
|
||||
sleep 1
|
||||
echo timestamp > conftestfile
|
||||
# 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 conftestfile 2> /dev/null`
|
||||
if test "[$]*" = "X"; then
|
||||
# -L didn't work.
|
||||
set X `ls -t $srcdir/configure conftestfile`
|
||||
fi
|
||||
if test "[$]*" != "X $srcdir/configure conftestfile" \
|
||||
&& test "[$]*" != "X conftestfile $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" = conftestfile
|
||||
)
|
||||
then
|
||||
# Ok.
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||
Check your system clock])
|
||||
fi
|
||||
rm -f conftest*
|
||||
AC_MSG_RESULT(yes)])
|
||||
|
||||
dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
|
||||
dnl The program must properly implement --version.
|
||||
AC_DEFUN(AM_MISSING_PROG,
|
||||
[AC_MSG_CHECKING(for working $2)
|
||||
# Run test in a subshell; some versions of sh will print an error if
|
||||
# an executable is not found, even if stderr is redirected.
|
||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||
if ($2 --version) < /dev/null > /dev/null 2>&1; then
|
||||
$1=$2
|
||||
AC_MSG_RESULT(found)
|
||||
else
|
||||
$1="$3/missing $2"
|
||||
AC_MSG_RESULT(missing)
|
||||
fi
|
||||
AC_SUBST($1)])
|
||||
|
||||
# Like AC_CONFIG_HEADER, but automatically create stamp file.
|
||||
|
||||
AC_DEFUN(AM_CONFIG_HEADER,
|
||||
[AC_PREREQ([2.12])
|
||||
AC_CONFIG_HEADER([$1])
|
||||
dnl When config.status generates a header, we must update the stamp-h file.
|
||||
dnl This file resides in the same directory as the config header
|
||||
dnl that is generated. We must strip everything past the first ":",
|
||||
dnl and everything past the last "/".
|
||||
AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
|
||||
ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
|
||||
<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
|
||||
<<am_indx=1
|
||||
for am_file in <<$1>>; do
|
||||
case " <<$>>CONFIG_HEADERS " in
|
||||
*" <<$>>am_file "*<<)>>
|
||||
echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
|
||||
;;
|
||||
esac
|
||||
am_indx=`expr "<<$>>am_indx" + 1`
|
||||
done<<>>dnl>>)
|
||||
changequote([,]))])
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
* Decode_Info: Returns a string with an error description
|
||||
* Note: infos with values of 0x00xx are only warnings and the corresponding
|
||||
* messages have been processed.
|
||||
* The description for all info values but 0x34xx is taken from the CAPI 2.0
|
||||
* specification february 1994.
|
||||
* The description for the 0x34xx values is taken from ETS 300 102-1/Q.931
|
||||
*/
|
||||
char *Decode_Info (unsigned int Info) {
|
||||
switch (Info) {
|
||||
/* informative values (corresponding message was processed) */
|
||||
case 0x0001:
|
||||
return "NCPI not supported by current protocol, NCPI ignored";
|
||||
case 0x0002:
|
||||
return "Flags not supported by current protocol, flags ignored";
|
||||
case 0x0003:
|
||||
return "Alert already sent by another application";
|
||||
/* error information concerning CAPI_REGISTER */
|
||||
case 0x1001:
|
||||
return "Too many applications";
|
||||
case 0x1002:
|
||||
return "Logical block size to small, must be at least 128 Bytes";
|
||||
case 0x1003:
|
||||
return "Buffer exceeds 64 kByte";
|
||||
case 0x1004:
|
||||
return "Message buffer size too small, must be at least 1024 Bytes";
|
||||
case 0x1005:
|
||||
return "Max. number of logical connections not supported";
|
||||
case 0x1006:
|
||||
return "Reserved";
|
||||
case 0x1007:
|
||||
return "The message could not be accepted because of an internal busy condition";
|
||||
case 0x1008:
|
||||
return "OS resource error (no memory ?)";
|
||||
case 0x1009:
|
||||
return "CAPI not installed";
|
||||
case 0x100A:
|
||||
return "Controller does not support external equipment";
|
||||
case 0x100B:
|
||||
return "Controller does only support external equipment";
|
||||
/* error information concerning message exchange functions */
|
||||
case 0x1101:
|
||||
return "Illegal application number";
|
||||
case 0x1102:
|
||||
return "Illegal command or subcommand or message length less than 12 bytes";
|
||||
case 0x1103:
|
||||
return "The message could not be accepted because of a queue full condition !! The error code does not imply that CAPI cannot receive messages directed to another controller, PLCI or NCCI";
|
||||
case 0x1104:
|
||||
return "Queue is empty";
|
||||
case 0x1105:
|
||||
return "Queue overflow, a message was lost !! This indicates a configuration error. The only recovery from this error is to perform a CAPI_RELEASE";
|
||||
case 0x1106:
|
||||
return "Unknown notification parameter";
|
||||
case 0x1107:
|
||||
return "The Message could not be accepted because of an internal busy condition";
|
||||
case 0x1108:
|
||||
return "OS Resource error (no memory ?)";
|
||||
case 0x1109:
|
||||
return "CAPI not installed";
|
||||
case 0x110A:
|
||||
return "Controller does not support external equipment";
|
||||
case 0x110B:
|
||||
return "Controller does only support external equipment";
|
||||
/* error information concerning resource / coding problems */
|
||||
case 0x2001:
|
||||
return "Message not supported in current state";
|
||||
case 0x2002:
|
||||
return "Illegal Controller / PLCI / NCCI";
|
||||
case 0x2003:
|
||||
return "Out of PLCIs";
|
||||
case 0x2004:
|
||||
return "Out of NCCIs";
|
||||
case 0x2005:
|
||||
return "Out of LISTEN requests";
|
||||
case 0x2006:
|
||||
return "Out of FAX resources (protocol T.30)";
|
||||
case 0x2007:
|
||||
return "Illegal message parameter coding";
|
||||
/* error information concerning requested services */
|
||||
case 0x3001:
|
||||
return "B1 protocol not supported";
|
||||
case 0x3002:
|
||||
return "B2 protocol not supported";
|
||||
case 0x3003:
|
||||
return "B3 protocol not supported";
|
||||
case 0x3004:
|
||||
return "B1 protocol parameter not supported";
|
||||
case 0x3005:
|
||||
return "B2 protocol parameter not supported";
|
||||
case 0x3006:
|
||||
return "B3 protocol parameter not supported";
|
||||
case 0x3007:
|
||||
return "B protocol combination not supported";
|
||||
case 0x3008:
|
||||
return "NCPI not supported";
|
||||
case 0x3009:
|
||||
return "CIP Value unknown";
|
||||
case 0x300A:
|
||||
return "Flags not supported (reserved bits)";
|
||||
case 0x300B:
|
||||
return "Facility not supported";
|
||||
case 0x300C:
|
||||
return "Data length not supported by current protocol";
|
||||
case 0x300D:
|
||||
return "Reset procedure not supported by current protocol";
|
||||
/* informations about the clearing of a physical connection */
|
||||
case 0x3301:
|
||||
return "Protocol error layer 1 (broken line or B-channel removed by signalling protocol)";
|
||||
case 0x3302:
|
||||
return "Protocol error layer 2";
|
||||
case 0x3303:
|
||||
return "Protocol error layer 3";
|
||||
case 0x3304:
|
||||
return "Another application got that call";
|
||||
/* T.30 specific reasons */
|
||||
case 0x3311:
|
||||
return "Connecting not successful (remote station is no FAX G3 machine)";
|
||||
case 0x3312:
|
||||
return "Connecting not successful (training error)";
|
||||
case 0x3313:
|
||||
return "Disconnected before transfer (remote station does not support transfer mode, e.g. resolution)";
|
||||
case 0x3314:
|
||||
return "Disconnected during transfer (remote abort)";
|
||||
case 0x3315:
|
||||
return "Disconnected during transfer (remote procedure error, e.g. unsuccessful repetition of T.30 commands)";
|
||||
case 0x3316:
|
||||
return "Disconnected during transfer (local tx data underrun)";
|
||||
case 0x3317:
|
||||
return "Disconnected during transfer (local rx data overflow)";
|
||||
case 0x3318:
|
||||
return "Disconnected during transfer (local abort)";
|
||||
case 0x3319:
|
||||
return "Illegal parameter coding (e.g. SFF coding error)";
|
||||
/* disconnect causes from the network according to ETS 300 102-1/Q.931 */
|
||||
case 0x3481:
|
||||
return "Unallocated (unassigned) number";
|
||||
case 0x3482:
|
||||
return "No route to specified transit network";
|
||||
case 0x3483:
|
||||
return "No route to destination";
|
||||
case 0x3486:
|
||||
return "Channel unacceptable";
|
||||
case 0x3487:
|
||||
return "Call awarded and being delivered in an established channel";
|
||||
case 0x3490:
|
||||
return "Normal call clearing";
|
||||
case 0x3491:
|
||||
return "User busy";
|
||||
case 0x3492:
|
||||
return "No user responding";
|
||||
case 0x3493:
|
||||
return "No answer from user (user alerted)";
|
||||
case 0x3495:
|
||||
return "Call rejected";
|
||||
case 0x3496:
|
||||
return "Number changed";
|
||||
case 0x349A:
|
||||
return "Non-selected user clearing";
|
||||
case 0x349B:
|
||||
return "Destination out of order";
|
||||
case 0x349C:
|
||||
return "Invalid number format";
|
||||
case 0x349D:
|
||||
return "Facility rejected";
|
||||
case 0x349E:
|
||||
return "Response to STATUS ENQUIRY";
|
||||
case 0x349F:
|
||||
return "Normal, unspecified";
|
||||
case 0x34A2:
|
||||
return "No circuit / channel available";
|
||||
case 0x34A6:
|
||||
return "Network out of order";
|
||||
case 0x34A9:
|
||||
return "Temporary failure";
|
||||
case 0x34AA:
|
||||
return "Switching equipment congestion";
|
||||
case 0x34AB:
|
||||
return "Access information discarded";
|
||||
case 0x34AC:
|
||||
return "Requested circuit / channel not available";
|
||||
case 0x34AF:
|
||||
return "Resources unavailable, unspecified";
|
||||
case 0x34B1:
|
||||
return "Quality of service unavailable";
|
||||
case 0x34B2:
|
||||
return "Requested facility not subscribed";
|
||||
case 0x34B9:
|
||||
return "Bearer capability not authorized";
|
||||
case 0x34BA:
|
||||
return "Bearer capability not presently available";
|
||||
case 0x34BF:
|
||||
return "Service or option not available, unspecified";
|
||||
case 0x34C1:
|
||||
return "Bearer capability not implemented";
|
||||
case 0x34C2:
|
||||
return "Channel type not implemented";
|
||||
case 0x34C5:
|
||||
return "Requested facility not implemented";
|
||||
case 0x34C6:
|
||||
return "Only restricted digital information bearer capability is available";
|
||||
case 0x34CF:
|
||||
return "Service or option not implemented, unspecified";
|
||||
case 0x34D1:
|
||||
return "Invalid call reference value";
|
||||
case 0x34D2:
|
||||
return "Identified channel does not exist";
|
||||
case 0x34D3:
|
||||
return "A suspended call exists, but this call identity does not";
|
||||
case 0x34D4:
|
||||
return "Call identity in use";
|
||||
case 0x34D5:
|
||||
return "No call suspended";
|
||||
case 0x34D6:
|
||||
return "Call having the requested call identity has been cleared";
|
||||
case 0x34D8:
|
||||
return "Incompatible destination";
|
||||
case 0x34DB:
|
||||
return "Invalid transit network selection";
|
||||
case 0x34DF:
|
||||
return "Invalid message, unspecified";
|
||||
case 0x34E0:
|
||||
return "Mandatory information element is missing";
|
||||
case 0x34E1:
|
||||
return "Message type non-existent or not implemented";
|
||||
case 0x34E2:
|
||||
return "Message not compatible with call state or message type non-existent or not implemented";
|
||||
case 0x34E3:
|
||||
return "Information element non-existent or not implemented";
|
||||
case 0x34E4:
|
||||
return "Invalid information element contents";
|
||||
case 0x34E5:
|
||||
return "Message not compatible with call state";
|
||||
case 0x34E6:
|
||||
return "Recovery on timer expiry";
|
||||
case 0x34EF:
|
||||
return "Protocol error, unspecified";
|
||||
case 0x34FF:
|
||||
return "Interworking, unspecified";
|
||||
default:
|
||||
return "No additional information";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode_Command: Returns a textstring with the CAPI-commandname
|
||||
*/
|
||||
char *Decode_Command (unsigned char Command) {
|
||||
switch (Command) {
|
||||
case 0x01:
|
||||
return "ALERT";
|
||||
case 0x02:
|
||||
return "CONNECT";
|
||||
case 0x03:
|
||||
return "CONNECT_ACTIVE";
|
||||
case 0x04:
|
||||
return "DISCONNECT";
|
||||
case 0x05:
|
||||
return "LISTEN";
|
||||
case 0x08:
|
||||
return "INFO";
|
||||
case 0x41:
|
||||
return "SELECT_B_PROTOCOL";
|
||||
case 0x80:
|
||||
return "FACILITY";
|
||||
case 0x82:
|
||||
return "CONNECT_B3";
|
||||
case 0x83:
|
||||
return "CONNECT_B3_ACTIVE";
|
||||
case 0x84:
|
||||
return "DISCONNECT_B3";
|
||||
case 0x86:
|
||||
return "DATA_B3";
|
||||
case 0x87:
|
||||
return "RESET_B3";
|
||||
case 0x88:
|
||||
return "CONNECT_B3_T90_ACTIVE";
|
||||
case 0xff:
|
||||
return "MANUFACTURER";
|
||||
}
|
||||
return "Error: Command undefined in function Decode_Command";
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode_Sub: Returns a textstring with the CAPI-subcommandname
|
||||
*/
|
||||
char *Decode_Sub (unsigned char Sub) {
|
||||
switch (Sub) {
|
||||
case 0x80:
|
||||
/* Request */
|
||||
return "REQ";
|
||||
case 0x81:
|
||||
/* Confirmation */
|
||||
return "CONF";
|
||||
case 0x82:
|
||||
/* Indication */
|
||||
return "IND";
|
||||
case 0x83:
|
||||
/* Response */
|
||||
return "RESP";
|
||||
}
|
||||
return "Error: Subcommand undefined in function Decode_Sub";
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef _c20msg_h_
|
||||
#define _c20msg_h_
|
||||
|
||||
/*
|
||||
* Decode_Info: Returns a string with an error description
|
||||
* Note: infos with values of 0x00xx are only warnings and the corresponding
|
||||
* messages have been processed.
|
||||
* The description for all info values but 0x34xx is taken from the CAPI 2.0
|
||||
* specification february 1994.
|
||||
* The description for the 0x34xx values is taken from ETS 300 102-1/Q.931
|
||||
*/
|
||||
char *Decode_Info(unsigned int Info);
|
||||
|
||||
/*
|
||||
* Decode_Command: Returns a textstring with the CAPI-commandname
|
||||
*/
|
||||
char *Decode_Command(unsigned char Command);
|
||||
|
||||
/*
|
||||
* Decode_Sub: Returns a textstring with the CAPI-subcommandname
|
||||
*/
|
||||
char *Decode_Sub (unsigned char Sub);
|
||||
|
||||
#endif /* _c20msg_h_ */
|
|
@ -0,0 +1,263 @@
|
|||
/*
|
||||
* Implementation of CAPI state machine
|
||||
*
|
||||
* Based heavily on
|
||||
* CAPI.C Version 1.1 by AVM
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <linux/capi.h>
|
||||
#include <capi20.h>
|
||||
|
||||
#include "connect.h"
|
||||
#include "data.h"
|
||||
#include "init.h"
|
||||
#include "capi.h"
|
||||
#include "id.h"
|
||||
|
||||
#define zNCPI (_cstruct)NULL
|
||||
|
||||
static _cmsg CMESSAGE;
|
||||
static _cmsg *CMSG = &CMESSAGE; /* used in all requests and responses */
|
||||
|
||||
/*
|
||||
* SetState: Set the state internal and informs the user
|
||||
*/
|
||||
static void ChangeState (ConnectionID Con, ConnectionState State) {
|
||||
SetState (Con, State);
|
||||
/* signal the status change to the user */
|
||||
StateChange (Con, State);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle_Indication: CAPI logic for all indications
|
||||
*/
|
||||
void Handle_Indication(void) {
|
||||
ConnectionID Connection;
|
||||
|
||||
switch (CMSG->Command) {
|
||||
case CAPI_CONNECT:
|
||||
Connection = GetConnectionByPLCI (CONNECT_IND_PLCI(CMSG));
|
||||
if (Connection == INVALID_CONNECTION_ID) {
|
||||
/* incoming call */
|
||||
Connection = AllocConnection();
|
||||
if (Connection == INVALID_CONNECTION_ID) {
|
||||
/* error no internal resources, reject call */
|
||||
CONNECT_RESP(CMSG, Appl_Id, CMSG->Messagenumber,
|
||||
CONNECT_IND_PLCI(CMSG), REJECT,
|
||||
0, 0, 0, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
SetConnectionPLCI(Connection, CONNECT_IND_PLCI(CMSG));
|
||||
}
|
||||
SetCallingPartyNumberStruct (Connection, CONNECT_IND_CALLINGPARTYNUMBER(CMSG));
|
||||
SetCalledPartyNumberStruct (Connection, CONNECT_IND_CALLEDPARTYNUMBER(CMSG));
|
||||
/* The ALERT_REQuest tells the caller that someone is listening
|
||||
* for incoming calls on the line. A new timeout of 2 minutes is set
|
||||
* Without the ALERT_REQuest a disconnect would be sent after
|
||||
* 4 seconds with the cause "no user responding" on the caller side
|
||||
* (Assumed that no CONNECT_RESPonse is sent in this time)
|
||||
* of the application
|
||||
*/
|
||||
ALERT_REQ (CMSG, Appl_Id, 0, CONNECT_IND_PLCI(CMSG),
|
||||
NULL, NULL, NULL, NULL);
|
||||
/* inform the user application */
|
||||
SetState(Connection, D_ConnectPending);
|
||||
IncomingCall(Connection, GetCallingPartyNumber (Connection));
|
||||
ChangeState(Connection, D_ConnectPending);
|
||||
/* signal incoming call to the user */
|
||||
return;
|
||||
case CAPI_CONNECT_ACTIVE:
|
||||
Connection = GetConnectionByPLCI (CONNECT_ACTIVE_IND_PLCI(CMSG));
|
||||
CONNECT_ACTIVE_RESP(CMSG, Appl_Id, CMSG->Messagenumber, CONNECT_ACTIVE_IND_PLCI(CMSG));
|
||||
ChangeState(Connection, D_Connected);
|
||||
if (GetConnectionInitiator (Connection))
|
||||
CONNECT_B3_REQ(CMSG, Appl_Id, 0, CONNECT_ACTIVE_IND_PLCI(CMSG), zNCPI);
|
||||
return;
|
||||
case CAPI_CONNECT_B3:
|
||||
Connection = GetConnectionByPLCI(CONNECT_B3_IND_NCCI(CMSG) & 0x0000FFFF);
|
||||
SetConnectionNCCI(Connection, CONNECT_B3_IND_NCCI(CMSG));
|
||||
CONNECT_B3_RESP(CMSG, Appl_Id, CMSG->Messagenumber, CONNECT_B3_IND_NCCI(CMSG), 0, zNCPI);
|
||||
ChangeState(Connection, B_ConnectPending);
|
||||
return;
|
||||
case CAPI_CONNECT_B3_ACTIVE:
|
||||
Connection = GetConnectionByNCCI(CONNECT_B3_ACTIVE_IND_NCCI(CMSG));
|
||||
SetConnectionInitiator(Connection, FALSE);
|
||||
CONNECT_B3_ACTIVE_RESP(CMSG, Appl_Id, CMSG->Messagenumber, CONNECT_B3_ACTIVE_IND_NCCI(CMSG));
|
||||
ChangeState(Connection, Connected);
|
||||
return;
|
||||
case CAPI_DISCONNECT_B3:
|
||||
Connection = GetConnectionByNCCI(DISCONNECT_B3_IND_NCCI(CMSG));
|
||||
SetFaxNCPI(Connection, (faxNCPI_t *)DISCONNECT_B3_IND_NCPI(CMSG));
|
||||
SetB3Reason(Connection, DISCONNECT_B3_IND_REASON_B3(CMSG));
|
||||
SetConnectionNCCI (Connection, INVAL_NCCI);
|
||||
DISCONNECT_B3_RESP(CMSG, Appl_Id, CMSG->Messagenumber, DISCONNECT_B3_IND_NCCI(CMSG));
|
||||
ChangeState(Connection, D_Connected);
|
||||
if (GetConnectionInitiator(Connection))
|
||||
DISCONNECT_REQ(CMSG, Appl_Id, 0, GetConnectionPLCI(Connection), NULL, NULL, NULL, NULL);
|
||||
return;
|
||||
case CAPI_DISCONNECT:
|
||||
Connection = GetConnectionByPLCI(DISCONNECT_IND_PLCI(CMSG));
|
||||
SetReason(Connection, DISCONNECT_IND_REASON(CMSG));
|
||||
DISCONNECT_RESP(CMSG, Appl_Id, CMSG->Messagenumber, DISCONNECT_IND_PLCI(CMSG));
|
||||
if (Connection != INVALID_CONNECTION_ID) {
|
||||
ChangeState(Connection, Disconnected);
|
||||
FreeConnection(Connection);
|
||||
}
|
||||
return;
|
||||
case CAPI_DATA_B3:
|
||||
Connection = GetConnectionByNCCI(DATA_B3_IND_NCCI(CMSG));
|
||||
if (CMSG->DataLength > 0) {
|
||||
int DiscardData = TRUE;
|
||||
|
||||
DataAvailable(Connection,
|
||||
(void *)DATA_B3_IND_DATA(CMSG),
|
||||
DATA_B3_IND_DATALENGTH(CMSG),
|
||||
DATA_B3_IND_DATAHANDLE(CMSG),
|
||||
&DiscardData);
|
||||
if (DiscardData)
|
||||
/* let CAPI free the data area immediately */
|
||||
DATA_B3_RESP(CMSG, Appl_Id, CMSG->Messagenumber,
|
||||
DATA_B3_IND_NCCI(CMSG), DATA_B3_IND_DATAHANDLE(CMSG));
|
||||
}
|
||||
return;
|
||||
case CAPI_INFO:
|
||||
INFO_RESP(CMSG, Appl_Id, CMSG->Messagenumber, INFO_IND_PLCI(CMSG));
|
||||
return;
|
||||
default:
|
||||
fprintf(stderr, "Handle_Indication: Unsupported Indication 0x%02x.\n", CMSG->Command);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle_Confirmation: CAPI logic for all confirmations
|
||||
*/
|
||||
static void Handle_Confirmation(void) {
|
||||
ConnectionID Connection;
|
||||
|
||||
if (CMSG->Info > 0x00FF) {
|
||||
/* Info's with value 0x00xx are only
|
||||
* warnings, the corresponding requests
|
||||
* have been processed
|
||||
*/
|
||||
fprintf(stderr, "Handle_Confirmation: Info value 0x%x indicates error.\n", CMSG->Info);
|
||||
switch (CMSG->Command) {
|
||||
case CAPI_CONNECT:
|
||||
Connection = CMSG->Messagenumber;
|
||||
ChangeState (Connection, D_ConnectPending);
|
||||
ChangeState (Connection, Disconnected);
|
||||
FreeConnection(Connection);
|
||||
break;
|
||||
case CAPI_DATA_B3:
|
||||
/* return the error value */
|
||||
Connection = GetConnectionByNCCI(DATA_B3_CONF_NCCI(CMSG));
|
||||
DataConf(Connection, DATA_B3_CONF_DATAHANDLE(CMSG),
|
||||
DATA_B3_CONF_INFO(CMSG));
|
||||
break;
|
||||
case CAPI_CONNECT_B3:
|
||||
/* disconnect line */
|
||||
Connection = GetConnectionByPLCI(CONNECT_B3_CONF_NCCI(CMSG) & 0x0000FFFF);
|
||||
if (Connection == INVALID_CONNECTION_ID)
|
||||
fprintf(stderr, "Handle_Confirmation: invalid PLCI in CONNECT_B3_CONF.\n");
|
||||
else
|
||||
DISCONNECT_REQ(CMSG, Appl_Id, 0, GetConnectionPLCI(Connection),
|
||||
NULL, NULL, NULL, NULL);
|
||||
break;
|
||||
case CAPI_DISCONNECT:
|
||||
Connection = GetConnectionByPLCI(DISCONNECT_CONF_PLCI(CMSG));
|
||||
if (Connection == INVALID_CONNECTION_ID)
|
||||
fprintf(stderr, "Handle_Confirmation: invalid PLCI in DISCONNECT_CONF.\n");
|
||||
break;
|
||||
case CAPI_DISCONNECT_B3:
|
||||
Connection = GetConnectionByNCCI(DISCONNECT_B3_CONF_NCCI(CMSG));
|
||||
if (Connection == INVALID_CONNECTION_ID)
|
||||
fprintf(stderr, "Handle_Confirmation: invalid NCCI in DISCONNECT_B3_CONF.\n");
|
||||
break;
|
||||
case CAPI_LISTEN:
|
||||
fprintf(stderr, "Handle_Confirmation: Info != 0 in LISTEN_CONF.\n");
|
||||
break;
|
||||
case CAPI_INFO:
|
||||
fprintf(stderr, "Handle_Confirmation: Info != 0 in INFO_CONF.\n");
|
||||
break;
|
||||
case CAPI_ALERT:
|
||||
fprintf(stderr, "Handle_Confirmation: Info != 0 in ALERT_CONF.\n");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* no error */
|
||||
switch (CMSG->Command) {
|
||||
case CAPI_CONNECT:
|
||||
Connection = CMSG->Messagenumber;
|
||||
SetConnectionPLCI(Connection, CONNECT_CONF_PLCI(CMSG));
|
||||
SetConnectionInitiator(Connection, TRUE);
|
||||
ChangeState(Connection, D_ConnectPending);
|
||||
return;
|
||||
case CAPI_CONNECT_B3:
|
||||
Connection = GetConnectionByPLCI(CONNECT_B3_CONF_NCCI(CMSG) & 0x0000FFFF);
|
||||
SetConnectionNCCI(Connection, CONNECT_B3_CONF_NCCI(CMSG));
|
||||
ChangeState(Connection, B_ConnectPending);
|
||||
return;
|
||||
case CAPI_DISCONNECT:
|
||||
Connection = GetConnectionByPLCI(DISCONNECT_CONF_PLCI(CMSG));
|
||||
if (Connection != INVALID_CONNECTION_ID)
|
||||
ChangeState(Connection, D_DisconnectPending);
|
||||
return;
|
||||
case CAPI_DISCONNECT_B3:
|
||||
Connection = GetConnectionByNCCI(DISCONNECT_B3_CONF_NCCI(CMSG));
|
||||
SetConnectionInitiator(Connection, TRUE);
|
||||
ChangeState(Connection, B_DisconnectPending);
|
||||
return;
|
||||
case CAPI_DATA_B3:
|
||||
Connection = GetConnectionByNCCI(DATA_B3_CONF_NCCI(CMSG));
|
||||
DataConf(Connection, DATA_B3_CONF_DATAHANDLE(CMSG),
|
||||
DATA_B3_CONF_INFO(CMSG));
|
||||
return;
|
||||
case CAPI_LISTEN:
|
||||
case CAPI_INFO:
|
||||
case CAPI_ALERT:
|
||||
return;
|
||||
default:
|
||||
fprintf(stderr, "Handle_Confirmation: Invalid Command 0x%02x.\n", CMSG->Command);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle_CAPI_Msg: the main routine, checks for messages and handles them
|
||||
*/
|
||||
void Handle_CAPI_Msg(void) {
|
||||
MESSAGE_EXCHANGE_ERROR Info;
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
CAPI20_WaitforMessage(Appl_Id, &tv); /* This does a select() */
|
||||
switch (Info = CAPI_GET_CMSG(CMSG, Appl_Id)) {
|
||||
case 0x0000:
|
||||
/* a message has been read */
|
||||
switch (CMSG->Subcommand) {
|
||||
case CAPI_CONF:
|
||||
Handle_Confirmation();
|
||||
break;
|
||||
case CAPI_IND:
|
||||
Handle_Indication();
|
||||
break;
|
||||
default:
|
||||
/* neither indication nor confirmation ???? */
|
||||
fprintf(stderr, "Handle_CAPI_Msg: Unknown subcommand 0x%02x.\n", CMSG->Subcommand);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x1104:
|
||||
/* messagequeue is empty */
|
||||
return;
|
||||
default:
|
||||
fprintf(stderr, "Handle_CAPI_Msg: CAPI_GET_CMSG returns Info != 0.\n");
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _capi_h_
|
||||
#define _capi_h_
|
||||
|
||||
extern void Handle_CAPI_Msg(void);
|
||||
|
||||
#endif /* _capi_h_ */
|
|
@ -0,0 +1,292 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/capi.h>
|
||||
#include <capi20.h>
|
||||
|
||||
#include "c20msg.h"
|
||||
#include "capi.h"
|
||||
#include "connect.h"
|
||||
#include "contr.h"
|
||||
#include "data.h"
|
||||
#include "id.h"
|
||||
#include "init.h"
|
||||
#include "fax.h"
|
||||
|
||||
extern char *stationID;
|
||||
extern char *headLine;
|
||||
|
||||
static char *CallingPartyNumber = NULL;
|
||||
static char *CalledPartyNumber = NULL;
|
||||
|
||||
static ConnectionID Slot;
|
||||
|
||||
#define B1PROTOCOL 4
|
||||
#define B2PROTOCOL 4
|
||||
#define B3PROTOCOL 4
|
||||
|
||||
#define QueueSize 8
|
||||
|
||||
typedef struct __DataElement {
|
||||
char DATA[SendBlockSize];
|
||||
unsigned short DATA_LENGTH;
|
||||
unsigned SENT;
|
||||
} _DataElement;
|
||||
|
||||
typedef struct __DataQueue {
|
||||
_DataElement Element[QueueSize];
|
||||
unsigned Head;
|
||||
unsigned Tail;
|
||||
unsigned Fill;
|
||||
} _DataQueue;
|
||||
|
||||
_DataQueue Queue;
|
||||
|
||||
static unsigned FileTransfer = FALSE; /* signals if transfer is in progress */
|
||||
static int verbose;
|
||||
static int reason;
|
||||
static int reason_b3;
|
||||
|
||||
/*--------------------------------------------------------------------------*\
|
||||
* MainDataConf: signals the successful sending of a datablock
|
||||
* This function is called after receiving a DATA_B3_CONFirmation. CAPI signals
|
||||
* that the datablock identified by DataHandle has been sent and the memory
|
||||
* area may be freed. The DataHandle is the same as specified in SendBlock.
|
||||
\*--------------------------------------------------------------------------*/
|
||||
void MainDataConf(ConnectionID Connection,
|
||||
unsigned short DataHandle,
|
||||
unsigned short Info) {
|
||||
|
||||
assert (Connection != INVALID_CONNECTION_ID);
|
||||
if (Info != 0)
|
||||
return;
|
||||
if (FileTransfer) {
|
||||
assert (DataHandle == (unsigned short)Queue.Tail);
|
||||
Queue.Element[Queue.Tail].SENT = FALSE;
|
||||
if (++Queue.Tail >= QueueSize)
|
||||
Queue.Tail = 0;
|
||||
Queue.Fill--;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*\
|
||||
* MainStateChange: signals a state change on both B-channels (connected,
|
||||
* disconnected). Whenever a channel changes his state this function is called
|
||||
\*--------------------------------------------------------------------------*/
|
||||
void MainStateChange(ConnectionID Connection, ConnectionState State) {
|
||||
faxNCPI_t *faxNCPI;
|
||||
|
||||
assert (Connection != INVALID_CONNECTION_ID);
|
||||
if (State == Disconnected) {
|
||||
unsigned short r3 = GetB3Reason(Connection);
|
||||
unsigned short r = GetReason(Connection);
|
||||
|
||||
Slot = INVALID_CONNECTION_ID;
|
||||
reason_b3 = r3;
|
||||
reason = r;
|
||||
if (!verbose)
|
||||
return;
|
||||
printf("Disconnected.\n");
|
||||
printf(" Reason : %04x %s\n", r, Decode_Info(r));
|
||||
printf(" Reason-B3 : %04x %s\n", r3, Decode_Info(r3));
|
||||
if ((faxNCPI = GetFaxNCPI(Connection))) {
|
||||
printf(" Remote Station ID : %s\n", faxNCPI->id);
|
||||
printf(" Transfer-Rate : %d bps\n", faxNCPI->rate);
|
||||
printf(" Resolution : %s\n", faxNCPI->resolution ? "high" : "low");
|
||||
printf(" Number of Pages : %d\n", faxNCPI->pages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*\
|
||||
* Disconnect_h: high level Disconnect
|
||||
\*--------------------------------------------------------------------------*/
|
||||
unsigned Disconnect_h(ConnectionID Connection) {
|
||||
|
||||
ConnectionState State;
|
||||
|
||||
if (Connection == INVALID_CONNECTION_ID) {
|
||||
fprintf(stderr, "Disconnect_h: ConnectionID is invalid\n");
|
||||
return 0xFFFF;
|
||||
}
|
||||
State = GetState(Connection);
|
||||
if ((State == Disconnected) || (State == D_DisconnectPending))
|
||||
return 0xFFFF;
|
||||
return Disconnect(Connection);
|
||||
}
|
||||
|
||||
void InitQueue(void) {
|
||||
unsigned x;
|
||||
|
||||
for (x=0; x<QueueSize; x++)
|
||||
Queue.Element[x].SENT = FALSE;
|
||||
Queue.Head = 0;
|
||||
Queue.Tail = 0;
|
||||
Queue.Fill = 0;
|
||||
}
|
||||
|
||||
void TransferData() {
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
unsigned t;
|
||||
|
||||
if (Queue.Fill > 0) {
|
||||
t = Queue.Tail;
|
||||
do {
|
||||
if (Queue.Element[t].SENT == FALSE) {
|
||||
error = SendData(0,
|
||||
(void *)Queue.Element[t].DATA,
|
||||
Queue.Element[t].DATA_LENGTH,
|
||||
(unsigned short)t);
|
||||
|
||||
if (error != 0) {
|
||||
fprintf(stderr, "Error during transfer: 0x%04X !!!\n",error);
|
||||
break;
|
||||
}
|
||||
Queue.Element[t].SENT = TRUE;
|
||||
}
|
||||
if (++t >= QueueSize)
|
||||
t = 0;
|
||||
} while (t != Queue.Head);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned SendFax(char *name) {
|
||||
int first;
|
||||
char mbuf[4];
|
||||
unsigned count;
|
||||
B3_PROTO_FAXG3 B3conf;
|
||||
FILE *f;
|
||||
|
||||
first = 1;
|
||||
reason = reason_b3 = 0;
|
||||
if (!strcmp(name, "-"))
|
||||
f = stdin;
|
||||
else
|
||||
f = fopen(name, "rb");
|
||||
if (!f) {
|
||||
perror(name);
|
||||
exit(errno);
|
||||
}
|
||||
fread(mbuf, 4, 1, f);
|
||||
|
||||
InitQueue();
|
||||
SetupB3Config(&B3conf,
|
||||
(strncmp(mbuf, "Sfff", 4)) ? FAX_ASCII_FORMAT:FAX_SFF_FORMAT);
|
||||
if (Slot != INVALID_CONNECTION_ID) {
|
||||
fprintf(stderr, "Connection is already in use\n");
|
||||
fclose(f);
|
||||
return 0xFFFF;
|
||||
}
|
||||
Connect(&Slot, CalledPartyNumber, CallingPartyNumber, SPEECH,
|
||||
B1PROTOCOL, B2PROTOCOL, B3PROTOCOL, (unsigned char *)&B3conf);
|
||||
do {
|
||||
Handle_CAPI_Msg();
|
||||
if (Slot == INVALID_CONNECTION_ID) {
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
} while (GetState(Slot) != Connected);
|
||||
FileTransfer = TRUE;
|
||||
while (!feof(f)) {
|
||||
if (Queue.Fill < 7) {
|
||||
/* max. 7 outstanding blocks supported by CAPI */
|
||||
if (first) {
|
||||
memcpy(&(Queue.Element[Queue.Head].DATA[0]), mbuf, 4);
|
||||
count = fread(&(Queue.Element[Queue.Head].DATA[4]), 1,
|
||||
SendBlockSize - 4, f);
|
||||
} else
|
||||
count = fread(&(Queue.Element[Queue.Head].DATA[0]), 1,
|
||||
SendBlockSize, f);
|
||||
if (count > 0) {
|
||||
if (first)
|
||||
count += 4;
|
||||
Queue.Element[Queue.Head].DATA_LENGTH = (unsigned short)count;
|
||||
if (++Queue.Head >= QueueSize)
|
||||
Queue.Head = 0;
|
||||
Queue.Fill++;
|
||||
}
|
||||
first = 0;
|
||||
}
|
||||
if (GetState(Slot) != Connected)
|
||||
break;
|
||||
TransferData();
|
||||
Handle_CAPI_Msg();
|
||||
}
|
||||
Disconnect_h(Slot);
|
||||
while ((Slot != INVALID_CONNECTION_ID) &&
|
||||
(GetState(Slot) != Disconnected))
|
||||
Handle_CAPI_Msg();
|
||||
FileTransfer = FALSE;
|
||||
fclose(f);
|
||||
switch (reason) {
|
||||
case 0x3490: /* Normal call clearing */
|
||||
case 0x349f: /* Normal, unspecified */
|
||||
return reason_b3;
|
||||
default:
|
||||
return reason;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usage(void) {
|
||||
fprintf(stderr, "usage: capifax [-v] [-i stationID] [-h header] [-c callerNumber] phone file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int numController;
|
||||
int BChannels, Contr;
|
||||
int c;
|
||||
int ret;
|
||||
|
||||
verbose = 0;
|
||||
while ((c = getopt(argc, argv, "vc:i:h:")) != EOF) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'c':
|
||||
CallingPartyNumber = strdup(optarg);
|
||||
break;
|
||||
case 'i':
|
||||
stationID = strdup(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
headLine = strdup(optarg);
|
||||
break;
|
||||
case '?':
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if (argc < optind + 2)
|
||||
usage();
|
||||
CalledPartyNumber = argv[optind++];
|
||||
Slot = INVALID_CONNECTION_ID;
|
||||
MainDataConf_p = MainDataConf;
|
||||
MainStateChange_p = MainStateChange;
|
||||
if (!RegisterCAPI())
|
||||
return -1;
|
||||
atexit (ReleaseCAPI);
|
||||
InitConnectionIDHandling();
|
||||
if (!(numController = GetNumController())) {
|
||||
fprintf(stderr, "No CAPI controllers available\n");
|
||||
return -2;
|
||||
}
|
||||
BChannels = 0;
|
||||
for (Contr=1; Contr<=numController; Contr++)
|
||||
BChannels += GetNumOfSupportedBChannels(Contr);
|
||||
if (!BChannels) {
|
||||
fprintf(stderr, "No B-Channels available\n");
|
||||
return -3;
|
||||
}
|
||||
ret = SendFax(argv[optind]);
|
||||
if ((Slot != INVALID_CONNECTION_ID) &&
|
||||
(GetState(Slot) != Disconnected) &&
|
||||
(GetState(Slot) != D_DisconnectPending))
|
||||
Disconnect(Slot);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,306 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/capi.h>
|
||||
#include <capi20.h>
|
||||
|
||||
#include "c20msg.h"
|
||||
#include "capi.h"
|
||||
#include "connect.h"
|
||||
#include "contr.h"
|
||||
#include "data.h"
|
||||
#include "id.h"
|
||||
#include "init.h"
|
||||
#include "fax.h"
|
||||
|
||||
extern char *stationID;
|
||||
extern char *headLine;
|
||||
|
||||
static char *CalledPartyNumber = NULL;
|
||||
static char *RcvDir = NULL;
|
||||
static char *notifyCmd = NULL;
|
||||
static char RcvName[1024];
|
||||
|
||||
static ConnectionID Slot;
|
||||
|
||||
#define B1PROTOCOL 4
|
||||
#define B2PROTOCOL 4
|
||||
#define B3PROTOCOL 4
|
||||
|
||||
#define QueueSize 8
|
||||
|
||||
typedef struct __DataElement {
|
||||
char DATA[SendBlockSize];
|
||||
unsigned short DATA_LENGTH;
|
||||
unsigned SENT;
|
||||
} _DataElement;
|
||||
|
||||
typedef struct __DataQueue {
|
||||
_DataElement Element[QueueSize];
|
||||
unsigned Head;
|
||||
unsigned Tail;
|
||||
unsigned Fill;
|
||||
} _DataQueue;
|
||||
|
||||
_DataQueue Queue;
|
||||
|
||||
static unsigned FileReceive = FALSE; /* signals if transfer is in progress */
|
||||
static FILE *f;
|
||||
static int reason;
|
||||
static int reason_b3;
|
||||
static int rres;
|
||||
static int rpages;
|
||||
static char rid[50];
|
||||
|
||||
/*
|
||||
* MainDataAvailable: signals received data blocks
|
||||
* This function is called after a DATA_B3_INDication is received. The flag
|
||||
* DiscardData tells CAPI to free the memora area directly after the return
|
||||
* of this function when set to TRUE (1) which is the preset. When the flag
|
||||
* is set to FALSE (0) the data area MUST be freed later with ReleaseData.
|
||||
* The datahandle identifies the memory area. When reaching 7 unconfirmed
|
||||
* blocks, no more incoming data will be signaled until freeing at least
|
||||
* one block.
|
||||
*/
|
||||
static void MainDataAvailable(ConnectionID Connection, void *Data, unsigned short DataLength,
|
||||
unsigned short DataHandle, int *DiscardData) {
|
||||
assert (Connection != INVALID_CONNECTION_ID);
|
||||
if ((FileReceive) && (f != NULL))
|
||||
fwrite(Data, 1, DataLength, f);
|
||||
*DiscardData = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* MainStateChange: signals a state change on both B-channels (connected,
|
||||
* disconnected). Whenever a channel changes his state this function is called
|
||||
*/
|
||||
static void MainStateChange(ConnectionID Connection, ConnectionState State) {
|
||||
faxNCPI_t *faxNCPI;
|
||||
|
||||
assert (Connection != INVALID_CONNECTION_ID);
|
||||
if (State == Disconnected) {
|
||||
unsigned short r3 = GetB3Reason(Connection);
|
||||
unsigned short r = GetReason(Connection);
|
||||
|
||||
Slot = INVALID_CONNECTION_ID;
|
||||
reason = r;
|
||||
reason_b3 = r3;
|
||||
#if 0
|
||||
printf("Disconnected.\n");
|
||||
printf(" Reason : %04x %s\n", r, Decode_Info(r));
|
||||
printf(" Reason-B3 : %04x %s\n", r3, Decode_Info(r3));
|
||||
#endif
|
||||
if ((faxNCPI = GetFaxNCPI(Connection))) {
|
||||
strcpy(rid, faxNCPI->id);
|
||||
rres = faxNCPI->resolution;
|
||||
rpages = faxNCPI->pages;
|
||||
|
||||
#if 0
|
||||
printf(" Remote Station ID : %s\n", faxNCPI->id);
|
||||
printf(" Transfer-Rate : %d bps\n", faxNCPI->rate);
|
||||
printf(" Resolution : %s\n", faxNCPI->resolution ? "high" : "low");
|
||||
printf(" Number of Pages : %d\n", faxNCPI->pages);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* MainIncomingCall: signals an incoming call
|
||||
* This function will be executed if a CONNECT_INDication appears to
|
||||
* inform the user.
|
||||
*/
|
||||
static void MainIncomingCall(ConnectionID Connection, char *CallingPartyNumber) {
|
||||
B3_PROTO_FAXG3 B3conf;
|
||||
|
||||
assert (Connection != INVALID_CONNECTION_ID);
|
||||
syslog(LOG_INFO, "Incoming Call from %s\n", CallingPartyNumber);
|
||||
SetupB3Config(&B3conf, FAX_SFF_FORMAT);
|
||||
if (CalledPartyNumber && strlen(CalledPartyNumber)) {
|
||||
syslog(LOG_INFO, "Called #: %s\n", GetCalledPartyNumber(Connection));
|
||||
if (strcmp(GetCalledPartyNumber(Connection), CalledPartyNumber)) {
|
||||
AnswerCall(Connection, IGNORE, 4, 4, 4, (_cstruct)&B3conf);
|
||||
syslog(LOG_INFO, "Call from %s ignored\n", CallingPartyNumber);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Slot == INVALID_CONNECTION_ID) {
|
||||
Slot = Connection;
|
||||
sprintf(RcvName, "rc-%s-%08lx", CallingPartyNumber, time(NULL));
|
||||
f = fopen(RcvName, "wb");
|
||||
if (f != NULL) {
|
||||
FileReceive = TRUE;
|
||||
syslog(LOG_INFO, "Call from %s accepted\n", CallingPartyNumber);
|
||||
AnswerCall(Connection, ACCEPT, 4, 4, 4, (_cstruct)&B3conf);
|
||||
chmod(RcvName, 0600);
|
||||
return;
|
||||
}
|
||||
}
|
||||
AnswerCall(Connection, REJECT, 4, 4, 4, (_cstruct)&B3conf);
|
||||
syslog(LOG_INFO, "Call from %s rejected\n", CallingPartyNumber);
|
||||
}
|
||||
|
||||
void InitQueue(void) {
|
||||
unsigned x;
|
||||
|
||||
for (x=0; x<QueueSize; x++)
|
||||
Queue.Element[x].SENT = FALSE;
|
||||
Queue.Head = 0;
|
||||
Queue.Tail = 0;
|
||||
Queue.Fill = 0;
|
||||
}
|
||||
|
||||
unsigned ReceiveFax() {
|
||||
int gotdata;
|
||||
int ret = 0;
|
||||
|
||||
reason = reason_b3 = rpages = rres = 0;
|
||||
rid[0] = '\0';
|
||||
syslog(LOG_INFO, "Start listening\n");
|
||||
InitQueue();
|
||||
Listen(0x1FFF03FF);
|
||||
while (Slot == INVALID_CONNECTION_ID)
|
||||
Handle_CAPI_Msg();
|
||||
while (Slot != INVALID_CONNECTION_ID)
|
||||
Handle_CAPI_Msg();
|
||||
FileReceive = FALSE;
|
||||
gotdata = (ftell(f) != 0L);
|
||||
fclose(f);
|
||||
switch (reason) {
|
||||
case 0:
|
||||
case 0x3490: /* Normal call clearing */
|
||||
case 0x349f: /* Normal, unspecified */
|
||||
ret = reason_b3;
|
||||
break;
|
||||
default:
|
||||
ret = reason;
|
||||
}
|
||||
if (gotdata && (!ret) && rpages) {
|
||||
/* Rename fax to reflect resolution, pages and remote-id */
|
||||
int i;
|
||||
int l;
|
||||
char newname[1024];
|
||||
|
||||
sprintf(newname, "f%c%03d%08lx", (rres)?'f':'n', rpages,
|
||||
time(NULL));
|
||||
l = strlen(newname);
|
||||
for (i=0; rid[i]; i++) {
|
||||
switch(rid[i]) {
|
||||
case ' ':
|
||||
newname[l++] = '_';
|
||||
break;
|
||||
case '/':
|
||||
case '\\':
|
||||
case '&':
|
||||
case ';':
|
||||
case '(':
|
||||
case ')':
|
||||
case '>':
|
||||
case '<':
|
||||
case '|':
|
||||
case '?':
|
||||
case '*':
|
||||
case '\'':
|
||||
case '"':
|
||||
case '`':
|
||||
if (newname[l-1] != '-' )
|
||||
newname[l++] = '-';
|
||||
break;
|
||||
default:
|
||||
newname[l++] = rid[i];
|
||||
}
|
||||
}
|
||||
newname[l] = '\0';
|
||||
rename(RcvName, newname);
|
||||
chmod(newname, 0640);
|
||||
syslog(LOG_INFO, "Received a FAX\n");
|
||||
if (notifyCmd) {
|
||||
sprintf(RcvName, "%s %s", notifyCmd, newname);
|
||||
system(RcvName);
|
||||
}
|
||||
} else
|
||||
remove(RcvName);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void usage(void) {
|
||||
fprintf(stderr, "usage: capifaxrcvd [-i stationID] [-h header] [-l listenNumber] [-n notifyCmd] rcvDirectory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int numController;
|
||||
int BChannels, Contr;
|
||||
int c;
|
||||
|
||||
while ((c = getopt(argc, argv, "l:i:h:n:")) != EOF) {
|
||||
switch (c) {
|
||||
case 'l':
|
||||
CalledPartyNumber = strdup(optarg);
|
||||
break;
|
||||
case 'i':
|
||||
stationID = strdup(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
headLine = strdup(optarg);
|
||||
break;
|
||||
case 'n':
|
||||
notifyCmd = strdup(optarg);
|
||||
break;
|
||||
case '?':
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if (argc < optind + 1)
|
||||
usage();
|
||||
RcvDir = argv[optind];
|
||||
if (chdir(RcvDir) != 0) {
|
||||
perror(RcvDir);
|
||||
return -1;
|
||||
}
|
||||
Slot = INVALID_CONNECTION_ID;
|
||||
MainStateChange_p = MainStateChange;
|
||||
MainDataAvailable_p = MainDataAvailable;
|
||||
MainIncomingCall_p = MainIncomingCall;
|
||||
if (!RegisterCAPI())
|
||||
return -1;
|
||||
atexit (ReleaseCAPI);
|
||||
InitConnectionIDHandling();
|
||||
if (!(numController = GetNumController())) {
|
||||
fprintf(stderr, "No CAPI controllers available\n");
|
||||
return -2;
|
||||
}
|
||||
BChannels = 0;
|
||||
for (Contr=1; Contr<=numController; Contr++)
|
||||
BChannels += GetNumOfSupportedBChannels(Contr);
|
||||
if (!BChannels) {
|
||||
fprintf(stderr, "No B-Channels available\n");
|
||||
return -3;
|
||||
}
|
||||
switch (fork()) {
|
||||
case 0:
|
||||
openlog("capifaxrcvd", LOG_PID, LOG_DAEMON);
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
while (1)
|
||||
ReceiveFax();
|
||||
if ((Slot != INVALID_CONNECTION_ID) &&
|
||||
(GetState(Slot) != Disconnected) &&
|
||||
(GetState(Slot) != D_DisconnectPending))
|
||||
Disconnect(Slot);
|
||||
break;
|
||||
case -1:
|
||||
perror("fork");
|
||||
exit(errno);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
#undef VERSION
|
||||
#undef PACKAGE
|
||||
#undef CONFIG_SBINDIR
|
||||
#undef CONFIG_MANDIR
|
||||
|
||||
/* Define if you have the <sys/ioctl.h> header file. */
|
||||
#undef HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,48 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(capifax.c)
|
||||
AM_INIT_AUTOMAKE(capifax, 1.0)
|
||||
AC_PREFIX_DEFAULT(/usr)
|
||||
|
||||
I4LCONFDIR=`eval echo ${CONFIG_I4LCONFDIR:-"/etc/isdn"}`
|
||||
I4LVERSION=${I4LVERSION:-"?.?"}
|
||||
CONFIG_KERNELDIR=${CONFIG_KERNELDIR:-"/usr/src/linux"}
|
||||
CONFIG_SBINDIR=${CONFIG_SBINDIR:-"/sbin"}
|
||||
CONFIG_MANDIR=${CONFIG_MANDIR:-"/usr/man"}
|
||||
#MANDATE=`grep CHECKIN isdnctrl.man.in | awk '{print $4}'`
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_CC
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(sys/ioctl.h unistd.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
|
||||
dnl Optional sbin directory
|
||||
AC_ARG_WITH(sbin,
|
||||
[ --with-sbin=DIR Set dir where binary is istalled. [/sbin]],
|
||||
CONFIG_SBINDIR="${withval}"
|
||||
AC_DEFINE(CONFIG_SBINDIR,"${withval}"),
|
||||
)
|
||||
|
||||
dnl Optional man directory
|
||||
AC_ARG_WITH(man,
|
||||
[ --with-man=DIR Set manpage dir. [/usr/man]],
|
||||
CONFIG_MANDIR="${withval}"
|
||||
AC_DEFINE(CONFIG_MANDIR,"${withval}"),
|
||||
)
|
||||
|
||||
AC_SUBST(INSTALL)
|
||||
AC_SUBST(DBMLIB)
|
||||
AC_SUBST(MANDATE)
|
||||
AC_SUBST(I4LCONFDIR)
|
||||
AC_SUBST(I4LVERSION)
|
||||
AC_SUBST(CONFIG_KERNELDIR)
|
||||
AC_SUBST(CONFIG_SBINDIR)
|
||||
AC_SUBST(CONFIG_MANDIR)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AC_OUTPUT(Makefile)
|
|
@ -0,0 +1,193 @@
|
|||
/*--------------------------------------------------------------------------*\
|
||||
|
||||
CONNECT.C Version 1.1 1995 AVM
|
||||
|
||||
Functions concerning activation and deactivation of connections
|
||||
|
||||
\*--------------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
#include <linux/capi.h>
|
||||
#include <capi20.h>
|
||||
|
||||
#include "contr.h"
|
||||
#include "init.h"
|
||||
#include "connect.h"
|
||||
|
||||
/* Function Pointers for Callback-Functions */
|
||||
MainStateChange_t MainStateChange_p = 0L;
|
||||
MainIncomingCall_t MainIncomingCall_p = 0L;
|
||||
|
||||
/*
|
||||
* Listen: send a LISTEN_REQ
|
||||
* parameters: CIPmask (which services shall be accepted) (see CAPI 2.0 spec.)
|
||||
* Listen will be sent to the number of controllers specified in InitISDN.
|
||||
* Listen with CIPmask = 0 results in getting no incoming calls signaled
|
||||
* by CAPI.
|
||||
*/
|
||||
unsigned Listen(unsigned long CIPmask) {
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
_cmsg CMSG;
|
||||
unsigned Controller;
|
||||
unsigned numController;
|
||||
|
||||
/* send listen to all controllers */
|
||||
numController = GetNumController();
|
||||
for (Controller=1; Controller<=numController; Controller++) {
|
||||
LISTEN_REQ_HEADER(&CMSG, Appl_Id, 0, Controller);
|
||||
LISTEN_REQ_CIPMASK(&CMSG) = CIPmask;
|
||||
if ((error = CAPI_PUT_CMSG(&CMSG)) != 0)
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* all capi functions can also be called with all possible parameters specified
|
||||
* direct in the function, e.g.
|
||||
*
|
||||
* error = CONNECT_REQ(&CMSG, Appl_Id, 0,
|
||||
* Controller, CIPValue,
|
||||
* CalledPartyNumber, CallingPartyNumber,
|
||||
* CalledPartySubaddress, CallingPartySubaddress,
|
||||
* B1Protokoll, B2Protokoll, B3Protokoll,
|
||||
* B1Configuration, B2Configuration, B3Configuration,
|
||||
* BC, LLC, HLC,
|
||||
* NULL, NULL, NULL, NULL);
|
||||
*/
|
||||
|
||||
/*
|
||||
* Connect: try's to connect to 'CalledPartyNumber'
|
||||
* the return value of CAPI_PUT_CMSG is the same as CAPI_PUT_MESSAGE
|
||||
* (defined in CAPI 2.0 spec. error class 0x11xx )
|
||||
* If CallingPartyNumber is not needed, set to NULL.
|
||||
* CallingPartyNumber & CalledPartyNumber have to be zero terminated strings.
|
||||
* For datatransmission set the protocols to zero, B3Configuration to NULL
|
||||
*/
|
||||
unsigned Connect(ConnectionID *Connection, char *CalledPartyNumber, char *CallingPartyNumber,
|
||||
unsigned long Service, unsigned short B1Protocol, unsigned short B2Protocol,
|
||||
unsigned short B3Protocol, unsigned char *B3Configuration) {
|
||||
|
||||
_cmsg CMSG;
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
long Controller;
|
||||
unsigned short CIPValue;
|
||||
|
||||
assert (*Connection == INVALID_CONNECTION_ID);
|
||||
|
||||
Controller = GetFreeController();
|
||||
if (Controller == INVAL_CONTROLLER) {
|
||||
/* if no available controller use the first one for correct
|
||||
* error signaling
|
||||
*/
|
||||
Controller = 1;
|
||||
}
|
||||
*Connection = AllocConnection();
|
||||
if (*Connection == INVALID_CONNECTION_ID) {
|
||||
fprintf(stderr, "Connect: No available connection identifiers.\n");
|
||||
/* no OS resources */
|
||||
return 0x1108;
|
||||
}
|
||||
/* use ConnectionIdentifier as Messagenumber */
|
||||
CONNECT_REQ_HEADER(&CMSG, Appl_Id, (unsigned short)*Connection, Controller);
|
||||
/* build up service mask */
|
||||
CIPValue = 0;
|
||||
if (Service != 0) {
|
||||
do {
|
||||
if (Service & 1)
|
||||
break;
|
||||
Service >>= 1;
|
||||
CIPValue++;
|
||||
} while (CIPValue < 31);
|
||||
}
|
||||
CONNECT_REQ_CIPVALUE(&CMSG) = CIPValue;
|
||||
SetCalledPartyNumber (*Connection, CalledPartyNumber);
|
||||
SetCallingPartyNumber (*Connection, CallingPartyNumber);
|
||||
CONNECT_REQ_CALLEDPARTYNUMBER(&CMSG) = GetCalledPartyNumberStruct(*Connection);
|
||||
CONNECT_REQ_CALLINGPARTYNUMBER(&CMSG) = GetCallingPartyNumberStruct(*Connection);
|
||||
CONNECT_REQ_B1PROTOCOL(&CMSG) = B1Protocol;
|
||||
CONNECT_REQ_B2PROTOCOL(&CMSG) = B2Protocol;
|
||||
CONNECT_REQ_B3PROTOCOL(&CMSG) = B3Protocol;
|
||||
CONNECT_REQ_B3CONFIGURATION(&CMSG) = B3Configuration;
|
||||
error = CAPI_PUT_CMSG(&CMSG);
|
||||
if (error != 0) {
|
||||
FreeConnection (*Connection);
|
||||
*Connection = INVALID_CONNECTION_ID;
|
||||
fprintf(stderr, "Connect: error in CAPI_PUT_MESSAGE\n");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disconnect: disconnects one channel
|
||||
* The ConnectionID must be valid
|
||||
*/
|
||||
unsigned Disconnect(ConnectionID Connection) {
|
||||
_cmsg CMSG;
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
|
||||
assert (Connection != INVALID_CONNECTION_ID);
|
||||
|
||||
switch (GetState(Connection)) {
|
||||
case Connected:
|
||||
case B_ConnectPending:
|
||||
SetConnectionInitiator (Connection, TRUE);
|
||||
DISCONNECT_B3_REQ_HEADER(&CMSG, Appl_Id, 0, GetConnectionNCCI (Connection));
|
||||
error = CAPI_PUT_CMSG(&CMSG);
|
||||
break;
|
||||
case D_Connected:
|
||||
case D_ConnectPending:
|
||||
case B_DisconnectPending:
|
||||
SetConnectionInitiator (Connection, TRUE);
|
||||
DISCONNECT_REQ_HEADER(&CMSG, Appl_Id, 0, GetConnectionPLCI (Connection));
|
||||
error = CAPI_PUT_CMSG(&CMSG);
|
||||
break;
|
||||
default:
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* IncomingCall: signals an incoming call
|
||||
* This function will be executed if a CONNECT_INDication appears to
|
||||
* inform the user. This function is implemented in the main program
|
||||
*/
|
||||
void IncomingCall(ConnectionID Connection, char *CallingPartyNumber) {
|
||||
if (MainIncomingCall_p)
|
||||
MainIncomingCall_p(Connection, CallingPartyNumber);
|
||||
}
|
||||
|
||||
/*
|
||||
* AnswerCall: answers incoming call with the specified reject-value
|
||||
* (some reject-values are defined in the req.h file)
|
||||
* (for more see CAPI 2.0 spec.)
|
||||
*/
|
||||
unsigned AnswerCall(ConnectionID Connection, RejectValue Reject, unsigned short B1Protocol,
|
||||
unsigned short B2Protocol, unsigned short B3Protocol, unsigned char *B3Configuration) {
|
||||
|
||||
_cmsg CMSG;
|
||||
|
||||
assert (Connection != INVALID_CONNECTION_ID);
|
||||
|
||||
CONNECT_RESP_HEADER(&CMSG, Appl_Id, 0, GetConnectionPLCI (Connection));
|
||||
CONNECT_RESP_REJECT(&CMSG) = (unsigned short)Reject;
|
||||
CONNECT_REQ_B1PROTOCOL(&CMSG) = B1Protocol;
|
||||
CONNECT_REQ_B2PROTOCOL(&CMSG) = B2Protocol;
|
||||
CONNECT_REQ_B3PROTOCOL(&CMSG) = B3Protocol;
|
||||
CONNECT_REQ_B3CONFIGURATION(&CMSG) = B3Configuration;
|
||||
return CAPI_PUT_CMSG(&CMSG);
|
||||
}
|
||||
|
||||
/*
|
||||
* StateChange: signals a state change on both B-channels (connected, disconnected)
|
||||
* Whenever a channel changes his state this function is called
|
||||
* This function is implemented in the main program
|
||||
*/
|
||||
void StateChange(ConnectionID Connection, ConnectionState State) {
|
||||
if (MainStateChange_p)
|
||||
MainStateChange_p(Connection, State);
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef _connect_h_
|
||||
#define _connect_h_
|
||||
|
||||
#include "id.h"
|
||||
|
||||
/*
|
||||
* Listen: send a LISTEN_REQ
|
||||
* parameters: CIPmask (which services shall be accepted) (see CAPI 2.0 spec.)
|
||||
* Listen will be sent to the number of controllers specified in InitISDN.
|
||||
* Listen with CIPmask = 0 results in getting no incoming calls signaled
|
||||
* by CAPI.
|
||||
*/
|
||||
#define NO_SERVICES 0x00000000
|
||||
#define ALL_SERVICES 0x1FFF03FF
|
||||
#define SPEECH 0x00000002
|
||||
#define DATA_TRANSFER 0x00000004
|
||||
#define AUDIO3_1KHZ 0x00000010
|
||||
#define TELEPHONY 0x00010000
|
||||
#define FAX_GROUP2_3 0x00020000
|
||||
|
||||
unsigned Listen(unsigned long CIPmask);
|
||||
|
||||
/*
|
||||
* Connect: try's to connect to 'CalledPartyNumber'
|
||||
* the return value of CAPI_PUT_CMSG is the same as CAPI_PUT_MESSAGE
|
||||
* (defined in CAPI 2.0 spec. error class 0x11xx )
|
||||
* If CallingPartyNumber is not needed, set to NULL.
|
||||
* CallingPartyNumber & CalledPartyNumber have to be zero terminated strings.
|
||||
* For datatransmission set the protocols to zero, B3Configuration to NULL
|
||||
*/
|
||||
unsigned Connect(ConnectionID *Connection, char *CalledPartyNumber, char *CallingPartyNumber,
|
||||
unsigned long Service, unsigned short B1Protocol, unsigned short B2Protocol,
|
||||
unsigned short B3Protocol, unsigned char *B3Configuration);
|
||||
|
||||
/*
|
||||
* Disconnect: disconnects one channel
|
||||
* The ConnectionID must be valid
|
||||
*/
|
||||
unsigned Disconnect(ConnectionID Connection);
|
||||
|
||||
/*
|
||||
* IncomingCall: signals an incoming call
|
||||
* This function will be executed if a CONNECT_INDication appears to
|
||||
* inform the user. This function has to be implemented in the main program
|
||||
*/
|
||||
void IncomingCall(ConnectionID Connection, char *CallingPartyNumber);
|
||||
|
||||
/*
|
||||
* AnswerCall: answers incoming call with the specified reject-value
|
||||
* (for more see CAPI 2.0 spec.)
|
||||
*/
|
||||
typedef enum _RejectValue {
|
||||
ACCEPT,
|
||||
IGNORE,
|
||||
REJECT
|
||||
} RejectValue;
|
||||
|
||||
unsigned AnswerCall(ConnectionID Connection, RejectValue Reject, unsigned short B1Protocol,
|
||||
unsigned short B2Protocol, unsigned short B3Protocol, unsigned char *B3Configuration);
|
||||
|
||||
/*
|
||||
* StateChange: signals a state change on both B-channels (connected, disconnected)
|
||||
* Whenever a channel changes his state this function is called
|
||||
* This function has to be implemented in the main program
|
||||
*/
|
||||
void StateChange(ConnectionID Connection, ConnectionState State);
|
||||
|
||||
typedef void (*MainStateChange_t)(ConnectionID, ConnectionState);
|
||||
typedef void (*MainIncomingCall_t)(ConnectionID, char *);
|
||||
extern MainStateChange_t MainStateChange_p;
|
||||
extern MainIncomingCall_t MainIncomingCall_p;
|
||||
|
||||
#endif /*----- _connect_h_ -----*/
|
|
@ -0,0 +1,48 @@
|
|||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
#include <linux/capi.h>
|
||||
#include <capi20.h>
|
||||
|
||||
#include "contr.h"
|
||||
#include "id.h"
|
||||
|
||||
/*
|
||||
* GetNumController: Returns the number of controllers detected by CAPI
|
||||
*/
|
||||
unsigned GetNumController(void) {
|
||||
unsigned short Buffer;
|
||||
|
||||
/* retrieve the number of installed controllers */
|
||||
CAPI20_GET_PROFILE (0, (unsigned char *)&Buffer);
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetNumOfSupportedBChannels: Returns the number of supported B-channels
|
||||
* for the specified controller
|
||||
*/
|
||||
unsigned GetNumOfSupportedBChannels (long Controller) {
|
||||
unsigned short Buffer[64 / sizeof (unsigned short)];
|
||||
|
||||
assert (Controller != INVAL_CONTROLLER);
|
||||
/* retrieve controller specific information */
|
||||
CAPI20_GET_PROFILE((unsigned)Controller, (unsigned char *)Buffer);
|
||||
return (unsigned)Buffer[1];
|
||||
}
|
||||
|
||||
/*
|
||||
* GetFreeController: Returns the number of the first controller that has
|
||||
* one free B-channel, or INVAL_CONTROLLER if none found.
|
||||
*/
|
||||
long GetFreeController(void) {
|
||||
long Controller;
|
||||
int numController;
|
||||
|
||||
numController = GetNumController ();
|
||||
for (Controller = 1; Controller <= numController; Controller++) {
|
||||
if (GetNumOfSupportedBChannels (Controller) > GetNumberOfConnections (Controller)) {
|
||||
return Controller;
|
||||
}
|
||||
}
|
||||
return INVAL_CONTROLLER;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef _contr_h_
|
||||
#define _contr_h_
|
||||
|
||||
/*
|
||||
* GetNumController: Returns the number of controllers detected by CAPI
|
||||
*/
|
||||
unsigned GetNumController (void);
|
||||
|
||||
/*
|
||||
* GetNumOfSupportedBChannels: Returns the number of supported B-channels
|
||||
* for the specified controller
|
||||
*/
|
||||
unsigned GetNumOfSupportedBChannels (long Controller);
|
||||
|
||||
/*
|
||||
* GetFreeController: Returns the number of the first controller that has
|
||||
* one free B-channel, or INVAL_CONTROLLER if none found.
|
||||
*/
|
||||
long GetFreeController (void);
|
||||
|
||||
#endif /* _contr_h_ */
|
|
@ -0,0 +1,72 @@
|
|||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
#include <linux/capi.h>
|
||||
#include <capi20.h>
|
||||
|
||||
#include "id.h"
|
||||
#include "init.h"
|
||||
#include "data.h"
|
||||
|
||||
MainDataAvailable_t MainDataAvailable_p = 0L;
|
||||
MainDataConf_t MainDataConf_p = 0L;
|
||||
|
||||
/*
|
||||
* SendData: Sends one block with data over the specified channel
|
||||
*/
|
||||
unsigned SendData(ConnectionID Connection, void *Data, unsigned short DataLength, unsigned short DataHandle) {
|
||||
_cmsg CMSG;
|
||||
|
||||
assert (Connection != INVALID_CONNECTION_ID);
|
||||
assert (GetState(Connection) == Connected);
|
||||
|
||||
DATA_B3_REQ_HEADER(&CMSG, Appl_Id, 0, GetConnectionNCCI(Connection));
|
||||
DATA_B3_REQ_DATA(&CMSG) = (unsigned long)Data;
|
||||
DATA_B3_REQ_DATALENGTH(&CMSG) = DataLength;
|
||||
DATA_B3_REQ_DATAHANDLE(&CMSG) = DataHandle;
|
||||
return CAPI_PUT_CMSG(&CMSG);
|
||||
}
|
||||
|
||||
/*
|
||||
* DataConf: signals the successful sending of a datablock
|
||||
* This function is called after receiving a DATA_B3_CONFirmation. CAPI signals
|
||||
* that the datablock identified by DataHandle has been sent and the memory
|
||||
* area may be freed. The DataHandle is the same as specified in SendBlock.
|
||||
* This function is implemented in the main program.
|
||||
*/
|
||||
void DataConf(ConnectionID Connection, unsigned short DataHandle, unsigned short Info) {
|
||||
if (MainDataConf_p)
|
||||
MainDataConf_p(Connection, DataHandle, Info);
|
||||
}
|
||||
|
||||
/*
|
||||
* DataAvailable: signals received data blocks
|
||||
* This function is called after a DATA_B3_INDication is received. The flag
|
||||
* DiscardData tells CAPI to free the memora area directly after the return
|
||||
* of this function when set to TRUE (1) which is the preset. When the flag
|
||||
* is set to FALSE (0) the data area MUST be freed later with ReleaseData.
|
||||
* The datahandle identifies the memory area. When reaching 7 unconfirmed
|
||||
* blocks, no more incoming data will be signaled until freeing at least
|
||||
* one block.
|
||||
* This function is implemented in the main program.
|
||||
*/
|
||||
void DataAvailable(ConnectionID Connection, void *Data, unsigned short DataLength,
|
||||
unsigned short DataHandle, int *DiscardData) {
|
||||
if (MainDataAvailable_p)
|
||||
MainDataAvailable_p(Connection, Data, DataLength, DataHandle,
|
||||
DiscardData);
|
||||
else
|
||||
*DiscardData = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* ReleaseData: allows CAPI to reuse the memory area of the specified block.
|
||||
* CAPI allows max. 7 unconfirmed Blocks. If the maximum of 7 is reached,
|
||||
* no more DATA_B3_INDications will come up.
|
||||
*/
|
||||
unsigned ReleaseData(ConnectionID Connection, unsigned short DataHandle) {
|
||||
_cmsg CMSG;
|
||||
|
||||
assert (Connection != INVALID_CONNECTION_ID);
|
||||
assert (GetState(Connection) == Connected);
|
||||
return DATA_B3_RESP(&CMSG, Appl_Id, 0, GetConnectionNCCI(Connection), DataHandle);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef _data_h_
|
||||
#define _data_h_
|
||||
|
||||
typedef void (*MainDataAvailable_t)(ConnectionID, void *, unsigned short,
|
||||
unsigned short, int *);
|
||||
typedef void (*MainDataConf_t)(ConnectionID, unsigned short, unsigned short);
|
||||
|
||||
extern MainDataAvailable_t MainDataAvailable_p;
|
||||
extern MainDataConf_t MainDataConf_p;
|
||||
|
||||
#define SendBlockSize 2048 /* must not be greater than MaxB3DataBlockSize in req.c */
|
||||
|
||||
/*
|
||||
* SendData: Sends one block with data over the specified channel
|
||||
*/
|
||||
unsigned SendData(ConnectionID Connection, void *Data, unsigned short DataLength, unsigned short DataHandle);
|
||||
|
||||
/*
|
||||
* DataConf: signals the successful sending of a datablock
|
||||
* This function is called after receiving a DATA_B3_CONFirmation. CAPI signals
|
||||
* that the datablock identified by DataHandle has been sent and the memory
|
||||
* area may be freed. The DataHandle is the same as specified in SendBlock.
|
||||
* This function is implemented in the main program.
|
||||
*/
|
||||
void DataConf(ConnectionID Connection, unsigned short DataHandle, unsigned short Info);
|
||||
|
||||
/*
|
||||
* DataAvailable: signals received data blocks
|
||||
* This function is called after a DATA_B3_INDication is received. The flag
|
||||
* DiscardData tells CAPI to free the memora area directly after the return
|
||||
* of this function when set to TRUE (1) which is the preset. When the flag
|
||||
* is set to FALSE (0) the data area MUST be freed later with ReleaseData.
|
||||
* The datahandle identifies the memory area. When reaching 7 unconfirmed
|
||||
* blocks, no more incoming data will be signaled until freeing at least
|
||||
* one block.
|
||||
* This function is implemented in the main program.
|
||||
*/
|
||||
void DataAvailable(ConnectionID Connection, void *Data, unsigned short DataLength,
|
||||
unsigned short DataHandle, int *DiscardData);
|
||||
|
||||
/*
|
||||
* ReleaseData: allows CAPI to reuse the memory area of the specified block.
|
||||
* CAPI allows max. 7 unconfirmed Blocks. If the maximum of 7 is reached,
|
||||
* no more DATA_B3_INDications will come up.
|
||||
*/
|
||||
unsigned ReleaseData(ConnectionID Connection, unsigned short DataHandle);
|
||||
|
||||
#endif /*----- _data_h_ -----*/
|
|
@ -0,0 +1,21 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "fax.h"
|
||||
|
||||
char *stationID = "00000000";
|
||||
char *headLine = "Unconfigured Cobalt FAXServer";
|
||||
|
||||
void SetupB3Config(B3_PROTO_FAXG3 *B3conf, int FAX_Format) {
|
||||
int len1;
|
||||
int len2;
|
||||
|
||||
B3conf->resolution = 0;
|
||||
B3conf->format = (unsigned short)FAX_Format;
|
||||
len1 = strlen(stationID);
|
||||
B3conf->Infos[0] = (unsigned char)len1;
|
||||
strcpy((char *)&B3conf->Infos[1], stationID);
|
||||
len2 = strlen(headLine);
|
||||
B3conf->Infos[len1 + 1] = (unsigned char)len2;
|
||||
strcpy((char *)&B3conf->Infos[len1 + 2], headLine);
|
||||
B3conf->len = (unsigned char)(2 * sizeof(unsigned short) + len1 + len2 + 2);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef _fax_h_
|
||||
#define _fax_h_
|
||||
|
||||
/* FAX Resolutions */
|
||||
#define FAX_STANDARD_RESOLUTION 0
|
||||
#define FAX_HIGH_RESOLUTION 1
|
||||
|
||||
/* FAX Formats */
|
||||
#define FAX_SFF_FORMAT 0
|
||||
#define FAX_PLAIN_FORMAT 1
|
||||
#define FAX_PCX_FORMAT 2
|
||||
#define FAX_DCX_FORMAT 3
|
||||
#define FAX_TIFF_FORMAT 4
|
||||
#define FAX_ASCII_FORMAT 5
|
||||
#define FAX_EXTENDED_ASCII_FORMAT 6
|
||||
#define FAX_BINARY_FILE_TRANSFER_FORMAT 7
|
||||
|
||||
typedef struct fax3proto3 {
|
||||
unsigned char len;
|
||||
unsigned short resolution __attribute__ ((packed));
|
||||
unsigned short format __attribute__ ((packed));
|
||||
unsigned char Infos[100] __attribute__ ((packed));
|
||||
} B3_PROTO_FAXG3;
|
||||
|
||||
void SetupB3Config(B3_PROTO_FAXG3 *B3conf, int FAX_Format);
|
||||
|
||||
#endif /* _fax_h_ */
|
|
@ -0,0 +1,399 @@
|
|||
#include <assert.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "id.h"
|
||||
|
||||
/*
|
||||
* type definitions
|
||||
*/
|
||||
const char *ConnectionStateString[7] = {
|
||||
"Disconnected",
|
||||
"D_ConnectPending",
|
||||
"D_Connected",
|
||||
"B_ConnectPending",
|
||||
"Connected",
|
||||
"B_DisconnectPending",
|
||||
"D_DisconnectPending"
|
||||
};
|
||||
|
||||
typedef struct _ConnectionDesc {
|
||||
unsigned InUse;
|
||||
long PLCI;
|
||||
long NCCI;
|
||||
long Controller;
|
||||
ConnectionState State;
|
||||
int Initiator;
|
||||
_cword Reason;
|
||||
_cword B3Reason;
|
||||
faxNCPI_t *faxNCPI; /* CAPI struct */
|
||||
unsigned char *CalledPartyNumberStruct; /* CAPI struct */
|
||||
unsigned char *CallingPartyNumberStruct; /* CAPI struct */
|
||||
} ConnectionDesc;
|
||||
|
||||
static ConnectionDesc C[maxConnections] = {0};
|
||||
static unsigned char *EmptyStruct = (unsigned char *)"\0";
|
||||
|
||||
/*
|
||||
* InitConnectionIDHandling: Initialisation of internal structures. Must be
|
||||
* executed before using the functions in this module.
|
||||
*/
|
||||
void InitConnectionIDHandling (void) {
|
||||
unsigned Con;
|
||||
|
||||
/* init local data */
|
||||
for (Con=0; Con<maxConnections; Con++)
|
||||
C[Con].InUse = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* AllocConnection: allocates one connection structure. Returns
|
||||
* INVALID_CONNECTION_ID if none free. All members are resetted.
|
||||
*/
|
||||
ConnectionID AllocConnection (void) {
|
||||
unsigned Con;
|
||||
|
||||
for (Con=0; Con<maxConnections; Con++) {
|
||||
if (!C[Con].InUse) {
|
||||
/* found free entry */
|
||||
C[Con].InUse = 1;
|
||||
C[Con].PLCI = INVAL_PLCI;
|
||||
C[Con].NCCI = INVAL_NCCI;
|
||||
C[Con].Controller = INVAL_CONTROLLER;
|
||||
C[Con].State = Disconnected;
|
||||
C[Con].Initiator = 0;
|
||||
C[Con].CalledPartyNumberStruct = EmptyStruct;
|
||||
C[Con].CallingPartyNumberStruct = EmptyStruct;
|
||||
C[Con].faxNCPI = NULL;
|
||||
C[Con].Reason = 0;
|
||||
C[Con].B3Reason = 0;
|
||||
return Con;
|
||||
}
|
||||
}
|
||||
return INVALID_CONNECTION_ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* FreeNumberStruct: Frees the memory area if the specified pointer is not
|
||||
* a pointer to EmptyStruct.
|
||||
*/
|
||||
static void FreeNumberStruct (unsigned char **pStruct) {
|
||||
|
||||
assert (*pStruct != NULL);
|
||||
if (*pStruct != EmptyStruct) {
|
||||
free (*pStruct);
|
||||
*pStruct = EmptyStruct;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FreeConnection: frees one connection, the ConnectionID is no longer valid
|
||||
*/
|
||||
void FreeConnection (ConnectionID Con) {
|
||||
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
C[Con].InUse = 0;
|
||||
FreeNumberStruct (&C[Con].CalledPartyNumberStruct);
|
||||
FreeNumberStruct (&C[Con].CallingPartyNumberStruct);
|
||||
if (C[Con].faxNCPI)
|
||||
free(C[Con].faxNCPI);
|
||||
}
|
||||
|
||||
/*
|
||||
* SetConnectionPLCI: sets the PLCI (and controller) for one connection
|
||||
*/
|
||||
void SetConnectionPLCI (ConnectionID Con, long PLCI) {
|
||||
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
C[Con].PLCI = PLCI;
|
||||
C[Con].Controller = (long)(PLCI & 0x000000FF);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetConnectionPLCI: returns the PLCI for one connection
|
||||
*/
|
||||
long GetConnectionPLCI (ConnectionID Con) {
|
||||
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
return C[Con].PLCI;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetConnectionByPLCI: Searches the connection that uses the PLCI, if none
|
||||
* found, returns INVALID_CONNECTION_ID.
|
||||
*/
|
||||
ConnectionID GetConnectionByPLCI (long PLCI) {
|
||||
unsigned Con;
|
||||
|
||||
assert (PLCI != INVAL_PLCI);
|
||||
for (Con=0; Con<maxConnections; Con++)
|
||||
if (C[Con].InUse && C[Con].PLCI == PLCI)
|
||||
return Con;
|
||||
return INVALID_CONNECTION_ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* SetConnectionNCCI: Sets the NCCI for one connection.
|
||||
*/
|
||||
void SetConnectionNCCI (ConnectionID Con, long NCCI) {
|
||||
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
C[Con].NCCI = NCCI;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetConnectionNCCI: Returns the NCCI for one connection.
|
||||
*/
|
||||
long GetConnectionNCCI (ConnectionID Con) {
|
||||
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
return C[Con].NCCI;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetConnectionByNCCI: Searches the connection that uses the NCCI, if none
|
||||
* found, returns INVALID_CONNECTION_ID.
|
||||
*/
|
||||
ConnectionID GetConnectionByNCCI (long NCCI) {
|
||||
unsigned Con;
|
||||
|
||||
assert (NCCI != INVAL_NCCI);
|
||||
for (Con=0; Con<maxConnections; Con++)
|
||||
if (C[Con].InUse && C[Con].NCCI == NCCI)
|
||||
return Con;
|
||||
return INVALID_CONNECTION_ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetController: Returns the controller that is used by the specified
|
||||
* connection.
|
||||
*/
|
||||
long GetController (ConnectionID Con) {
|
||||
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
return C[Con].Controller;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetNumberOfConnections: Returns the number of currently active connections
|
||||
* on the specified controller.
|
||||
*/
|
||||
unsigned GetNumberOfConnections (long Controller) {
|
||||
ConnectionID Con;
|
||||
unsigned numConnections = 0;
|
||||
|
||||
assert (Controller != INVAL_CONTROLLER);
|
||||
for (Con=0; Con<maxConnections; Con++)
|
||||
if (C[Con].InUse && (C[Con].Controller == Controller))
|
||||
numConnections++;
|
||||
return numConnections;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetState: Returns the state of the specified connection.
|
||||
*/
|
||||
ConnectionState GetState (ConnectionID Con) {
|
||||
if (Con == INVALID_CONNECTION_ID)
|
||||
return (ConnectionState)INVAL_STATE;
|
||||
assert (C[Con].InUse);
|
||||
return C[Con].State;
|
||||
}
|
||||
|
||||
/*
|
||||
* SetState: Sets the state of the specified connection.
|
||||
*/
|
||||
void SetState (ConnectionID Con, ConnectionState State) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
/* internal connection state */
|
||||
C[Con].State = State;
|
||||
}
|
||||
|
||||
/*
|
||||
* SetConnectionInitiator: Changes the Initiator flag to the specified value
|
||||
*/
|
||||
void SetConnectionInitiator (ConnectionID Con, int Initiator) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
C[Con].Initiator = Initiator;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetConnectionInitiator: Returns the Initiator flag for the specified
|
||||
* connection
|
||||
*/
|
||||
int GetConnectionInitiator (ConnectionID Con) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
return C[Con].Initiator;
|
||||
}
|
||||
|
||||
/*
|
||||
* SetCalledPartyNumber: Sets the CalledPartyNumber belonging to the specified
|
||||
* connection. CalledPartyNumber has to be a zero terminated string containing
|
||||
* only ASCII numbers.
|
||||
* Note: CalledPartyNumber has to different meanings in incoming and outgoing
|
||||
* call. For the outgoing call it contains the number of the party that will
|
||||
* be called, in incoming calls it contains the number that has been dialed
|
||||
* by the external party. On an ISDN access with multiple numbers this
|
||||
* CalledPartyNumber must be used to determine which number has been called.
|
||||
* Note, that this number may contain only the last one or two digits of
|
||||
* the called number, but this is enough to uniquely identify the called port.
|
||||
*/
|
||||
void SetCalledPartyNumber (ConnectionID Con, char *CalledNumber) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
FreeNumberStruct (&C[Con].CalledPartyNumberStruct);
|
||||
if (CalledNumber) {
|
||||
int len = strlen(CalledNumber);
|
||||
/* \xLen\x80 STRING '\0' */
|
||||
C[Con].CalledPartyNumberStruct = (unsigned char *)malloc(len + 2 + 1);
|
||||
assert (C[Con].CalledPartyNumberStruct != NULL);
|
||||
C[Con].CalledPartyNumberStruct[0] = (unsigned char)(len + 1);
|
||||
C[Con].CalledPartyNumberStruct[1] = 0x80;
|
||||
strcpy ((char *)&(C[Con].CalledPartyNumberStruct[2]), CalledNumber);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SetCalledPartyNumberStruct: Sets the CalledPartyNumber belonging to the
|
||||
* specified connection. CalledStruct has to be a valid CAPI struct.
|
||||
*/
|
||||
void SetCalledPartyNumberStruct (ConnectionID Con, unsigned char *CalledStruct) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
FreeNumberStruct (&C[Con].CalledPartyNumberStruct);
|
||||
if (CalledStruct) {
|
||||
/* two more for the length byte and '\0' */
|
||||
C[Con].CalledPartyNumberStruct = (unsigned char *)malloc((size_t)(CalledStruct[0] + 2));
|
||||
assert(C[Con].CalledPartyNumberStruct != NULL);
|
||||
memcpy(C[Con].CalledPartyNumberStruct, CalledStruct, (size_t)(CalledStruct[0] + 1));
|
||||
C[Con].CalledPartyNumberStruct[CalledStruct[0] + 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GetCalledPartyNumber: Returns the CalledPartyNumber belonging to the
|
||||
* specified connection as a zero terminated string.
|
||||
*/
|
||||
char *GetCalledPartyNumber (ConnectionID Con) {
|
||||
if (C[Con].CalledPartyNumberStruct[0] > 1)
|
||||
return (char *)(&(C[Con].CalledPartyNumberStruct[2]));
|
||||
else
|
||||
return (char *)EmptyStruct;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetCalledPartyNumberStruct: Returns the CalledPartyNumber belonging to the
|
||||
* specified connection as a CAPI struct.
|
||||
*/
|
||||
unsigned char *GetCalledPartyNumberStruct (ConnectionID Con) {
|
||||
return C[Con].CalledPartyNumberStruct;
|
||||
}
|
||||
|
||||
/*
|
||||
* SetCallingPartyNumber: Sets the CallingPartyNumber belonging to the
|
||||
* specified connection. CalledPartyNumber has to be a zero terminated string
|
||||
* containing only ASCII numbers.
|
||||
* CallingPartyNumber contains always the number of the party that originated
|
||||
* the call, if it is not needed you dont need to set it.
|
||||
*/
|
||||
void SetCallingPartyNumber (ConnectionID Con, char *CallingNumber) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
FreeNumberStruct (&C[Con].CallingPartyNumberStruct);
|
||||
if (CallingNumber && (*CallingNumber != 0)) {
|
||||
int len = strlen(CallingNumber);
|
||||
/* \xLen\x00\x80 STRING '\0' */
|
||||
C[Con].CallingPartyNumberStruct = (unsigned char *)malloc(len + 3 + 1);
|
||||
assert (C[Con].CallingPartyNumberStruct != NULL);
|
||||
C[Con].CallingPartyNumberStruct[0] = (unsigned char)(len + 2);
|
||||
C[Con].CallingPartyNumberStruct[1] = 0x00;
|
||||
C[Con].CallingPartyNumberStruct[2] = 0x80;
|
||||
strcpy ((char *)&(C[Con].CallingPartyNumberStruct[3]), CallingNumber);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SetCallingPartyNumberStruct: Sets the CallingPartyNumber belonging to the
|
||||
* specified connection. CallingStruct has to be a valid CAPI struct.
|
||||
*/
|
||||
void SetCallingPartyNumberStruct (ConnectionID Con, unsigned char *CallingStruct) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
FreeNumberStruct (&C[Con].CallingPartyNumberStruct);
|
||||
if (CallingStruct) {
|
||||
/* two more for the length byte and '\0' */
|
||||
C[Con].CallingPartyNumberStruct = (unsigned char *)malloc((size_t)(CallingStruct[0] + 2));
|
||||
assert(C[Con].CallingPartyNumberStruct != NULL);
|
||||
memcpy(C[Con].CallingPartyNumberStruct, CallingStruct, (size_t)(CallingStruct[0] + 1));
|
||||
C[Con].CallingPartyNumberStruct[CallingStruct[0] + 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GetCallingPartyNumber: Returns the CallingPartyNumber belonging to the
|
||||
* specified connection as a zero terminated string.
|
||||
*/
|
||||
char *GetCallingPartyNumber (ConnectionID Con) {
|
||||
if (C[Con].CallingPartyNumberStruct[0] > 2)
|
||||
return (char *)&(C[Con].CallingPartyNumberStruct[3]);
|
||||
else
|
||||
return (char *)EmptyStruct;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetCallingPartyNumberStruct: Returns the CallingPartyNumber belonging to the
|
||||
* specified connection as a CAPI struct.
|
||||
*/
|
||||
unsigned char *GetCallingPartyNumberStruct (ConnectionID Con) {
|
||||
return C[Con].CallingPartyNumberStruct;
|
||||
}
|
||||
|
||||
void SetB3Reason(ConnectionID Con, _cword r) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
C[Con].B3Reason = r;
|
||||
}
|
||||
|
||||
void SetReason(ConnectionID Con, _cword r) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
C[Con].Reason = r;
|
||||
}
|
||||
|
||||
unsigned short GetB3Reason(ConnectionID Con) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
return C[Con].B3Reason;
|
||||
}
|
||||
|
||||
unsigned short GetReason(ConnectionID Con) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
return C[Con].Reason;
|
||||
}
|
||||
|
||||
/*
|
||||
* SetFaxNCPI: Sets the faxNCPI (StationId, Speed, etc.) belonging to the
|
||||
* specified connection. faxNCPI has to be a valid CAPI struct.
|
||||
*/
|
||||
void SetFaxNCPI (ConnectionID Con, faxNCPI_t *faxNCPI) {
|
||||
assert (Con != INVALID_CONNECTION_ID);
|
||||
assert (C[Con].InUse);
|
||||
if (faxNCPI) {
|
||||
C[Con].faxNCPI = (faxNCPI_t *)malloc(sizeof(faxNCPI_t));
|
||||
assert(C[Con].faxNCPI != NULL);
|
||||
memset(C[Con].faxNCPI, 0, sizeof(faxNCPI_t));
|
||||
memcpy(C[Con].faxNCPI, faxNCPI, (size_t)(faxNCPI->length + 1));
|
||||
C[Con].faxNCPI->id[faxNCPI->idlen + 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
faxNCPI_t *GetFaxNCPI(ConnectionID Con) {
|
||||
return C[Con].faxNCPI;
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
#ifndef _id_h_
|
||||
#define _id_h_
|
||||
|
||||
#include <capi20.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
typedef enum _ConnectionState {
|
||||
Disconnected,
|
||||
D_ConnectPending,
|
||||
D_Connected,
|
||||
B_ConnectPending,
|
||||
Connected,
|
||||
B_DisconnectPending,
|
||||
D_DisconnectPending
|
||||
} ConnectionState;
|
||||
|
||||
typedef struct {
|
||||
_cbyte length;
|
||||
_cword rate __attribute__ ((packed));
|
||||
_cword resolution __attribute__ ((packed));
|
||||
_cword format __attribute__ ((packed));
|
||||
_cword pages __attribute__ ((packed));
|
||||
_cbyte idlen __attribute__ ((packed));
|
||||
_cbyte id[50] __attribute__ ((packed));
|
||||
} faxNCPI_t;
|
||||
|
||||
extern const char *ConnectionStateString[7];
|
||||
|
||||
typedef int ConnectionID;
|
||||
|
||||
#define maxConnections 8
|
||||
#define INVALID_CONNECTION_ID (-1)
|
||||
#define INVAL_STATE (-1)
|
||||
#define INVAL_NCCI (-1)
|
||||
#define INVAL_PLCI (-1)
|
||||
#define INVAL_CONTROLLER (-1)
|
||||
|
||||
/*
|
||||
* InitConnectionIDHandling: Initialisation of internal structures. Must be
|
||||
* executed before using the functions in this module.
|
||||
*/
|
||||
void InitConnectionIDHandling(void);
|
||||
|
||||
/*
|
||||
* AllocConnection: allocates one connection structure. Returns
|
||||
* INVALID_CONNECTION_ID if none free. All members are resetted.
|
||||
*/
|
||||
ConnectionID AllocConnection(void);
|
||||
|
||||
/*
|
||||
* FreeConnection: frees one connection, the ConnectionID is no longer valid
|
||||
*/
|
||||
void FreeConnection(ConnectionID Connection);
|
||||
|
||||
/*
|
||||
* SetConnectionPLCI: sets the PLCI (and controller) for one connection
|
||||
*/
|
||||
void SetConnectionPLCI(ConnectionID Con, long PLCI);
|
||||
|
||||
/*
|
||||
* GetConnectionPLCI: returns the PLCI for one connection
|
||||
*/
|
||||
long GetConnectionPLCI(ConnectionID Con);
|
||||
|
||||
/*
|
||||
* GetConnectionByPLCI: Searches the connection that uses the PLCI, if none
|
||||
* found, returns INVALID_CONNECTION_ID.
|
||||
*/
|
||||
ConnectionID GetConnectionByPLCI(long PLCI);
|
||||
|
||||
/*
|
||||
* SetConnectionNCCI: Sets the NCCI for one connection.
|
||||
*/
|
||||
void SetConnectionNCCI(ConnectionID Con, long NCCI);
|
||||
|
||||
/*
|
||||
* GetConnectionNCCI: Returns the NCCI for one connection.
|
||||
*/
|
||||
long GetConnectionNCCI(ConnectionID Con);
|
||||
|
||||
/*
|
||||
* GetConnectionByNCCI: Searches the connection that uses the NCCI, if none
|
||||
* found, returns INVALID_CONNECTION_ID.
|
||||
*/
|
||||
ConnectionID GetConnectionByNCCI(long NCCI);
|
||||
|
||||
/*
|
||||
* GetController: Returns the controller that is used by the specified
|
||||
* connection.
|
||||
*/
|
||||
long GetController(ConnectionID Con);
|
||||
|
||||
/*
|
||||
* GetNumberOfConnections: Returns the number of currently active connections
|
||||
* on the specified controller.
|
||||
*/
|
||||
unsigned GetNumberOfConnections(long Controller);
|
||||
|
||||
/*
|
||||
* GetState: Returns the state of the specified connection.
|
||||
*/
|
||||
ConnectionState GetState(ConnectionID Connection);
|
||||
|
||||
/*
|
||||
* SetState: Sets the state of the specified connection.
|
||||
*/
|
||||
void SetState(ConnectionID Connection, ConnectionState State);
|
||||
|
||||
/*
|
||||
* SetConnectionInitiator: Changes the Initiator flag to the specified value
|
||||
*/
|
||||
void SetConnectionInitiator(ConnectionID Con, int Initiator);
|
||||
|
||||
/*
|
||||
* GetConnectionInitiator: Returns the Initiator flag for the specified
|
||||
* connection
|
||||
*/
|
||||
int GetConnectionInitiator(ConnectionID Con);
|
||||
|
||||
/*
|
||||
* SetCalledPartyNumber: Sets the CalledPartyNumber belonging to the specified
|
||||
* connection. CalledPartyNumber has to be a zero terminated string containing
|
||||
* only ASCII numbers.
|
||||
* Note: CalledPartyNumber has to different meanings in incoming and outgoing
|
||||
* call. For the outgoing call it contains the number of the party that will
|
||||
* be called, in incoming calls it contains the number that has been dialed
|
||||
* by the external party. On an ISDN access with multiple numbers this
|
||||
* CalledPartyNumber must be used to determine which number has been called.
|
||||
* Note, that this number may contain only the last one or two digits of
|
||||
* the called number, but this is enough to uniquely identify the called port.
|
||||
*/
|
||||
void SetCalledPartyNumber(ConnectionID Con, char *CalledPartyNumber);
|
||||
|
||||
/*
|
||||
* SetCalledPartyNumberStruct: Sets the CalledPartyNumber belonging to the
|
||||
* specified connection. CalledStruct has to be a valid CAPI struct.
|
||||
*/
|
||||
void SetCalledPartyNumberStruct(ConnectionID Con, unsigned char *CalledPartyNumber);
|
||||
|
||||
/*
|
||||
* GetCalledPartyNumber: Returns the CalledPartyNumber belonging to the
|
||||
* specified connection as a zero terminated string.
|
||||
*/
|
||||
char *GetCalledPartyNumber(ConnectionID Con);
|
||||
|
||||
/*
|
||||
* GetCalledPartyNumberStruct: Returns the CalledPartyNumber belonging to the
|
||||
* specified connection as a CAPI struct.
|
||||
*/
|
||||
unsigned char *GetCalledPartyNumberStruct(ConnectionID Con);
|
||||
|
||||
/*
|
||||
* SetCallingPartyNumber: Sets the CallingPartyNumber belonging to the
|
||||
* specified connection. CalledPartyNumber has to be a zero terminated string
|
||||
* containing only ASCII numbers.
|
||||
* CallingPartyNumber contains always the number of the party that originated
|
||||
* the call, if it is not needed you dont need to set it.
|
||||
*/
|
||||
void SetCallingPartyNumber(ConnectionID Con, char *CallingPartyNumber);
|
||||
|
||||
/*
|
||||
* SetCallingPartyNumberStruct: Sets the CallingPartyNumber belonging to the
|
||||
* specified connection. CallingStruct has to be a valid CAPI struct.
|
||||
*/
|
||||
void SetCallingPartyNumberStruct(ConnectionID Con, unsigned char *CallingPartyNumber);
|
||||
|
||||
/*
|
||||
* GetCallingPartyNumber: Returns the CallingPartyNumber belonging to the
|
||||
* specified connection as a zero terminated string.
|
||||
*/
|
||||
char *GetCallingPartyNumber(ConnectionID Con);
|
||||
|
||||
/*
|
||||
* GetCallingPartyNumberStruct: Returns the CallingPartyNumber belonging to the
|
||||
* specified connection as a CAPI struct.
|
||||
*/
|
||||
unsigned char *GetCallingPartyNumberStruct(ConnectionID Con);
|
||||
|
||||
void SetFaxNCPI (ConnectionID Con, faxNCPI_t *faxNCPI);
|
||||
faxNCPI_t *GetFaxNCPI(ConnectionID Con);
|
||||
|
||||
void SetB3Reason(ConnectionID Con, _cword r);
|
||||
void SetReason(ConnectionID Con, _cword r);
|
||||
|
||||
unsigned short GetB3Reason(ConnectionID);
|
||||
unsigned short GetReason(ConnectionID);
|
||||
#endif /* _id_h_ */
|
|
@ -0,0 +1,63 @@
|
|||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/time.h>
|
||||
#include <linux/capi.h>
|
||||
#include <capi20.h>
|
||||
|
||||
#include "init.h"
|
||||
#include "contr.h"
|
||||
#include "capi.h"
|
||||
|
||||
/*
|
||||
* defines needed by InitISDN
|
||||
*/
|
||||
unsigned short Appl_Id = 0;
|
||||
|
||||
#define MaxNumBChan 2 /* max. number of B-channels */
|
||||
#define MaxNumB3DataBlocks 7 /* max. number of unconfirmed B3-datablocks */
|
||||
/* 7 is the maximal number supported by CAPI */
|
||||
#define MaxB3DataBlockSize 2048 /* max. B3-Datablocksize */
|
||||
/* 2048 is the maximum supported by CAPI */
|
||||
|
||||
static CAPI_MESSAGE CAPI_BUFFER = NULL;
|
||||
|
||||
/*
|
||||
* RegisterCAPI: Check for CAPI, allocate memory for CAPI-buffer and
|
||||
* register application. This function has to be called before using any
|
||||
* other CAPI functions.
|
||||
*/
|
||||
unsigned RegisterCAPI (void) {
|
||||
CAPI_REGISTER_ERROR ErrorCode;
|
||||
int numController;
|
||||
|
||||
if (!CAPI20_ISINSTALLED()) {
|
||||
fprintf(stderr, "No CAPI support on this system.\n");
|
||||
return 0;
|
||||
}
|
||||
if (!(numController = GetNumController())) {
|
||||
fprintf(stderr, "RegisterCAPI: No ISDN-controller installed\n");
|
||||
return 0;
|
||||
}
|
||||
Appl_Id = CAPI20_REGISTER(MaxNumBChan, MaxNumB3DataBlocks,
|
||||
MaxB3DataBlockSize, &ErrorCode);
|
||||
if (!Appl_Id) {
|
||||
fprintf(stderr, "RegisterCAPI: error: %04x\n", ErrorCode);
|
||||
return 0;
|
||||
}
|
||||
return numController;
|
||||
}
|
||||
|
||||
/*
|
||||
* ReleaseCAPI: deregister application
|
||||
*/
|
||||
void ReleaseCAPI (void) {
|
||||
MESSAGE_EXCHANGE_ERROR ErrorCode;
|
||||
|
||||
ErrorCode = CAPI20_RELEASE(Appl_Id);
|
||||
if (ErrorCode != 0)
|
||||
fprintf(stderr, "ReleaseCAPI: error: 0x%04X\n", ErrorCode);
|
||||
if (CAPI_BUFFER) {
|
||||
free(CAPI_BUFFER);
|
||||
CAPI_BUFFER = NULL;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef _init_h_
|
||||
#define _init_h_
|
||||
|
||||
extern unsigned short Appl_Id;
|
||||
|
||||
/*
|
||||
* RegisterCAPI: Check for CAPI, allocate memory for CAPI-buffer and
|
||||
* register application. This function has to be called before using any
|
||||
* other CAPI functions.
|
||||
*/
|
||||
unsigned RegisterCAPI (void);
|
||||
|
||||
/*
|
||||
* ReleaseCAPI: deregister application
|
||||
*/
|
||||
void ReleaseCAPI (void);
|
||||
|
||||
#endif /* _init_h_ */
|
|
@ -0,0 +1,250 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5 (mit/util/scripts/install.sh).
|
||||
#
|
||||
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||
#
|
||||
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||
# documentation for any purpose is hereby granted without fee, provided that
|
||||
# the above copyright notice appear in all copies and that both that
|
||||
# copyright notice and this permission notice appear in supporting
|
||||
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||
# publicity pertaining to distribution of the software without specific,
|
||||
# written prior permission. M.I.T. makes no representations about the
|
||||
# suitability of this software for any purpose. It is provided "as is"
|
||||
# without express or implied warranty.
|
||||
#
|
||||
# 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. It can only install one file at a time, a restriction
|
||||
# shared with many OS's install programs.
|
||||
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. 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}"
|
||||
|
||||
transformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd="$cpprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd="$stripprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "install: no input file specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
instcmd=mkdir
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
then
|
||||
true
|
||||
else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
|
||||
if [ -d $dst ]
|
||||
then
|
||||
dst="$dst"/`basename $src`
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
oIFS="${IFS}"
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS="${oIFS}"
|
||||
|
||||
pathcomp=''
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp="${pathcomp}${1}"
|
||||
shift
|
||||
|
||||
if [ ! -d "${pathcomp}" ] ;
|
||||
then
|
||||
$mkdirprog "${pathcomp}"
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd $dst &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
|
||||
else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
$doit $instcmd $src $dsttmp &&
|
||||
|
||||
trap "rm -f ${dsttmp}" 0 &&
|
||||
|
||||
# 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 $instcmd $src $dsttmp" command.
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,134 @@
|
|||
#! /bin/sh
|
||||
# Common stub for a few missing GNU programs while installing.
|
||||
# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
# Franc,ois 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., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
|
||||
-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
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal touch file \`aclocal.m4'
|
||||
autoconf touch file \`configure'
|
||||
autoheader touch file \`config.h.in'
|
||||
automake touch all \`Makefile.in' files
|
||||
bison touch file \`y.tab.c'
|
||||
makeinfo touch the output file
|
||||
yacc touch file \`y.tab.c'"
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing - GNU libit 0.0"
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: Unknown \`$1' option"
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
aclocal)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
you modified \`acinclude.m4' or \`configure.in'. 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 missing on your system. You should only need it if
|
||||
you modified \`configure.in'. 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 missing on your system. You should only need it if
|
||||
you modified \`acconfig.h' or \`configure.in'. You might want
|
||||
to install the \`Autoconf' and \`GNU m4' packages. Grab them
|
||||
from any GNU archive site."
|
||||
touch config.h.in
|
||||
;;
|
||||
|
||||
automake)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
|
||||
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$/touch \1.in/' \
|
||||
| sh
|
||||
;;
|
||||
|
||||
bison|yacc)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. 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."
|
||||
touch y.tab.c
|
||||
;;
|
||||
|
||||
makeinfo)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. 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."
|
||||
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||
if test -z "$file"; then
|
||||
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
|
||||
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
|
||||
fi
|
||||
touch $file
|
||||
;;
|
||||
|
||||
*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is needed, and you do not seem to have it handy on your
|
||||
system. 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 prerequirements 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
|
|
@ -0,0 +1,40 @@
|
|||
#! /bin/sh
|
||||
# mkinstalldirs --- make directory hierarchy
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-05-16
|
||||
# Public domain
|
||||
|
||||
# $Id: mkinstalldirs,v 1.1 1998/10/23 12:27:54 fritz Exp $
|
||||
|
||||
errstatus=0
|
||||
|
||||
for file
|
||||
do
|
||||
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
|
||||
shift
|
||||
|
||||
pathcomp=
|
||||
for d
|
||||
do
|
||||
pathcomp="$pathcomp$d"
|
||||
case "$pathcomp" in
|
||||
-* ) pathcomp=./$pathcomp ;;
|
||||
esac
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
echo "mkdir $pathcomp" 1>&2
|
||||
|
||||
mkdir "$pathcomp" || lasterr=$?
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
errstatus=$lasterr
|
||||
fi
|
||||
fi
|
||||
|
||||
pathcomp="$pathcomp/"
|
||||
done
|
||||
done
|
||||
|
||||
exit $errstatus
|
||||
|
||||
# mkinstalldirs ends here
|
|
@ -0,0 +1,525 @@
|
|||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <linux/capi.h>
|
||||
#include "capi20.h"
|
||||
|
||||
typedef enum {
|
||||
CAPI_PROTOCOL_HEADER, /* occurs only once at CAPI_PROTOCOL_INIT */
|
||||
CAPI_PROTOCOL_MSG, /* output is a CAPI Message */
|
||||
CAPI_PROTOCOL_TXT, /* output is text caused by CAPI_PROTOCOL_TEXT */
|
||||
} CAPI_PROTOCOL_TYP;
|
||||
|
||||
typedef struct {
|
||||
int typ;
|
||||
unsigned off;
|
||||
} _cdef;
|
||||
|
||||
#define _CBYTE 1
|
||||
#define _CWORD 2
|
||||
#define _CDWORD 3
|
||||
#define _CSTRUCT 4
|
||||
#define _CMSTRUCT 5
|
||||
#define _CEND 6
|
||||
|
||||
static _cdef cdef[] = {
|
||||
/*00*/{_CEND},
|
||||
/*01*/{_CEND},
|
||||
/*02*/{_CEND},
|
||||
/*03*/{_CDWORD, (unsigned)(unsigned long)&((_cmsg *)0)->adr.adrController},
|
||||
/*04*/{_CMSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->AdditionalInfo},
|
||||
/*05*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->B1configuration},
|
||||
/*06*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->B1protocol},
|
||||
/*07*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->B2configuration},
|
||||
/*08*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->B2protocol},
|
||||
/*09*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->B3configuration},
|
||||
/*0a*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->B3protocol},
|
||||
/*0b*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->BC},
|
||||
/*0c*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->BChannelinformation},
|
||||
/*0d*/{_CMSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->BProtocol},
|
||||
/*0e*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->CalledPartyNumber},
|
||||
/*0f*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->CalledPartySubaddress},
|
||||
/*10*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->CallingPartyNumber},
|
||||
/*11*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->CallingPartySubaddress},
|
||||
/*12*/{_CDWORD, (unsigned)(unsigned long)&((_cmsg *)0)->CIPmask},
|
||||
/*13*/{_CDWORD, (unsigned)(unsigned long)&((_cmsg *)0)->CIPmask2},
|
||||
/*14*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->CIPValue},
|
||||
/*15*/{_CDWORD, (unsigned)(unsigned long)&((_cmsg *)0)->Class},
|
||||
/*16*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->ConnectedNumber},
|
||||
/*17*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->ConnectedSubaddress},
|
||||
/*18*/{_CDWORD, (unsigned)(unsigned long)&((_cmsg *)0)->Data},
|
||||
/*19*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->DataHandle},
|
||||
/*1a*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->DataLength},
|
||||
/*1b*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->FacilityConfirmationParameter},
|
||||
/*1c*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->Facilitydataarray},
|
||||
/*1d*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->FacilityIndicationParameter},
|
||||
/*1e*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->FacilityRequestParameter},
|
||||
/*1f*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->FacilityResponseParameters},
|
||||
/*20*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->FacilitySelector},
|
||||
/*21*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->Flags},
|
||||
/*22*/{_CDWORD, (unsigned)(unsigned long)&((_cmsg *)0)->Function},
|
||||
/*23*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->HLC},
|
||||
/*24*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->Info},
|
||||
/*25*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->InfoElement},
|
||||
/*26*/{_CDWORD, (unsigned)(unsigned long)&((_cmsg *)0)->InfoMask},
|
||||
/*27*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->InfoNumber},
|
||||
/*28*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->Keypadfacility},
|
||||
/*29*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->LLC},
|
||||
/*2a*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->ManuData},
|
||||
/*2b*/{_CDWORD, (unsigned)(unsigned long)&((_cmsg *)0)->ManuID},
|
||||
/*2c*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->NCPI},
|
||||
/*2d*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->Reason},
|
||||
/*2e*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->Reason_B3},
|
||||
/*2f*/{_CWORD, (unsigned)(unsigned long)&((_cmsg *)0)->Reject},
|
||||
/*30*/{_CSTRUCT, (unsigned)(unsigned long)&((_cmsg *)0)->Useruserdata},
|
||||
};
|
||||
|
||||
static unsigned char *cpars[] = {
|
||||
/*00*/ 0,
|
||||
/*01 ALERT_REQ*/ (unsigned char*)"\x03\x04\x0c\x28\x30\x1c\x01\x01",
|
||||
/*02 CONNECT_REQ*/ (unsigned char*)"\x03\x14\x0e\x10\x0f\x11\x0d\x06\x08\x0a\x05\x07\x09\x01\x0b\x29\x23\x04\x0c\x28\x30\x1c\x01\x01",
|
||||
/*03*/ 0,
|
||||
/*04 DISCONNECT_REQ*/ (unsigned char*)"\x03\x04\x0c\x28\x30\x1c\x01\x01",
|
||||
/*05 LISTEN_REQ*/ (unsigned char*)"\x03\x26\x12\x13\x10\x11\x01",
|
||||
/*06*/ 0,
|
||||
/*07*/ 0,
|
||||
/*08 INFO_REQ*/ (unsigned char*)"\x03\x0e\x04\x0c\x28\x30\x1c\x01\x01",
|
||||
/*09 FACILITY_REQ*/ (unsigned char*)"\x03\x20\x1e\x01",
|
||||
/*0a SELECT_B_PROTOCOL_REQ*/ (unsigned char*)"\x03\x0d\x06\x08\x0a\x05\x07\x09\x01\x01",
|
||||
/*0b CONNECT_B3_REQ*/ (unsigned char*)"\x03\x2c\x01",
|
||||
/*0c*/ 0,
|
||||
/*0d DISCONNECT_B3_REQ*/ (unsigned char*)"\x03\x2c\x01",
|
||||
/*0e*/ 0,
|
||||
/*0f DATA_B3_REQ*/ (unsigned char*)"\x03\x18\x1a\x19\x21\x01",
|
||||
/*10 RESET_B3_REQ*/ (unsigned char*)"\x03\x2c\x01",
|
||||
/*11*/ 0,
|
||||
/*12*/ 0,
|
||||
/*13 ALERT_CONF*/ (unsigned char*)"\x03\x24\x01",
|
||||
/*14 CONNECT_CONF*/ (unsigned char*)"\x03\x24\x01",
|
||||
/*15*/ 0,
|
||||
/*16 DISCONNECT_CONF*/ (unsigned char*)"\x03\x24\x01",
|
||||
/*17 LISTEN_CONF*/ (unsigned char*)"\x03\x24\x01",
|
||||
/*18 MANUFACTURER_REQ*/ (unsigned char*)"\x03\x2b\x15\x22\x2a\x01",
|
||||
/*19*/ 0,
|
||||
/*1a INFO_CONF*/ (unsigned char*)"\x03\x24\x01",
|
||||
/*1b FACILITY_CONF*/ (unsigned char*)"\x03\x24\x20\x1b\x01",
|
||||
/*1c SELECT_B_PROTOCOL_CONF*/ (unsigned char*)"\x03\x24\x01",
|
||||
/*1d CONNECT_B3_CONF*/ (unsigned char*)"\x03\x24\x01",
|
||||
/*1e*/ 0,
|
||||
/*1f DISCONNECT_B3_CONF*/ (unsigned char*)"\x03\x24\x01",
|
||||
/*20*/ 0,
|
||||
/*21 DATA_B3_CONF*/ (unsigned char*)"\x03\x19\x24\x01",
|
||||
/*22 RESET_B3_CONF*/ (unsigned char*)"\x03\x24\x01",
|
||||
/*23*/ 0,
|
||||
/*24*/ 0,
|
||||
/*25*/ 0,
|
||||
/*26 CONNECT_IND*/ (unsigned char*)"\x03\x14\x0e\x10\x0f\x11\x0b\x29\x23\x04\x0c\x28\x30\x1c\x01\x01",
|
||||
/*27 CONNECT_ACTIVE_IND*/ (unsigned char*)"\x03\x16\x17\x29\x01",
|
||||
/*28 DISCONNECT_IND*/ (unsigned char*)"\x03\x2d\x01",
|
||||
/*29*/ 0,
|
||||
/*2a MANUFACTURER_CONF*/ (unsigned char*)"\x03\x2b\x15\x22\x2a\x01",
|
||||
/*2b*/ 0,
|
||||
/*2c INFO_IND*/ (unsigned char*)"\x03\x27\x25\x01",
|
||||
/*2d FACILITY_IND*/ (unsigned char*)"\x03\x20\x1d\x01",
|
||||
/*2e*/ 0,
|
||||
/*2f CONNECT_B3_IND*/ (unsigned char*)"\x03\x2c\x01",
|
||||
/*30 CONNECT_B3_ACTIVE_IND*/ (unsigned char*)"\x03\x2c\x01",
|
||||
/*31 DISCONNECT_B3_IND*/ (unsigned char*)"\x03\x2e\x2c\x01",
|
||||
/*32*/ 0,
|
||||
/*33 DATA_B3_IND*/ (unsigned char*)"\x03\x18\x1a\x19\x21\x01",
|
||||
/*34 RESET_B3_IND*/ (unsigned char*)"\x03\x2c\x01",
|
||||
/*35 CONNECT_B3_T90_ACTIVE_IND*/ (unsigned char*)"\x03\x2c\x01",
|
||||
/*36*/ 0,
|
||||
/*37*/ 0,
|
||||
/*38 CONNECT_RESP*/ (unsigned char*)"\x03\x2f\x0d\x06\x08\x0a\x05\x07\x09\x01\x16\x17\x29\x04\x0c\x28\x30\x1c\x01\x01",
|
||||
/*39 CONNECT_ACTIVE_RESP*/ (unsigned char*)"\x03\x01",
|
||||
/*3a DISCONNECT_RESP*/ (unsigned char*)"\x03\x01",
|
||||
/*3b*/ 0,
|
||||
/*3c MANUFACTURER_IND*/ (unsigned char*)"\x03\x2b\x15\x22\x2a\x01",
|
||||
/*3d*/ 0,
|
||||
/*3e INFO_RESP*/ (unsigned char*)"\x03\x01",
|
||||
/*3f FACILITY_RESP*/ (unsigned char*)"\x03\x20\x1f\x01",
|
||||
/*40*/ 0,
|
||||
/*41 CONNECT_B3_RESP*/ (unsigned char*)"\x03\x2f\x2c\x01",
|
||||
/*42 CONNECT_B3_ACTIVE_RESP*/ (unsigned char*)"\x03\x01",
|
||||
/*43 DISCONNECT_B3_RESP*/ (unsigned char*)"\x03\x01",
|
||||
/*44*/ 0,
|
||||
/*45 DATA_B3_RESP*/ (unsigned char*)"\x03\x19\x01",
|
||||
/*46 RESET_B3_RESP*/ (unsigned char*)"\x03\x01",
|
||||
/*47 CONNECT_B3_T90_ACTIVE_RESP*/ (unsigned char*)"\x03\x01",
|
||||
/*48*/ 0,
|
||||
/*49*/ 0,
|
||||
/*4a*/ 0,
|
||||
/*4b*/ 0,
|
||||
/*4c*/ 0,
|
||||
/*4d*/ 0,
|
||||
/*4e MANUFACTURER_RESP*/ (unsigned char*)"\x03\x2b\x15\x22\x2a\x01",
|
||||
};
|
||||
|
||||
#define TYP (cdef[cmsg->par[cmsg->p]].typ)
|
||||
|
||||
#define byteTLcpy(x,y) *(_cbyte *)(x)=*(_cbyte *)(y);
|
||||
#define wordTLcpy(x,y) *(_cword *)(x)=*(_cword *)(y);
|
||||
#define dwordTLcpy(x,y) memcpy(x,y,4);
|
||||
#define structTLcpy(x,y,l) memcpy (x,y,l)
|
||||
#define structTLcpyovl(x,y,l) memmove (x,y,l)
|
||||
|
||||
#define byteTRcpy(x,y) *(_cbyte *)(y)=*(_cbyte *)(x);
|
||||
#define wordTRcpy(x,y) *(_cword *)(y)=*(_cword *)(x);
|
||||
#define dwordTRcpy(x,y) memcpy(y,x,4);
|
||||
#define structTRcpy(x,y,l) memcpy (y,x,l)
|
||||
#define structTRcpyovl(x,y,l) memmove (y,x,l)
|
||||
|
||||
static unsigned command_2_index (unsigned c, unsigned sc) {
|
||||
if (c & 0x80) c = 0x9+(c&0x0f);
|
||||
else if (c<=0x0f) ;
|
||||
else if (c==0x41) c = 0x9+0x1;
|
||||
else if (c==0xff) c = 0x00;
|
||||
return (sc&3)*(0x9+0x9)+c;
|
||||
}
|
||||
|
||||
#define OFF (((char *)cmsg)+cdef[cmsg->par[cmsg->p]].off)
|
||||
|
||||
static void jumpcstruct (_cmsg *cmsg) {
|
||||
unsigned layer;
|
||||
for (cmsg->p++,layer=1; layer;) {
|
||||
assert (cmsg->p);
|
||||
cmsg->p++;
|
||||
switch (TYP) {
|
||||
case _CMSTRUCT:
|
||||
layer++;
|
||||
break;
|
||||
case _CEND:
|
||||
layer--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *pnames[] = {
|
||||
/*00*/0,
|
||||
/*01*/0,
|
||||
/*02*/0,
|
||||
/*03*/"Controller/PLCI/NCCI",
|
||||
/*04*/"AdditionalInfo",
|
||||
/*05*/"B1configuration",
|
||||
/*06*/"B1protocol",
|
||||
/*07*/"B2configuration",
|
||||
/*08*/"B2protocol",
|
||||
/*09*/"B3configuration",
|
||||
/*0a*/"B3protocol",
|
||||
/*0b*/"BC",
|
||||
/*0c*/"BChannelinformation",
|
||||
/*0d*/"BProtocol",
|
||||
/*0e*/"CalledPartyNumber",
|
||||
/*0f*/"CalledPartySubaddress",
|
||||
/*10*/"CallingPartyNumber",
|
||||
/*11*/"CallingPartySubaddress",
|
||||
/*12*/"CIPmask",
|
||||
/*13*/"CIPmask2",
|
||||
/*14*/"CIPValue",
|
||||
/*15*/"Class",
|
||||
/*16*/"ConnectedNumber",
|
||||
/*17*/"ConnectedSubaddress",
|
||||
/*18*/"Data",
|
||||
/*19*/"DataHandle",
|
||||
/*1a*/"DataLength",
|
||||
/*1b*/"FacilityConfirmationParameter",
|
||||
/*1c*/"Facilitydataarray",
|
||||
/*1d*/"FacilityIndicationParameter",
|
||||
/*1e*/"FacilityRequestParameter",
|
||||
/*1f*/"FacilityResponseParameters",
|
||||
/*20*/"FacilitySelector",
|
||||
/*21*/"Flags",
|
||||
/*22*/"Function",
|
||||
/*23*/"HLC",
|
||||
/*24*/"Info",
|
||||
/*25*/"InfoElement",
|
||||
/*26*/"InfoMask",
|
||||
/*27*/"InfoNumber",
|
||||
/*28*/"Keypadfacility",
|
||||
/*29*/"LLC",
|
||||
/*2a*/"ManuData",
|
||||
/*2b*/"ManuID",
|
||||
/*2c*/"NCPI",
|
||||
/*2d*/"Reason",
|
||||
/*2e*/"Reason_B3",
|
||||
/*2f*/"Reject",
|
||||
/*30*/"Useruserdata",
|
||||
};
|
||||
|
||||
static char *mnames[] = {
|
||||
0,
|
||||
"ALERT_REQ",
|
||||
"CONNECT_REQ",
|
||||
0,
|
||||
"DISCONNECT_REQ",
|
||||
"LISTEN_REQ",
|
||||
0,
|
||||
0,
|
||||
"INFO_REQ",
|
||||
"FACILITY_REQ",
|
||||
"SELECT_B_PROTOCOL_REQ",
|
||||
"CONNECT_B3_REQ",
|
||||
0,
|
||||
"DISCONNECT_B3_REQ",
|
||||
0,
|
||||
"DATA_B3_REQ",
|
||||
"RESET_B3_REQ",
|
||||
0,
|
||||
0,
|
||||
"ALERT_CONF",
|
||||
"CONNECT_CONF",
|
||||
0,
|
||||
"DISCONNECT_CONF",
|
||||
"LISTEN_CONF",
|
||||
"MANUFACTURER_REQ",
|
||||
0,
|
||||
"INFO_CONF",
|
||||
"FACILITY_CONF",
|
||||
"SELECT_B_PROTOCOL_CONF",
|
||||
"CONNECT_B3_CONF",
|
||||
0,
|
||||
"DISCONNECT_B3_CONF",
|
||||
0,
|
||||
"DATA_B3_CONF",
|
||||
"RESET_B3_CONF",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"CONNECT_IND",
|
||||
"CONNECT_ACTIVE_IND",
|
||||
"DISCONNECT_IND",
|
||||
0,
|
||||
"MANUFACTURER_CONF",
|
||||
0,
|
||||
"INFO_IND",
|
||||
"FACILITY_IND",
|
||||
0,
|
||||
"CONNECT_B3_IND",
|
||||
"CONNECT_B3_ACTIVE_IND",
|
||||
"DISCONNECT_B3_IND",
|
||||
0,
|
||||
"DATA_B3_IND",
|
||||
"RESET_B3_IND",
|
||||
"CONNECT_B3_T90_ACTIVE_IND",
|
||||
0,
|
||||
0,
|
||||
"CONNECT_RESP",
|
||||
"CONNECT_ACTIVE_RESP",
|
||||
"DISCONNECT_RESP",
|
||||
0,
|
||||
"MANUFACTURER_IND",
|
||||
0,
|
||||
"INFO_RESP",
|
||||
"FACILITY_RESP",
|
||||
0,
|
||||
"CONNECT_B3_RESP",
|
||||
"CONNECT_B3_ACTIVE_RESP",
|
||||
"DISCONNECT_B3_RESP",
|
||||
0,
|
||||
"DATA_B3_RESP",
|
||||
"RESET_B3_RESP",
|
||||
"CONNECT_B3_T90_ACTIVE_RESP",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"MANUFACTURER_RESP"
|
||||
};
|
||||
|
||||
static void (*signal)(char *, CAPI_PROTOCOL_TYP, CAPI_MESSAGE);
|
||||
static char *buf=0, *p=0;
|
||||
/*-------------------------------------------------------*/
|
||||
void bufprint (char *fmt, ...) {
|
||||
va_list f;
|
||||
va_start (f,fmt);
|
||||
vsprintf (p,fmt,f);
|
||||
va_end (f);
|
||||
p+=strlen(p);
|
||||
}
|
||||
|
||||
static void printstructlen (_cbyte *m, unsigned len) {
|
||||
unsigned hex = 0;
|
||||
for (;len;len--,m++)
|
||||
if (isalnum (*m) | *m == ' ') {
|
||||
if (hex)
|
||||
bufprint (">");
|
||||
bufprint ("%c", *m);
|
||||
hex = 0;
|
||||
}
|
||||
else {
|
||||
if (!hex)
|
||||
bufprint ("<%02x", *m);
|
||||
else
|
||||
bufprint (" %02x", *m);
|
||||
hex = 1;
|
||||
}
|
||||
if (hex)
|
||||
bufprint (">");
|
||||
}
|
||||
|
||||
static void printstruct (_cbyte *m) {
|
||||
unsigned len;
|
||||
if (m[0] != 0xff) {
|
||||
len = m[0];
|
||||
m+=1;
|
||||
}
|
||||
else {
|
||||
len = ((_cword *)(m+1))[0];
|
||||
m+=3;
|
||||
}
|
||||
printstructlen (m, len);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------*/
|
||||
#define NAME (pnames[cmsg->par[cmsg->p]])
|
||||
|
||||
static void PROTOCOL_MESSAGE_2_PARS (_cmsg *cmsg, int level) {
|
||||
for (;TYP != _CEND; cmsg->p++) {
|
||||
int slen = 29+3-level;
|
||||
int i;
|
||||
|
||||
bufprint (" ");
|
||||
for (i=0; i<level-1; i++) bufprint (" ");
|
||||
|
||||
switch (TYP) {
|
||||
case _CBYTE:
|
||||
bufprint ("%-*s = 0x%02x\n", slen, NAME, *(_cbyte *)(cmsg->m+cmsg->l));
|
||||
cmsg->l++;
|
||||
break;
|
||||
case _CWORD:
|
||||
bufprint ("%-*s = 0x%04x\n", slen, NAME, *(_cword *)(cmsg->m+cmsg->l));
|
||||
cmsg->l+=2;
|
||||
break;
|
||||
case _CDWORD:
|
||||
if (strcmp(NAME,"Data")==0) {
|
||||
bufprint ("%-*s = ", slen, NAME);
|
||||
printstructlen ((_cbyte *)*(_cdword *)(cmsg->m+cmsg->l),
|
||||
*(_cword *)(cmsg->m+cmsg->l+sizeof(_cdword)));
|
||||
bufprint ("\n");
|
||||
}
|
||||
else
|
||||
bufprint ("%-*s = 0x%08lx\n", slen, NAME, *(_cdword *)(cmsg->m+cmsg->l));
|
||||
cmsg->l+=4;
|
||||
break;
|
||||
case _CSTRUCT:
|
||||
bufprint ("%-*s = ", slen, NAME);
|
||||
if (cmsg->m[cmsg->l]=='\0')
|
||||
bufprint ("default");
|
||||
else
|
||||
printstruct (cmsg->m+cmsg->l);
|
||||
bufprint ("\n");
|
||||
if (cmsg->m[cmsg->l] != 0xff)
|
||||
cmsg->l+= 1+ cmsg->m[cmsg->l];
|
||||
else
|
||||
cmsg->l+= 3+ *(_cword *)(cmsg->m+cmsg->l+1);
|
||||
|
||||
break;
|
||||
|
||||
case _CMSTRUCT:
|
||||
/*----- Metastruktur 0 -----*/
|
||||
if (cmsg->m[cmsg->l] == '\0') {
|
||||
bufprint ("%-*s = default\n", slen, NAME);
|
||||
cmsg->l++;
|
||||
jumpcstruct (cmsg);
|
||||
}
|
||||
else {
|
||||
char *name = NAME;
|
||||
unsigned _l = cmsg->l;
|
||||
bufprint ("%-*s\n", slen, name);
|
||||
cmsg->l = (cmsg->m+_l)[0] == 255 ? cmsg->l+3 : cmsg->l+1;
|
||||
cmsg->p++;
|
||||
PROTOCOL_MESSAGE_2_PARS (cmsg, level+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------*/
|
||||
#ifndef NOCLOCK
|
||||
#include <time.h>
|
||||
#endif
|
||||
void CAPI_PROTOCOL_INIT(char *_buf, void (*_signal)(char *, CAPI_PROTOCOL_TYP, CAPI_MESSAGE)) {
|
||||
|
||||
#ifndef NOCLOCK
|
||||
time_t ltime;
|
||||
char *date;
|
||||
#endif
|
||||
|
||||
buf = _buf;
|
||||
signal = _signal;
|
||||
p = buf; p[0]=0;
|
||||
if (buf==NULL||signal==NULL) return;
|
||||
|
||||
bufprint ("+---------------------------------------------------------------------\n");
|
||||
bufprint ("| COMMON-ISDN-API Development Kit AVM-Berlin Version 2.0\n");
|
||||
bufprint ("|\n");
|
||||
#ifndef NOCLOCK
|
||||
time (<ime);
|
||||
date = ctime (<ime);
|
||||
date[24]='\0';
|
||||
bufprint ("|%*s\n", 69/2 + strlen(date)/2, date);
|
||||
#endif
|
||||
bufprint ("+---------------------------------------------------------------------\n");
|
||||
(*signal)(buf, CAPI_PROTOCOL_HEADER, NULL);
|
||||
p = buf;
|
||||
p[0]=0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------*/
|
||||
void CAPI_PROTOCOL_TEXT (char *fmt, ...) {
|
||||
va_list f;
|
||||
if (buf==NULL||signal==NULL) return;
|
||||
p = buf; p[0]=0;
|
||||
va_start (f,fmt);
|
||||
vsprintf (p,fmt,f);
|
||||
va_end (f);
|
||||
(*signal)(p, CAPI_PROTOCOL_TXT, NULL);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------*/
|
||||
void CAPI_PROTOCOL_MESSAGE (CAPI_MESSAGE msg) {
|
||||
|
||||
#ifndef NOCLOCK
|
||||
clock_t lclock;
|
||||
#endif
|
||||
_cmsg cmsg;
|
||||
p = buf;
|
||||
if (buf==NULL || signal==NULL) return;
|
||||
p[0]=0;
|
||||
|
||||
cmsg.m = msg;
|
||||
cmsg.l = 8;
|
||||
cmsg.p = 0;
|
||||
byteTRcpy (cmsg.m+4, &cmsg.Command);
|
||||
byteTRcpy (cmsg.m+5, &cmsg.Subcommand);
|
||||
cmsg.par = cpars [command_2_index (cmsg.Command,cmsg.Subcommand)];
|
||||
|
||||
#ifndef NOCLOCK
|
||||
lclock = clock();
|
||||
bufprint ("\n%-26s ID=%03d #0x%04x LEN=%04d %02ld:%02ld:%02ld:%02ld\n",
|
||||
mnames[command_2_index (cmsg.Command,cmsg.Subcommand)],
|
||||
((unsigned short *)msg)[1],
|
||||
((unsigned short *)msg)[3],
|
||||
((unsigned short *)msg)[0],
|
||||
(lclock / CLOCKS_PER_SEC / 60l / 60l),
|
||||
(lclock / CLOCKS_PER_SEC / 60) % 60l,
|
||||
(lclock / CLOCKS_PER_SEC) % 60l,
|
||||
((lclock) % CLOCKS_PER_SEC) / 10);
|
||||
#else
|
||||
bufprint ("\n%-26s ID=%03d #0x%04x LEN=%04d\n",
|
||||
mnames[command_2_index (cmsg.Command,cmsg.Subcommand)],
|
||||
((unsigned short *)msg)[1],
|
||||
((unsigned short *)msg)[3],
|
||||
((unsigned short *)msg)[0]);
|
||||
#endif
|
||||
|
||||
PROTOCOL_MESSAGE_2_PARS (&cmsg, 1);
|
||||
(*signal)(buf, CAPI_PROTOCOL_MSG, msg);
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
timestamp
|
Loading…
Reference in New Issue