summaryrefslogtreecommitdiffstats
path: root/hdlcutil
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-04-21 09:51:03 +0200
committerRalf Baechle <ralf@linux-mips.org>1999-04-21 09:51:03 +0200
commit17287576555a5c46fa23549e2e5f073660dccb70 (patch)
tree08be5f5005dad609a2803758b8b825170f6701cb /hdlcutil
Import ax25-tools 0.0.1 from tarballax25-tools-0.0.1
Diffstat (limited to 'hdlcutil')
-rw-r--r--hdlcutil/Makefile.am31
-rw-r--r--hdlcutil/Makefile.in403
-rw-r--r--hdlcutil/hdrvcomm.c663
-rw-r--r--hdlcutil/hdrvcomm.h109
-rw-r--r--hdlcutil/setcrystal.c136
-rw-r--r--hdlcutil/sethdlc.c598
-rw-r--r--hdlcutil/smdiag.c434
-rw-r--r--hdlcutil/smmixer.c781
-rw-r--r--hdlcutil/usersmdiag.h118
9 files changed, 3273 insertions, 0 deletions
diff --git a/hdlcutil/Makefile.am b/hdlcutil/Makefile.am
new file mode 100644
index 0000000..32059d1
--- /dev/null
+++ b/hdlcutil/Makefile.am
@@ -0,0 +1,31 @@
+
+installconf:
+
+sbin_PROGRAMS = setcrystal sethdlc smmixer smdiag
+
+man_MANS = sethdlc.8 smdiag.8 smmixer.8 baycom.9 hdlcdrv.9 soundmodem.9
+
+setcrystal_SOURCES = \
+ setcrystal.c
+
+sethdlc_SOURCES = \
+ sethdlc.c \
+ hdrvcomm.c \
+ hdrvcomm.h \
+ usersmdiag.h
+
+smmixer_SOURCES = \
+ smmixer.c \
+ hdrvcomm.c \
+ hdrvcomm.h \
+ usersmdiag.h
+
+smdiag_SOURCES = \
+ smdiag.c \
+ hdrvcomm.c \
+ hdrvcomm.h \
+ usersmdiag.h
+
+smdiag_LDADD = \
+ $(X_LIBS) \
+ -lX11
diff --git a/hdlcutil/Makefile.in b/hdlcutil/Makefile.in
new file mode 100644
index 0000000..edf7170
--- /dev/null
+++ b/hdlcutil/Makefile.in
@@ -0,0 +1,403 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 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 = @SHELL@
+
+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
+
+DESTDIR =
+
+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@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+AWK = @AWK@
+CC = @CC@
+MAKEINFO = @MAKEINFO@
+NCURSES_LIB = @NCURSES_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+sbin_PROGRAMS = setcrystal sethdlc smmixer smdiag
+
+man_MANS = sethdlc.8 smdiag.8 smmixer.8 baycom.9 hdlcdrv.9 soundmodem.9
+
+setcrystal_SOURCES = setcrystal.c
+
+
+sethdlc_SOURCES = sethdlc.c hdrvcomm.c hdrvcomm.h usersmdiag.h
+
+
+smmixer_SOURCES = smmixer.c hdrvcomm.c hdrvcomm.h usersmdiag.h
+
+
+smdiag_SOURCES = smdiag.c hdrvcomm.c hdrvcomm.h usersmdiag.h
+
+
+smdiag_LDADD = $(X_LIBS) -lX11
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(sbin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+setcrystal_OBJECTS = setcrystal.o
+setcrystal_LDADD = $(LDADD)
+setcrystal_DEPENDENCIES =
+setcrystal_LDFLAGS =
+sethdlc_OBJECTS = sethdlc.o hdrvcomm.o
+sethdlc_LDADD = $(LDADD)
+sethdlc_DEPENDENCIES =
+sethdlc_LDFLAGS =
+smmixer_OBJECTS = smmixer.o hdrvcomm.o
+smmixer_LDADD = $(LDADD)
+smmixer_DEPENDENCIES =
+smmixer_LDFLAGS =
+smdiag_OBJECTS = smdiag.o hdrvcomm.o
+smdiag_DEPENDENCIES =
+smdiag_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man8dir = $(mandir)/man8
+man9dir = $(mandir)/man9
+MANS = $(man_MANS)
+
+NROFF = nroff
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(setcrystal_SOURCES) $(sethdlc_SOURCES) $(smmixer_SOURCES) $(smdiag_SOURCES)
+OBJECTS = $(setcrystal_OBJECTS) $(sethdlc_OBJECTS) $(smmixer_OBJECTS) $(smdiag_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps hdlcutil/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-sbinPROGRAMS:
+
+clean-sbinPROGRAMS:
+ -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
+
+distclean-sbinPROGRAMS:
+
+maintainer-clean-sbinPROGRAMS:
+
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(sbindir)
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+.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:
+
+setcrystal: $(setcrystal_OBJECTS) $(setcrystal_DEPENDENCIES)
+ @rm -f setcrystal
+ $(LINK) $(setcrystal_LDFLAGS) $(setcrystal_OBJECTS) $(setcrystal_LDADD) $(LIBS)
+
+sethdlc: $(sethdlc_OBJECTS) $(sethdlc_DEPENDENCIES)
+ @rm -f sethdlc
+ $(LINK) $(sethdlc_LDFLAGS) $(sethdlc_OBJECTS) $(sethdlc_LDADD) $(LIBS)
+
+smmixer: $(smmixer_OBJECTS) $(smmixer_DEPENDENCIES)
+ @rm -f smmixer
+ $(LINK) $(smmixer_LDFLAGS) $(smmixer_OBJECTS) $(smmixer_LDADD) $(LIBS)
+
+smdiag: $(smdiag_OBJECTS) $(smdiag_DEPENDENCIES)
+ @rm -f smdiag
+ $(LINK) $(smdiag_LDFLAGS) $(smdiag_OBJECTS) $(smdiag_LDADD) $(LIBS)
+
+install-man8:
+ $(mkinstalldirs) $(DESTDIR)$(man8dir)
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
+ done
+
+uninstall-man8:
+ @list='$(man8_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man8dir)/$$inst; \
+ done
+
+install-man9:
+ $(mkinstalldirs) $(DESTDIR)$(man9dir)
+ @list='$(man9_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.9*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man9dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man9dir)/$$inst; \
+ done
+
+uninstall-man9:
+ @list='$(man9_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.9*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man9dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man9dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man8 install-man9
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man8 uninstall-man9
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(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)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = hdlcutil
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+hdrvcomm.o: hdrvcomm.c hdrvcomm.h usersmdiag.h
+setcrystal.o: setcrystal.c
+sethdlc.o: sethdlc.c hdrvcomm.h
+smdiag.o: smdiag.c hdrvcomm.h
+smmixer.o: smmixer.c hdrvcomm.h
+
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-sbinPROGRAMS
+install-exec: install-exec-am
+
+install-data-am: install-man
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-sbinPROGRAMS uninstall-man
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) $(MANS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8 \
+ $(DESTDIR)$(mandir)/man9
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-sbinPROGRAMS mostlyclean-compile \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-sbinPROGRAMS clean-compile clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-sbinPROGRAMS distclean-compile distclean-tags \
+ distclean-generic clean-am
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-sbinPROGRAMS \
+ maintainer-clean-compile maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS \
+clean-sbinPROGRAMS maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \
+install-sbinPROGRAMS mostlyclean-compile distclean-compile \
+clean-compile maintainer-clean-compile install-man8 uninstall-man8 \
+install-man9 uninstall-man9 install-man uninstall-man tags \
+mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \
+distdir info-am info dvi-am dvi check check-am installcheck-am \
+installcheck install-exec-am install-exec install-data-am install-data \
+install-am install uninstall-am uninstall all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+installconf:
+
+# 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:
diff --git a/hdlcutil/hdrvcomm.c b/hdlcutil/hdrvcomm.c
new file mode 100644
index 0000000..55f0f38
--- /dev/null
+++ b/hdlcutil/hdrvcomm.c
@@ -0,0 +1,663 @@
+/*****************************************************************************/
+
+/*
+ * hdrvcomm.c -- HDLC driver communications.
+ *
+ * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Please note that the GPL allows you to use the driver, NOT the radio.
+ * In order to use the radio, you need a license from the communications
+ * authority of your country.
+ *
+ *
+ * History:
+ * 0.1 10.5.97 Started
+ */
+
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <asm/byteorder.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+/*#include <linux/if.h>*/
+#include <net/if.h>
+#include "hdrvcomm.h"
+#include "usersmdiag.h"
+
+#include <linux/hdlcdrv.h>
+/* ---------------------------------------------------------------------- */
+
+#ifdef HDRVC_KERNEL
+static int kernel_mode = 1;
+#endif /* HDRVC_KERNEL */
+static char *if_name = "bc0";
+static char *prg_name;
+static int fd = -1;
+static struct ifreq ifr_h;
+static int promisc = 0;
+static int msqid = -1;
+
+/* ---------------------------------------------------------------------- */
+
+static void terminate(void)
+{
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ if (ioctl(fd, SIOCSIFFLAGS, &ifr_h) < 0) {
+ perror("ioctl (SIOCSIFFLAGS)");
+ exit(1);
+ }
+ }
+#endif /* HDRVC_KERNEL */
+ exit(0);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void terminate_sig(int signal)
+{
+ printf("signal %i caught\n", signal);
+ terminate();
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_recvpacket(char *pkt, int maxlen)
+{
+ struct ifreq ifr_new;
+ struct sockaddr from;
+ int from_len = sizeof(from);
+
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ if (!promisc) {
+ struct sockaddr sa;
+
+ strcpy(sa.sa_data, if_name);
+ sa.sa_family = AF_INET;
+ if (bind(fd, &sa, sizeof(struct sockaddr)) < 0) {
+ fprintf(stderr, "%s: Error %s (%i) bind failed\n",
+ prg_name, strerror(errno), errno);
+ exit(-2);
+ }
+ ifr_new = ifr_h;
+ ifr_new.ifr_flags |= IFF_PROMISC;
+ if (ioctl(fd, SIOCSIFFLAGS, &ifr_new) < 0) {
+ perror("ioctl (SIOCSIFFLAGS)");
+ exit(1);
+ }
+ signal(SIGTERM, terminate_sig);
+ signal(SIGQUIT, terminate_sig);
+ if (atexit((void (*)(void))terminate)) {
+ perror("atexit");
+ terminate();
+ }
+ promisc = 1;
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
+ }
+ if (!pkt || maxlen < 2)
+ return 0;
+ return recvfrom(fd, pkt, maxlen, 0, &from, &from_len);
+ }
+#endif /* HDRVC_KERNEL */
+ return -1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_getfd(void)
+{
+ return fd;
+}
+
+/* ---------------------------------------------------------------------- */
+
+char *hdrvc_ifname(void)
+{
+ return if_name;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void hdrvc_args(int *argc, char *argv[], char *def_if)
+{
+ int ac, i;
+
+ if (def_if)
+ if_name = def_if;
+ if (!argc || !argv || (ac = *argc) < 1)
+ return;
+ prg_name = argv[0];
+ for (i = 1; i < ac-1; i++) {
+#ifdef HDRVC_KERNEL
+ if (!strcmp(argv[i], "-i")) {
+ kernel_mode = 1;
+ if_name = argv[i+1];
+ ac -= 2;
+ if (i < ac)
+ memmove(argv+i, argv+i+2, (ac-i) * sizeof(void *));
+ i--;
+ } else
+#endif /* HDRVC_KERNEL */
+ if (!strcmp(argv[i], "-u")) {
+#ifdef HDRVC_KERNEL
+ kernel_mode = 0;
+#endif /* HDRVC_KERNEL */
+ if_name = argv[i+1];
+ ac -= 2;
+ if (i < ac)
+ memmove(argv+i, argv+i+2, (ac-i) * sizeof(void *));
+ i--;
+ }
+ }
+ *argc = ac;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void hdrvc_init(void)
+{
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ if ((fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_AX25))) < 0) {
+ fprintf(stderr, "%s: Error %s (%i), cannot open %s\n", prg_name,
+ strerror(errno), errno, if_name);
+ exit(-1);
+ }
+ strcpy(ifr_h.ifr_name, if_name);
+ if (ioctl(fd, SIOCGIFFLAGS, &ifr_h) < 0) {
+ fprintf(stderr, "%s: Error %s (%i), cannot ioctl %s\n", prg_name,
+ strerror(errno), errno, if_name);
+ exit(-1);
+ }
+ } else
+#endif /* HDRVC_KERNEL */
+ {
+ key_t k = ftok(if_name, USERSM_KEY_PROJ);
+
+ if (k == (key_t)-1) {
+ fprintf(stderr, "%s: Error %s (%i), cannot ftok on %s\n", prg_name,
+ strerror(errno), errno, if_name);
+ exit(-1);
+ }
+ if ((msqid = msgget(k, 0700)) < 0) {
+ fprintf(stderr, "%s: Error %s (%i), cannot msgget %d\n", prg_name,
+ strerror(errno), errno, k);
+ exit(-1);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+extern __inline__ void hdrvc_sendmsg(struct usersmmsg *msg, int len)
+{
+ if (msgsnd(msqid, (struct msgbuf *)msg, len+sizeof(msg->hdr)-sizeof(long), 0) < 0) {
+ perror("msgsnd");
+ exit(1);
+ }
+}
+
+extern __inline__ int hdrvc_recvmsg(struct usersmmsg *msg, int maxlen, long type)
+{
+ int len;
+
+ if ((len = msgrcv(msqid, (struct msgbuf *)msg, maxlen-sizeof(long), type, MSG_NOERROR)) < 0) {
+ perror("msgrcv");
+ exit(1);
+ }
+#if 0
+ for (;;) {
+ if ((len = msgrcv(msqid, (struct msgbuf *)msg, maxlen-sizeof(long), type, IPC_NOWAIT|MSG_NOERROR)) >= 0)
+ return len+sizeof(long);
+ if (errno != ENOMSG) {
+ perror("msgrcv");
+ exit(1);
+ }
+ usleep(250000);
+ }
+#endif
+ return len+sizeof(long);
+}
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef HDRVC_KERNEL
+
+int hdrvc_hdlcdrv_ioctl(int cmd, struct hdlcdrv_ioctl *par)
+{
+ struct ifreq ifr = ifr_h;
+
+ if (!kernel_mode) {
+ errno = EINVAL;
+ return -1;
+ }
+ ifr.ifr_data = (caddr_t)par;
+ par->cmd = cmd;
+ return ioctl(fd, SIOCDEVPRIVATE, &ifr);
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_sm_ioctl(int cmd, struct sm_ioctl *par)
+{
+ struct ifreq ifr = ifr_h;
+
+ if (!kernel_mode) {
+ errno = EINVAL;
+ return -1;
+ }
+ ifr.ifr_data = (caddr_t)par;
+ par->cmd = cmd;
+ return ioctl(fd, SIOCDEVPRIVATE, &ifr);
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_baycom_ioctl(int cmd, struct baycom_ioctl *par)
+{
+ struct ifreq ifr = ifr_h;
+
+ if (!kernel_mode) {
+ errno = EINVAL;
+ return -1;
+ }
+ ifr.ifr_data = (caddr_t)par;
+ par->cmd = cmd;
+ return ioctl(fd, SIOCDEVPRIVATE, &ifr);
+}
+
+/* ---------------------------------------------------------------------- */
+
+unsigned int hdrvc_get_ifflags(void)
+{
+ struct ifreq ifr;
+
+ if (kernel_mode) {
+ memcpy(&ifr, &ifr_h, sizeof(ifr));
+ if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
+ perror("ioctl: SIOCGIFFLAGS");
+ exit(-1);
+ }
+ return ifr.ifr_flags;
+ }
+ return IFF_UP | IFF_RUNNING;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_diag(struct sm_diag_data *diag)
+{
+ struct sm_ioctl smi;
+ int ret;
+ struct usersmmsg msg;
+
+ if (!diag) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (kernel_mode) {
+ memcpy(&smi.data.diag, diag, sizeof(smi.data.diag));
+ ret = hdrvc_sm_ioctl(SMCTL_DIAGNOSE, &smi);
+ memcpy(diag, &smi.data.diag, sizeof(smi.data.diag));
+ return ret;
+ }
+ msg.hdr.type = USERSM_CMD_REQ_DIAG;
+ msg.hdr.channel = 0;
+ msg.data.diag.mode = diag->mode;
+ msg.data.diag.flags = diag->flags;
+ msg.data.diag.samplesperbit = diag->samplesperbit;
+ msg.data.diag.datalen = diag->datalen;
+ hdrvc_sendmsg(&msg, sizeof(msg.data.diag));
+ ret = hdrvc_recvmsg(&msg, sizeof(msg), USERSM_CMD_ACK_DIAG);
+ if (ret < 0)
+ return ret;
+ if (ret < sizeof(msg.data.diag) || ret < sizeof(msg.data.diag)+msg.data.diag.datalen*sizeof(short)) {
+ errno = EIO;
+ return -1;
+ }
+ diag->mode = msg.data.diag.mode;
+ diag->flags = msg.data.diag.flags;
+ diag->samplesperbit = msg.data.diag.samplesperbit;
+ diag->datalen = msg.data.diag.datalen;
+ memcpy(diag->data, msg.data.diag_out.samples, msg.data.diag.datalen*sizeof(short));
+ return 0;
+}
+
+#endif /* HDRVC_KERNEL */
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_get_samples(void)
+{
+ int ret;
+ struct hdlcdrv_ioctl bi;
+
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_GETSAMPLES, &bi);
+ if (ret < 0)
+ return ret;
+ return bi.data.bits & 0xff;
+ }
+#endif /* HDRVC_KERNEL */
+ errno = EAGAIN;
+ return -1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_get_bits(void)
+{
+ int ret;
+ struct hdlcdrv_ioctl bi;
+
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_GETBITS, &bi);
+ if (ret < 0)
+ return ret;
+ return bi.data.bits & 0xff;
+ }
+#endif /* HDRVC_KERNEL */
+ errno = EAGAIN;
+ return -1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_get_channel_access_param(struct hdrvc_channel_params *par)
+{
+ struct hdlcdrv_ioctl hi;
+ int ret;
+ struct usersmmsg msg;
+
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ if ((ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_GETCHANNELPAR, &hi)) < 0)
+ return ret;
+ if (!par) {
+ errno = EINVAL;
+ return -1;
+ }
+ par->tx_delay = hi.data.cp.tx_delay;
+ par->tx_tail = hi.data.cp.tx_tail;
+ par->slottime = hi.data.cp.slottime;
+ par->ppersist = hi.data.cp.ppersist;
+ par->fulldup = hi.data.cp.fulldup;
+ return 0;
+ }
+#endif /* HDRVC_KERNEL */
+ msg.hdr.type = USERSM_CMD_REQ_CHACCESS_PAR;
+ msg.hdr.channel = 0;
+ hdrvc_sendmsg(&msg, 0);
+ ret = hdrvc_recvmsg(&msg, sizeof(msg), USERSM_CMD_ACK_CHACCESS_PAR);
+ if (ret < 0)
+ return ret;
+ if (ret < sizeof(msg.data.cp)) {
+ errno = EIO;
+ return -1;
+ }
+ par->tx_delay = msg.data.cp.tx_delay;
+ par->tx_tail = msg.data.cp.tx_tail;
+ par->slottime = msg.data.cp.slottime;
+ par->ppersist = msg.data.cp.ppersist;
+ par->fulldup = msg.data.cp.fulldup;
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_set_channel_access_param(struct hdrvc_channel_params par)
+{
+ int ret;
+ struct usersmmsg msg;
+
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ struct hdlcdrv_ioctl hi;
+
+ hi.data.cp.tx_delay = par.tx_delay;
+ hi.data.cp.tx_tail = par.tx_tail;
+ hi.data.cp.slottime = par.slottime;
+ hi.data.cp.ppersist = par.ppersist;
+ hi.data.cp.fulldup = par.fulldup;
+ if ((ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_SETCHANNELPAR, &hi)) < 0)
+ return ret;
+ return 0;
+ }
+#endif /* HDRVC_KERNEL */
+ msg.hdr.type = USERSM_CMD_SET_CHACCESS_PAR;
+ msg.hdr.channel = 0;
+ msg.data.cp.tx_delay = par.tx_delay;
+ msg.data.cp.tx_tail = par.tx_tail;
+ msg.data.cp.slottime = par.slottime;
+ msg.data.cp.ppersist = par.ppersist;
+ msg.data.cp.fulldup = par.fulldup;
+ hdrvc_sendmsg(&msg, sizeof(msg.data.cp));
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_calibrate(int calib)
+{
+ struct hdlcdrv_ioctl bhi;
+ struct usersmmsg msg;
+
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ bhi.data.calibrate = calib;
+ return hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_CALIBRATE, &bhi);
+ }
+#endif /* HDRVC_KERNEL */
+ msg.hdr.type = USERSM_CMD_CALIBRATE;
+ msg.hdr.channel = 0;
+ msg.data.calib = calib;
+ hdrvc_sendmsg(&msg, sizeof(msg.data.calib));
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_get_channel_state(struct hdrvc_channel_state *st)
+{
+ struct hdlcdrv_ioctl bhi;
+ int ret;
+ struct usersmmsg msg;
+
+ if (!st) {
+ errno = EINVAL;
+ return -1;
+ }
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_GETSTAT, &bhi);
+ if (ret >= 0) {
+ st->ptt = bhi.data.cs.ptt;
+ st->dcd = bhi.data.cs.dcd;
+ st->ptt_keyed = bhi.data.cs.ptt_keyed;
+ st->tx_packets = bhi.data.cs.tx_packets;
+ st->tx_errors = bhi.data.cs.tx_errors;
+ st->rx_packets = bhi.data.cs.rx_packets;
+ st->rx_errors = bhi.data.cs.rx_errors;
+ }
+ return ret;
+ }
+#endif /* HDRVC_KERNEL */
+ msg.hdr.type = USERSM_CMD_REQ_CHANNELSTATE;
+ msg.hdr.channel = 0;
+ hdrvc_sendmsg(&msg, 0);
+ ret = hdrvc_recvmsg(&msg, sizeof(msg), USERSM_CMD_ACK_CHANNELSTATE);
+ if (ret < 0)
+ return ret;
+ if (ret < sizeof(msg.data.cs)) {
+ errno = EIO;
+ return -1;
+ }
+ st->ptt = msg.data.cs.ptt;
+ st->dcd = msg.data.cs.dcd;
+ st->ptt_keyed = msg.data.cs.ptt_keyed;
+ st->tx_packets = msg.data.cs.tx_packets;
+ st->tx_errors = msg.data.cs.tx_errors;
+ st->rx_packets = msg.data.cs.rx_packets;
+ st->rx_errors = msg.data.cs.rx_errors;
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_diag2(unsigned int mode, unsigned int flags, short *data,
+ unsigned int maxdatalen, unsigned int *samplesperbit)
+{
+ int ret;
+ struct usersmmsg msg;
+ static unsigned int modeconvusersm[4] = {
+ USERSM_DIAGMODE_OFF, USERSM_DIAGMODE_INPUT, USERSM_DIAGMODE_DEMOD,
+ USERSM_DIAGMODE_CONSTELLATION
+ };
+
+ if (mode > HDRVC_DIAGMODE_CONSTELLATION) {
+ errno = EINVAL;
+ return -1;
+ }
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ struct sm_ioctl smi;
+ static unsigned int modeconvsm[4] = {
+ SM_DIAGMODE_OFF, SM_DIAGMODE_INPUT, SM_DIAGMODE_DEMOD, SM_DIAGMODE_CONSTELLATION
+ };
+
+ smi.data.diag.mode = modeconvsm[mode];
+ smi.data.diag.flags = (flags & HDRVC_DIAGFLAG_DCDGATE) ? SM_DIAGFLAG_DCDGATE : 0;
+ smi.data.diag.samplesperbit = 0;
+ smi.data.diag.datalen = maxdatalen;
+ smi.data.diag.data = data;
+ if ((ret = hdrvc_sm_ioctl(SMCTL_DIAGNOSE, &smi)) < 0)
+ return ret;
+ if (samplesperbit)
+ *samplesperbit = smi.data.diag.samplesperbit;
+ if (smi.data.diag.mode != modeconvsm[mode] || !(smi.data.diag.flags & SM_DIAGFLAG_VALID))
+ return 0;
+ return smi.data.diag.datalen;
+ }
+#endif /* HDRVC_KERNEL */
+ msg.hdr.type = USERSM_CMD_REQ_DIAG;
+ msg.hdr.channel = 0;
+ msg.data.diag.mode = modeconvusersm[mode];
+ msg.data.diag.flags = (flags & HDRVC_DIAGFLAG_DCDGATE) ? USERSM_DIAGFLAG_DCDGATE : 0;
+ msg.data.diag.samplesperbit = 0;
+ msg.data.diag.datalen = maxdatalen;
+ hdrvc_sendmsg(&msg, sizeof(msg.data.diag));
+ ret = hdrvc_recvmsg(&msg, sizeof(msg), USERSM_CMD_ACK_DIAG);
+ if (ret < 0)
+ return ret;
+ if (ret < sizeof(msg.data.diag) || ret < sizeof(msg.data.diag)+msg.data.diag.datalen*sizeof(short)) {
+ errno = EIO;
+ return -1;
+ }
+ if (samplesperbit)
+ *samplesperbit = msg.data.diag.samplesperbit;
+ if (msg.data.diag.mode != modeconvusersm[mode] || !(msg.data.diag.flags & USERSM_DIAGFLAG_VALID))
+ return 0;
+ if (!data || msg.data.diag.datalen <= 0)
+ return 0;
+ memcpy(data, msg.data.diag_out.samples, msg.data.diag.datalen*sizeof(short));
+ return msg.data.diag.datalen;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_get_driver_name(char *buf, int bufsz)
+{
+ int ret;
+ struct usersmmsg msg;
+
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ struct hdlcdrv_ioctl bhi;
+
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_DRIVERNAME, &bhi);
+ if (ret < 0)
+ return ret;
+ strncpy(buf, bhi.data.modename, bufsz);
+ return 0;
+ }
+#endif /* HDRVC_KERNEL */
+ msg.hdr.type = USERSM_CMD_REQ_DRVNAME;
+ msg.hdr.channel = 0;
+ hdrvc_sendmsg(&msg, 0);
+ ret = hdrvc_recvmsg(&msg, sizeof(msg), USERSM_CMD_ACK_DRVNAME);
+ if (ret < 0)
+ return ret;
+ if (ret < 1) {
+ errno = EIO;
+ return -1;
+ }
+ if (bufsz < ret)
+ ret = bufsz;
+ strncpy(buf, msg.data.by, ret);
+ buf[ret-1] = 0;
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int hdrvc_get_mode_name(char *buf, int bufsz)
+{
+ int ret;
+ struct usersmmsg msg;
+
+#ifdef HDRVC_KERNEL
+ if (kernel_mode) {
+ struct hdlcdrv_ioctl bhi;
+
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_GETMODE, &bhi);
+ if (ret < 0)
+ return ret;
+ strncpy(buf, bhi.data.modename, bufsz);
+ return 0;
+ }
+#endif /* HDRVC_KERNEL */
+ msg.hdr.type = USERSM_CMD_REQ_DRVMODE;
+ msg.hdr.channel = 0;
+ hdrvc_sendmsg(&msg, 0);
+ ret = hdrvc_recvmsg(&msg, sizeof(msg), USERSM_CMD_ACK_DRVMODE);
+ if (ret < 0)
+ return ret;
+ if (ret < 1) {
+ errno = EIO;
+ return -1;
+ }
+ if (bufsz < ret)
+ ret = bufsz;
+ strncpy(buf, msg.data.by, ret);
+ buf[ret-1] = 0;
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
diff --git a/hdlcutil/hdrvcomm.h b/hdlcutil/hdrvcomm.h
new file mode 100644
index 0000000..ec4be73
--- /dev/null
+++ b/hdlcutil/hdrvcomm.h
@@ -0,0 +1,109 @@
+/*****************************************************************************/
+
+/*
+ * hdrvcomm.h -- HDLC driver communications.
+ *
+ * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Please note that the GPL allows you to use the driver, NOT the radio.
+ * In order to use the radio, you need a license from the communications
+ * authority of your country.
+ *
+ */
+
+/*****************************************************************************/
+
+#ifndef _HDRVCOMM_H
+#define _HDRVCOMM_H
+
+/* ---------------------------------------------------------------------- */
+
+#undef HDRVC_KERNEL 1
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef HDRVC_KERNEL
+#include <linux/hdlcdrv.h>
+#include <linux/soundmodem.h>
+#include <linux/baycom.h>
+#endif /* HDRVC_KERNEL */
+
+/* ---------------------------------------------------------------------- */
+
+struct hdrvc_channel_params {
+ int tx_delay; /* the transmitter keyup delay in 10ms units */
+ int tx_tail; /* the transmitter keyoff delay in 10ms units */
+ int slottime; /* the slottime in 10ms; usually 10 = 100ms */
+ int ppersist; /* the p-persistence 0..255 */
+ int fulldup; /* some driver do not support full duplex, setting */
+ /* this just makes them send even if DCD is on */
+};
+
+struct hdrvc_channel_state {
+ int ptt;
+ int dcd;
+ int ptt_keyed;
+ unsigned long tx_packets;
+ unsigned long tx_errors;
+ unsigned long rx_packets;
+ unsigned long rx_errors;
+};
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * diagnose modes
+ */
+#define HDRVC_DIAGMODE_OFF 0
+#define HDRVC_DIAGMODE_INPUT 1
+#define HDRVC_DIAGMODE_DEMOD 2
+#define HDRVC_DIAGMODE_CONSTELLATION 3
+
+/*
+ * diagnose flags
+ */
+#define HDRVC_DIAGFLAG_DCDGATE (1<<0)
+
+
+/* ---------------------------------------------------------------------- */
+
+extern int hdrvc_recvpacket(char *pkt, int maxlen);
+extern int hdrvc_getfd(void);
+extern char *hdrvc_ifname(void);
+extern void hdrvc_args(int *argc, char *argv[], char *def_if);
+extern void hdrvc_init(void);
+extern int hdrvc_get_samples(void);
+extern int hdrvc_get_bits(void);
+extern int hdrvc_get_channel_access_param(struct hdrvc_channel_params *par);
+extern int hdrvc_set_channel_access_param(struct hdrvc_channel_params par);
+extern int hdrvc_calibrate(int calib);
+extern int hdrvc_get_channel_state(struct hdrvc_channel_state *st);
+extern unsigned int hdrvc_get_ifflags(void);
+extern int hdrvc_diag2(unsigned int mode, unsigned int flags, short *data, unsigned int maxdatalen,
+ unsigned int *samplesperbit);
+extern int hdrvc_get_driver_name(char *buf, int bufsz);
+extern int hdrvc_get_mode_name(char *buf, int bufsz);
+
+#ifdef HDRVC_KERNEL
+extern int hdrvc_hdlcdrv_ioctl(int cmd, struct hdlcdrv_ioctl *par);
+extern int hdrvc_sm_ioctl(int cmd, struct sm_ioctl *par);
+extern int hdrvc_baycom_ioctl(int cmd, struct baycom_ioctl *par);
+extern int hdrvc_diag(struct sm_diag_data *diag);
+#endif /* HDRVC_KERNEL */
+
+/* ---------------------------------------------------------------------- */
+#endif /* _HDRVCOMM_H */
diff --git a/hdlcutil/setcrystal.c b/hdlcutil/setcrystal.c
new file mode 100644
index 0000000..f5181f3
--- /dev/null
+++ b/hdlcutil/setcrystal.c
@@ -0,0 +1,136 @@
+/*****************************************************************************/
+
+/*
+ * setcrystal.c -- crystal soundcard configuration utility
+ *
+ * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Please note that the GPL allows you to use the driver, NOT the radio.
+ * In order to use the radio, you need a license from the communications
+ * authority of your country.
+ *
+ */
+
+/* --------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <asm/io.h>
+
+/* --------------------------------------------------------------------- */
+
+static const unsigned char crystal_key[32] = {
+ 0x96, 0x35, 0x9a, 0xcd, 0xe6, 0xf3, 0x79, 0xbc,
+ 0x5e, 0xaf, 0x57, 0x2b, 0x15, 0x8a, 0xc5, 0xe2,
+ 0xf1, 0xf8, 0x7c, 0x3e, 0x9f, 0x4f, 0x27, 0x13,
+ 0x09, 0x84, 0x42, 0xa1, 0xd0, 0x68, 0x34, 0x1a
+};
+
+#define KEY_PORT 0x279
+#define CSN 1 /* card select number */
+
+/* --------------------------------------------------------------------- */
+
+int main(int argc, char *argv[])
+{
+ int wssbase = 0x534;
+ int synbase = 0x388;
+ int sbbase = 0x220;
+ int irq = 5;
+ int dma = 1;
+ int dma2 = 3;
+
+ int i;
+
+ printf("Crystal PnP Soundcard enabler\n"
+ "(C) 1996 by Thomas Sailer, HB9JNX/AE4WA\n"
+ "WARNING: This utility is incompatible with OS PnP support!\n"
+ " Remove it as soon as Linux supports PnP!\n");
+ while ((i = getopt(argc, argv, "i:d:c:s:w:f:h")) != EOF) {
+ switch (i) {
+ case 'i':
+ irq = strtoul(optarg, NULL, 0);
+ break;
+ case 'd':
+ dma = strtoul(optarg, NULL, 0);
+ break;
+ case 'c':
+ dma2 = strtoul(optarg, NULL, 0);
+ break;
+ case 's':
+ sbbase = strtoul(optarg, NULL, 0);
+ break;
+ case 'w':
+ wssbase = strtoul(optarg, NULL, 0);
+ break;
+ case 'f':
+ synbase = strtoul(optarg, NULL, 0);
+ break;
+
+ default:
+ case ':':
+ case '?':
+ case 'h':
+ fprintf(stderr, "usage: [-w wssio] [-s sbio] "
+ "[-f synthio] [-i irq] [-d dma] [-c dma2]\n");
+ exit(1);
+ }
+ }
+
+ if ((i = ioperm(KEY_PORT, 1, 1))) {
+ perror("ioperm");
+ exit(1);
+ }
+ /*
+ * send crystal key
+ */
+ for (i = 0; i < 32; i++)
+ outb(crystal_key[i], KEY_PORT);
+ /*
+ * send config data
+ */
+ outb(0x6, KEY_PORT);
+ outb(CSN, KEY_PORT);
+ outb(0x15, KEY_PORT);
+ outb(0x0, KEY_PORT); /* logical device 0 */
+ outb(0x47, KEY_PORT);
+ outb(wssbase >> 8, KEY_PORT);
+ outb(wssbase & 0xff, KEY_PORT);
+ outb(0x48, KEY_PORT);
+ outb(synbase >> 8, KEY_PORT);
+ outb(synbase & 0xff, KEY_PORT);
+ outb(0x42, KEY_PORT);
+ outb(sbbase >> 8, KEY_PORT);
+ outb(sbbase & 0xff, KEY_PORT);
+ outb(0x22, KEY_PORT);
+ outb(irq, KEY_PORT);
+ outb(0x2a, KEY_PORT);
+ outb(dma, KEY_PORT);
+ outb(0x25, KEY_PORT);
+ outb(dma2, KEY_PORT);
+ outb(0x33, KEY_PORT);
+ outb(0x1, KEY_PORT); /* activate logical device */
+ outb(0x79, KEY_PORT); /* activate part */
+
+ printf("Crystal CS423[26] set to: WSS iobase 0x%x, Synth iobase 0x%x,"
+ " SB iobase 0x%x,\n IRQ %u, DMA %u, DMA2 %u\n", wssbase,
+ synbase, sbbase, irq, dma, dma2);
+ exit(0);
+}
+
+/* --------------------------------------------------------------------- */
diff --git a/hdlcutil/sethdlc.c b/hdlcutil/sethdlc.c
new file mode 100644
index 0000000..b07c0de
--- /dev/null
+++ b/hdlcutil/sethdlc.c
@@ -0,0 +1,598 @@
+/*****************************************************************************/
+
+/*
+ * sethdlc.c -- kernel HDLC radio modem driver setup utility.
+ *
+ * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Please note that the GPL allows you to use the driver, NOT the radio.
+ * In order to use the radio, you need a license from the communications
+ * authority of your country.
+ *
+ *
+ * History:
+ * 0.1 16.10.96 Adapted from setbaycom.c and setsm.c
+ * 0.2 20.11.96 New mode set/query code
+ * 0.5 11.05.97 introduced hdrvcomm.h
+ */
+
+/*****************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+/*#include <linux/if.h>*/
+#include <net/if.h>
+#include "hdrvcomm.h"
+
+#include <linux/soundmodem.h>
+#include <linux/baycom.h>
+
+/* ---------------------------------------------------------------------- */
+
+static unsigned char trace_stat = 0;
+static char *progname;
+
+/* ---------------------------------------------------------------------- */
+
+static void display_packet(unsigned char *bp, unsigned int len)
+{
+ unsigned char v1=1,cmd=0;
+ unsigned char i,j;
+
+ if (!bp || !len)
+ return;
+ if (len < 8)
+ return;
+ if (bp[1] & 1) {
+ /*
+ * FlexNet Header Compression
+ */
+ v1 = 0;
+ cmd = (bp[1] & 2) != 0;
+ printf("fm ? to ");
+ i = (bp[2] >> 2) & 0x3f;
+ if (i)
+ printf("%c",i+0x20);
+ i = ((bp[2] << 4) | ((bp[3] >> 4) & 0xf)) & 0x3f;
+ if (i)
+ printf("%c",i+0x20);
+ i = ((bp[3] << 2) | ((bp[4] >> 6) & 3)) & 0x3f;
+ if (i)
+ printf("%c",i+0x20);
+ i = bp[4] & 0x3f;
+ if (i)
+ printf("%c",i+0x20);
+ i = (bp[5] >> 2) & 0x3f;
+ if (i)
+ printf("%c",i+0x20);
+ i = ((bp[5] << 4) | ((bp[6] >> 4) & 0xf)) & 0x3f;
+ if (i)
+ printf("%c",i+0x20);
+ printf("-%u QSO Nr %u", bp[6] & 0xf, (bp[0] << 6) |
+ (bp[1] >> 2));
+ bp += 7;
+ len -= 7;
+ } else {
+ /*
+ * normal header
+ */
+ if (len < 15)
+ return;
+ if ((bp[6] & 0x80) != (bp[13] & 0x80)) {
+ v1 = 0;
+ cmd = (bp[6] & 0x80);
+ }
+ printf("fm ");
+ for(i = 7; i < 13; i++)
+ if ((bp[i] &0xfe) != 0x40)
+ printf("%c",bp[i] >> 1);
+ printf("-%u to ",(bp[13] >> 1) & 0xf);
+ for(i = 0; i < 6; i++)
+ if ((bp[i] &0xfe) != 0x40)
+ printf("%c", bp[i] >> 1);
+ printf("-%u", (bp[6] >> 1) & 0xf);
+ bp += 14;
+ len -= 14;
+ if ((!(bp[-1] & 1)) && (len >= 7))
+ printf(" via ");
+ while ((!(bp[-1] & 1)) && (len >= 7)) {
+ for(i = 0; i < 6; i++)
+ if ((bp[i] &0xfe) != 0x40)
+ printf("%c",bp[i] >> 1);
+ printf("-%u",(bp[6] >> 1) & 0xf);
+ bp += 7;
+ len -= 7;
+ if ((!(bp[-1] & 1)) && (len >= 7))
+ printf(",");
+ }
+ }
+ if(!len)
+ return;
+ i = *bp++;
+ len--;
+ j = v1 ? ((i & 0x10) ? '!' : ' ') :
+ ((i & 0x10) ? (cmd ? '+' : '-') : (cmd ? '^' : 'v'));
+ if (!(i & 1)) {
+ /*
+ * Info frame
+ */
+ printf(" I%u%u%c",(i >> 5) & 7,(i >> 1) & 7,j);
+ } else if (i & 2) {
+ /*
+ * U frame
+ */
+ switch (i & (~0x10)) {
+ case 0x03:
+ printf(" UI%c",j);
+ break;
+ case 0x2f:
+ printf(" SABM%c",j);
+ break;
+ case 0x43:
+ printf(" DISC%c",j);
+ break;
+ case 0x0f:
+ printf(" DM%c",j);
+ break;
+ case 0x63:
+ printf(" UA%c",j);
+ break;
+ case 0x87:
+ printf(" FRMR%c",j);
+ break;
+ default:
+ printf(" unknown U (0x%x)%c",i & (~0x10),j);
+ break;
+ }
+ } else {
+ /*
+ * supervisory
+ */
+ switch (i & 0xf) {
+ case 0x1:
+ printf(" RR%u%c",(i >> 5) & 7,j);
+ break;
+ case 0x5:
+ printf(" RNR%u%c",(i >> 5) & 7,j);
+ break;
+ case 0x9:
+ printf(" REJ%u%c",(i >> 5) & 7,j);
+ break;
+ default:
+ printf(" unknown S (0x%x)%u%c", i & 0xf,
+ (i >> 5) & 7, j);
+ break;
+ }
+ }
+ if (!len) {
+ printf("\n");
+ return;
+ }
+ printf(" pid=%02X\n", *bp++);
+ len--;
+ j = 0;
+ while (len) {
+ i = *bp++;
+ if ((i >= 32) && (i < 128))
+ printf("%c",i);
+ else if (i == 13) {
+ if (j)
+ printf("\n");
+ j = 0;
+ } else
+ printf(".");
+ if (i >= 32)
+ j = 1;
+ len--;
+ }
+ if (j)
+ printf("\n");
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void print_bits(int (*bitproc)(void))
+{
+ int ret;
+ int i;
+ char str[9];
+ char *cp;
+
+ for(;;) {
+ ret = bitproc();
+ if (ret < 0) {
+ if (errno == EAGAIN)
+ return;
+ fprintf(stderr, "%s: Error %s (%i), cannot ioctl\n",
+ progname, strerror(errno), errno);
+ return;
+ }
+ strcpy(cp = str, "00000000");
+ for(i = 0; i < 8; i++, cp++, ret >>= 1)
+ *cp += (ret & 1);
+ printf("%s", str);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef HDRVC_KERNEL
+
+static void do_set_params(int argc, char **argv)
+{
+ struct hdlcdrv_ioctl drvname, curm, newm, mlist, curp, newp, mpmask;
+ char set = 0;
+ int ret;
+ int mask;
+
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_DRIVERNAME, &drvname);
+ if (ret < 0) {
+ perror("ioctl (HDLCDRVCTL_DRIVERNAME)");
+ exit(1);
+ }
+ printf("driver name: %s\n", drvname.data.drivername);
+
+ mask = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_MODEMPARMASK, &mpmask);
+ if (mask < 0)
+ mask = ~0;
+
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_GETMODEMPAR, &curp);
+ if (ret < 0) {
+ perror("ioctl (HDLCDRVCTL_GETMODEMPAR)");
+ exit(1);
+ }
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_GETMODE, &curm);
+ if (ret < 0) {
+ perror("ioctl (HDLCDRVCTL_GETMODE)");
+ exit(1);
+ }
+ newm = curm;
+ newp = curp;
+ while (argc >= 2) {
+ if (!strcasecmp(argv[0], "mode")) {
+ strncpy(newm.data.modename, argv[1],
+ sizeof(newm.data.modename));
+ set |= 1;
+ } else if (!strcasecmp(argv[0], "io") && mask & HDLCDRV_PARMASK_IOBASE) {
+ newp.data.mp.iobase = strtoul(argv[1], NULL, 0);
+ set |= 2;
+ } else if (!strcasecmp(argv[0], "irq") && mask & HDLCDRV_PARMASK_IRQ) {
+ newp.data.mp.irq = strtoul(argv[1], NULL, 0);
+ set |= 2;
+ } else if (!strcasecmp(argv[0], "dma") && mask & HDLCDRV_PARMASK_DMA) {
+ newp.data.mp.dma = strtoul(argv[1], NULL, 0);
+ set |= 2;
+ } else if (!strcasecmp(argv[0], "dma2") && mask & HDLCDRV_PARMASK_DMA2) {
+ newp.data.mp.dma2 = strtoul(argv[1], NULL, 0);
+ set |= 2;
+ } else if (!strcasecmp(argv[0], "serio") && mask & HDLCDRV_PARMASK_SERIOBASE) {
+ newp.data.mp.seriobase = strtol(argv[1], NULL, 0);
+ set |= 2;
+ } else if (!strcasecmp(argv[0], "pario") && mask & HDLCDRV_PARMASK_PARIOBASE) {
+ newp.data.mp.pariobase = strtol(argv[1], NULL, 0);
+ set |= 2;
+ } else if (!strcasecmp(argv[0], "midiio") && mask & HDLCDRV_PARMASK_MIDIIOBASE) {
+ newp.data.mp.midiiobase = strtol(argv[1], NULL, 0);
+ set |= 2;
+ } else {
+ fprintf(stderr, "%s: invalid parameter type '%s', "
+ "valid: mode%s%s%s%s%s%s%s\n",
+ progname, argv[0],
+ (mask & HDLCDRV_PARMASK_IOBASE) ? " io" : "",
+ (mask & HDLCDRV_PARMASK_IRQ) ? " irq" : "",
+ (mask & HDLCDRV_PARMASK_DMA) ? " dma" : "",
+ (mask & HDLCDRV_PARMASK_DMA2) ? " dma2" : "",
+ (mask & HDLCDRV_PARMASK_SERIOBASE) ? " serio" : "",
+ (mask & HDLCDRV_PARMASK_PARIOBASE) ? " pario" : "",
+ (mask & HDLCDRV_PARMASK_MIDIIOBASE) ? " midiio" : "");
+ }
+ argv += 2;
+ argc -= 2;
+ }
+ if (argc >= 1)
+ fprintf(stderr, "%s: orphaned parameter type '%s', no data\n",
+ progname, argv[0]);
+ printf("current parameters: mode %s", curm.data.modename);
+ if (mask & HDLCDRV_PARMASK_IOBASE)
+ printf(" io 0x%x", curp.data.mp.iobase);
+ if (mask & HDLCDRV_PARMASK_IRQ)
+ printf(" irq %u", curp.data.mp.irq);
+ if (mask & HDLCDRV_PARMASK_DMA)
+ printf(" dma %u", curp.data.mp.dma);
+ if (mask & HDLCDRV_PARMASK_DMA2)
+ printf(" dma2 %u", curp.data.mp.dma2);
+ if (mask & HDLCDRV_PARMASK_SERIOBASE)
+ printf(" serio 0x%x", curp.data.mp.seriobase);
+ if (mask & HDLCDRV_PARMASK_PARIOBASE)
+ printf(" pario 0x%x", curp.data.mp.pariobase);
+ if (mask & HDLCDRV_PARMASK_MIDIIOBASE)
+ printf(" midiio 0x%x", curp.data.mp.midiiobase);
+ printf("\n");
+
+ if (set & 1)
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_SETMODE, &newm);
+ if (ret < 0) {
+ perror("ioctl (HDLCDRVCTL_SETMODE)");
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_MODELIST, &mlist);
+ if (ret < 0) {
+ perror("ioctl (HDLCDRVCTL_MODELIST)");
+ exit(1);
+ }
+ printf("driver supported modes: %s\n",
+ mlist.data.modename);
+ exit(1);
+ }
+ if (set & 2) {
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_SETMODEMPAR, &newp);
+ if (ret < 0) {
+ perror("ioctl (HDLCDRVCTL_SETMODEMPAR)");
+ fprintf(stderr, "%s: trying to restore old "
+ "parameters\n", progname);
+ ret = hdrvc_hdlcdrv_ioctl(HDLCDRVCTL_SETMODEMPAR, &curp);
+ if (ret < 0)
+ perror("ioctl (HDLCDRVCTL_SETMODEMPAR)");
+ exit(1);
+ }
+ }
+ if (set & 3) {
+ printf("new parameters: mode %s", newm.data.modename);
+ if (mask & HDLCDRV_PARMASK_IOBASE)
+ printf(" io 0x%x", newp.data.mp.iobase);
+ if (mask & HDLCDRV_PARMASK_IRQ)
+ printf(" irq %u", newp.data.mp.irq);
+ if (mask & HDLCDRV_PARMASK_DMA)
+ printf(" dma %u", newp.data.mp.dma);
+ if (mask & HDLCDRV_PARMASK_DMA2)
+ printf(" dma2 %u", newp.data.mp.dma2);
+ if (mask & HDLCDRV_PARMASK_SERIOBASE)
+ printf(" serio 0x%x", newp.data.mp.seriobase);
+ if (mask & HDLCDRV_PARMASK_PARIOBASE)
+ printf(" pario 0x%x", newp.data.mp.pariobase);
+ if (mask & HDLCDRV_PARMASK_MIDIIOBASE)
+ printf(" midiio 0x%x", newp.data.mp.midiiobase);
+ printf("\n");
+ }
+ exit(0);
+}
+
+#endif /* HDRVC_KERNEL */
+
+/* ---------------------------------------------------------------------- */
+
+static void display_channel_params(const struct hdrvc_channel_params *par)
+{
+ printf("TX delay %ums, TX tail %ums, slottime %ums, p-persistence "
+ " %u/256, %s duplex\n", 10*par->tx_delay, 10*par->tx_tail,
+ 10*par->slottime, par->ppersist,
+ par->fulldup ? "Full" : "Half");
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void do_set_channel_params(int argc, char **argv)
+{
+ struct hdrvc_channel_params par1, par2;
+ char set = 0;
+ int ret;
+
+ ret = hdrvc_get_channel_access_param(&par1);
+ if (ret < 0) {
+ perror("hdrvc_get_channel_access_param");
+ exit(1);
+ }
+ par2 = par1;
+ while (argc > 0) {
+ if (argc >= 2 && !strcasecmp(argv[0], "txd")) {
+ par2.tx_delay = strtoul(argv[1], NULL, 0) / 10;
+ set = 1;
+ argv += 2;
+ argc -= 2;
+ } else if (argc >= 2 && !strcasecmp(argv[0], "txtail")) {
+ par2.tx_tail = strtoul(argv[1], NULL, 0) / 10;
+ set = 1;
+ argv += 2;
+ argc -= 2;
+ } else if (argc >= 2 && !strcasecmp(argv[0], "slot")) {
+ par2.slottime = strtoul(argv[1], NULL, 0) / 10;
+ set = 1;
+ argv += 2;
+ argc -= 2;
+ } else if (argc >= 2 && !strcasecmp(argv[0], "ppersist")) {
+ par2.ppersist = strtoul(argv[1], NULL, 0);
+ set = 1;
+ argv += 2;
+ argc -= 2;
+ } else if (!strcasecmp(argv[0], "half")) {
+ par2.fulldup = 0;
+ set = 1;
+ argv += 1;
+ argc -= 1;
+ } else if (!strcasecmp(argv[0], "full")) {
+ par2.fulldup = 1;
+ set = 1;
+ argv += 1;
+ argc -= 1;
+ } else {
+
+ argv += 1;
+ argc -= 1;
+ }
+ }
+ printf("current parameters: ");
+ display_channel_params(&par1);
+ if (set) {
+ ret = hdrvc_set_channel_access_param(par2);
+ if (ret < 0) {
+ perror("hdrvc_set_channel_access_param");
+ exit(1);
+ }
+ printf("new parameters: ");
+ display_channel_params(&par2);
+ }
+ exit(0);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static const char *usage_str =
+"[-b] [-i] [-d] [-i <baycomif>] [-h] [-c <cal>]\n"
+"[-p] [hw <hw>] [type <type>] [io <iobase>] [irq <irq>] [dma <dma>]\n"
+" [options <opt>] [serio <serio>] [pario <pario>] [midiio <midiio>]\n"
+"[-a] [txd <txdelay>] [txtail <txtail>] [slot <slottime>]\n"
+" [ppersist <ppersistence>] [full] [half]\n"
+" -a: set or display channel access parameters\n"
+" -b: trace demodulated bits\n"
+" -s: trace sampled input from tcm3105 (ser12 only)\n"
+" -d: trace dcd and ptt status on stdout\n"
+" -i: specify the name of the baycom kernel driver interface\n"
+" -c: calibrate (i.e. send calibration pattern) for cal seconds\n"
+#ifdef HDRVC_KERNEL
+" -p: set or display interface parameters\n"
+#endif /* HDRVC_KERNEL */
+" -h: this help\n\n";
+
+int main(int argc, char *argv[])
+{
+ int ret;
+ fd_set fds_read;
+ fd_set fds_write;
+ struct timeval tm;
+ char getsetparams = 0;
+ char cal = 0;
+ int cal_val = 0;
+ struct sm_ioctl bsi;
+ struct baycom_ioctl bbi;
+ struct hdrvc_channel_state chst;
+ unsigned char pktbuf[2048];
+
+ progname = *argv;
+ printf("%s: Version 0.5; (C) 1996-1997 by Thomas Sailer HB9JNX/AE4WA\n", *argv);
+ hdrvc_args(&argc, argv, "bc0");
+ while ((ret = getopt(argc, argv, "bsdhpc:a")) != -1) {
+ switch (ret) {
+ case 'b':
+ trace_stat = 2;
+ break;
+ case 's':
+ trace_stat = 3;
+ break;
+ case 'd':
+ trace_stat = 1;
+ break;
+#ifdef HDRVC_KERNEL
+ case 'p':
+ getsetparams = 1;
+ break;
+#endif /* HDRVC_KERNEL */
+ case 'a':
+ getsetparams = 2;
+ break;
+ case 'c':
+ cal = 1;
+ cal_val = strtoul(optarg, NULL, 0);
+ break;
+ default:
+ printf("usage: %s %s", *argv, usage_str);
+ exit(-1);
+ }
+ }
+ hdrvc_init();
+ if (getsetparams == 1) {
+#ifdef HDRVC_KERNEL
+ do_set_params(argc - optind, argv+optind);
+#endif /* HDRVC_KERNEL */
+ exit(0);
+ }
+ if (getsetparams == 2) {
+ do_set_channel_params(argc - optind, argv+optind);
+ exit(0);
+ }
+ if (cal) {
+ ret = hdrvc_calibrate(cal_val);
+ if (ret < 0) {
+ perror("hdrvc_calibrate");
+ exit(1);
+ }
+ fprintf(stdout, "%s: calibrating for %i seconds\n", *argv,
+ cal_val);
+ exit(0);
+ }
+ for (;;) {
+ while ((ret = hdrvc_recvpacket(pktbuf, sizeof(pktbuf))) > 1)
+ display_packet(pktbuf+1, ret-1);
+ switch (trace_stat) {
+ case 1:
+ ret = hdrvc_get_channel_state(&chst);
+ if (ret < 0)
+ perror("hdrvc_get_channel_state");
+ printf("%c%c rx: %lu tx: %lu rxerr: %lu txerr: %lu",
+ chst.dcd ? 'D' : '-', chst.ptt ? 'P' : '-',
+ chst.rx_packets, chst.tx_packets, chst.rx_errors,
+ chst.tx_errors);
+#ifdef HDRVC_KERNEL
+ if (hdrvc_sm_ioctl(SMCTL_GETDEBUG, &bsi) >= 0) {
+ printf(" intrate: %u modcyc: %u "
+ "demodcyc: %u dmares: %u",
+ bsi.data.dbg.int_rate,
+ bsi.data.dbg.mod_cycles,
+ bsi.data.dbg.demod_cycles,
+ bsi.data.dbg.dma_residue);
+ }
+ if (hdrvc_baycom_ioctl(BAYCOMCTL_GETDEBUG, &bbi) >= 0) {
+ printf(" dbg1: %lu dbg2: %lu dbg3: %li",
+ bbi.data.dbg.debug1, bbi.data.dbg.debug2,
+ bbi.data.dbg.debug3);
+ }
+#endif /* HDRVC_KERNEL */
+ printf("\n");
+ break;
+ case 2:
+ print_bits(hdrvc_get_bits);
+ printf("\n");
+ break;
+ case 3:
+ print_bits(hdrvc_get_samples);
+ printf("\n");
+ break;
+ default:
+ break;
+ }
+ tm.tv_usec = 500000L;
+ tm.tv_sec = 0L;
+ if (hdrvc_getfd() >= 0) {
+ FD_ZERO(&fds_read);
+ FD_ZERO(&fds_write);
+ FD_SET(hdrvc_getfd(), &fds_read);
+ ret = select(hdrvc_getfd()+1, &fds_read, &fds_write, NULL, &tm);
+ } else
+ ret = select(0, NULL, NULL, NULL, &tm);
+ if (ret < 0) {
+ fprintf(stderr, "%s: Error %s (%i) in select\n", *argv,
+ strerror(errno), errno);
+ exit(-2);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
diff --git a/hdlcutil/smdiag.c b/hdlcutil/smdiag.c
new file mode 100644
index 0000000..d8a20f8
--- /dev/null
+++ b/hdlcutil/smdiag.c
@@ -0,0 +1,434 @@
+/*****************************************************************************/
+
+/*
+ * smdiag.c -- kernel soundcard radio modem driver diagnostics utility.
+ *
+ * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Please note that the GPL allows you to use the driver, NOT the radio.
+ * In order to use the radio, you need a license from the communications
+ * authority of your country.
+ *
+ *
+ * History:
+ * 0.1 26.06.96 Started
+ * 0.2 11.05.97 introduced hdrvcomm.h
+ */
+
+/*****************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <net/if.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "hdrvcomm.h"
+
+#include <linux/soundmodem.h>
+
+/* ---------------------------------------------------------------------- */
+
+static char *progname;
+static Display *display = NULL;
+static Window window;
+static Pixmap pixmap;
+static unsigned long col_zeroline;
+static unsigned long col_background;
+static unsigned long col_trace;
+static GC gr_context;
+static int xmul;
+
+/* ---------------------------------------------------------------------- */
+
+static int x_error_handler(Display *disp, XErrorEvent *evt)
+{
+ char err_buf[256], mesg[256], number[256];
+ char *mtype = "XlibMessage";
+
+ XGetErrorText(disp, evt->error_code, err_buf, sizeof(err_buf));
+ fprintf(stderr, "X Error: %s\n", err_buf);
+ XGetErrorDatabaseText(disp, mtype, "MajorCode", "Request Major code %d",
+ mesg, sizeof(mesg));
+ fprintf(stderr, mesg, evt->request_code);
+ sprintf(number, "%d", evt->request_code);
+ XGetErrorDatabaseText(disp, "XRequest", number, "", err_buf,
+ sizeof(err_buf));
+ fprintf(stderr, " (%s)\n", err_buf);
+ abort();
+}
+
+/* ---------------------------------------------------------------------- */
+
+#define WIDTH 512
+#define HEIGHT (constell ? 512 : 256)
+
+static int openwindow(char *disp, int constell, int samplesperbit)
+{
+ XSetWindowAttributes attr;
+ XGCValues gr_values;
+ XColor color, dummy;
+ XSizeHints sizehints;
+
+ if (!(display = XOpenDisplay(NULL)))
+ return -1;
+ XSetErrorHandler(x_error_handler);
+ XAllocNamedColor(display, DefaultColormap(display, 0), "red",
+ &color, &dummy);
+ col_zeroline = color.pixel;
+ col_background = WhitePixel(display, 0);
+ col_trace = BlackPixel(display, 0);
+ attr.background_pixel = col_background;
+ if (!(window = XCreateWindow(display, XRootWindow(display, 0),
+ 200, 200, WIDTH, HEIGHT, 5,
+ DefaultDepth(display, 0),
+ InputOutput, DefaultVisual(display, 0),
+ CWBackPixel, &attr))) {
+ fprintf(stderr, "smdiag: unable to open X window\n");
+ exit(1);
+ }
+ if (!(pixmap = XCreatePixmap(display, window, WIDTH, HEIGHT,
+ DefaultDepth(display, 0)))) {
+ fprintf(stderr, "smdiag: unable to open offscreen pixmap\n");
+ exit(1);
+ }
+ xmul = WIDTH / (2*(samplesperbit > 0 ? samplesperbit : 1));
+ XSelectInput(display, window, KeyPressMask | StructureNotifyMask
+ | ExposureMask) ;
+ XAllocNamedColor(display, DefaultColormap(display, 0), "red",
+ &color, &dummy);
+ gr_values.foreground = col_trace;
+ gr_values.line_width = 1;
+ gr_values.line_style = LineSolid;
+ gr_context = XCreateGC(display, window, GCForeground | GCLineWidth |
+ GCLineStyle, &gr_values);
+ XStoreName(display, window, "diagnostics");
+ /*
+ * Do not allow the window to be resized
+ */
+ memset(&sizehints, 0, sizeof(sizehints));
+ sizehints.min_width = sizehints.max_width = WIDTH;
+ sizehints.min_height = sizehints.max_height = HEIGHT;
+ sizehints.flags = PMinSize | PMaxSize;
+ XSetWMNormalHints(display, window, &sizehints);
+ XMapWindow(display, window);
+ XSynchronize(display, 1);
+ return 0;
+}
+
+#undef WIDTH
+#undef HEIGHT
+
+/* ---------------------------------------------------------------------- */
+
+static void closewindow(void)
+{
+ if (!display)
+ return;
+ XDestroyWindow(display, window);
+ XCloseDisplay(display);
+ display = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+#define XCOORD(x) ((x) * xm)
+#define YCOORD(y) ((SHRT_MAX - (int)(y)) * winattrs.height / USHRT_MAX)
+
+static void drawdata(short *data, int len, int replace, int xm)
+{
+ int cnt;
+ GC gc;
+ XGCValues gcv;
+ XWindowAttributes winattrs;
+
+ if (!display || !pixmap)
+ return;
+ XGetWindowAttributes(display, window, &winattrs);
+ gcv.line_width = 1;
+ gcv.line_style = LineSolid;
+ gc = XCreateGC(display, pixmap, GCLineWidth | GCLineStyle, &gcv);
+ XSetState(display, gc, col_background, col_background, GXcopy,
+ AllPlanes);
+ if (replace)
+ XFillRectangle(display, pixmap, gc, 0, 0,
+ winattrs.width, winattrs.height);
+ else
+ XCopyArea(display, window, pixmap, gr_context, 0, 0,
+ winattrs.width, winattrs.height, 0, 0);
+ XSetForeground(display, gc, col_trace);
+ for (cnt = 0; cnt < len-1; cnt++)
+ XDrawLine(display, pixmap, gc, XCOORD(cnt), YCOORD(data[cnt]),
+ XCOORD(cnt+1), YCOORD(data[cnt+1]));
+ XSetForeground(display, gc, col_zeroline);
+ XDrawLine(display, pixmap, gc, 0, YCOORD(0), winattrs.width,
+ YCOORD(0));
+ XCopyArea(display, pixmap, window, gr_context, 0, 0, winattrs.width,
+ winattrs.height, 0, 0);
+ XFreeGC(display, gc);
+ XSync(display, 0);
+}
+
+#undef XCOORD
+#undef YCOORD
+
+/* ---------------------------------------------------------------------- */
+
+#define XCOORD(x) ((SHRT_MAX - (int)(x)) * winattrs.width / USHRT_MAX)
+#define YCOORD(y) ((SHRT_MAX - (int)(y)) * winattrs.height / USHRT_MAX)
+
+static void drawconstell(short *data, int len)
+{
+ int cnt;
+ GC gc;
+ XGCValues gcv;
+ XWindowAttributes winattrs;
+
+ if (!display || !pixmap)
+ return;
+ XGetWindowAttributes(display, window, &winattrs);
+ gcv.line_width = 1;
+ gcv.line_style = LineSolid;
+ gc = XCreateGC(display, pixmap, GCLineWidth | GCLineStyle, &gcv);
+ XSetState(display, gc, col_background, col_background, GXcopy,
+ AllPlanes);
+ XCopyArea(display, window, pixmap, gr_context, 0, 0,
+ winattrs.width, winattrs.height, 0, 0);
+ XSetForeground(display, gc, col_trace);
+ for (cnt = 0; cnt < len-1; cnt += 2)
+ XDrawPoint(display, pixmap, gc,
+ XCOORD(data[cnt]), YCOORD(data[cnt+1]));
+ XSetForeground(display, gc, col_zeroline);
+ XDrawLine(display, pixmap, gc, 0, YCOORD(0), winattrs.width, YCOORD(0));
+ XDrawLine(display, pixmap, gc, XCOORD(0), 0, XCOORD(0), winattrs.height);
+ XCopyArea(display, pixmap, window, gr_context, 0, 0, winattrs.width,
+ winattrs.height, 0, 0);
+ XFreeGC(display, gc);
+ XSync(display, 0);
+}
+
+#undef XCOORD
+#undef YCOORD
+
+/* ---------------------------------------------------------------------- */
+
+static void clearwindow(void)
+{
+ XWindowAttributes winattrs;
+ GC gc;
+ XGCValues gcv;
+
+ if (!display || !pixmap)
+ return;
+ XGetWindowAttributes(display, window, &winattrs);
+ gcv.line_width = 1;
+ gcv.line_style = LineSolid;
+ gc = XCreateGC(display, pixmap, GCLineWidth | GCLineStyle, &gcv);
+ XSetState(display, gc, col_background, col_background, GXcopy,
+ AllPlanes);
+ XFillRectangle(display, pixmap, gc, 0, 0,
+ winattrs.width, winattrs.height);
+ XSetForeground(display, gc, col_zeroline);
+ XClearArea(display, window, 0, 0, 0, 0, False);
+ XCopyArea(display, pixmap, window, gr_context, 0, 0, winattrs.width,
+ winattrs.height, 0, 0);
+ XFreeGC(display, gc);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static Bool predicate(Display *display, XEvent *event, char *arg)
+{
+ return True;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static char *getkey(void)
+{
+ XWindowAttributes winattrs;
+ XEvent evt;
+ static char kbuf[32];
+ int i;
+
+ if (!display)
+ return NULL;
+ XSync(display, 0);
+ while (XCheckIfEvent(display, &evt, predicate, NULL)) {
+ switch (evt.type) {
+ case KeyPress:
+ i = XLookupString((XKeyEvent *)&evt, kbuf, sizeof(kbuf)-1,
+ NULL, NULL);
+ if (!i)
+ return NULL;
+ kbuf[i] = 0;
+ return kbuf;
+ case DestroyNotify:
+ XCloseDisplay(display);
+ display = NULL;
+ return NULL;
+ case Expose:
+ XGetWindowAttributes(display, window, &winattrs);
+ XCopyArea(display, pixmap, window, gr_context, 0, 0,
+ winattrs.width, winattrs.height, 0, 0);
+ break;
+ default:
+ break;
+ }
+ }
+ return NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void printmode(unsigned int mode, unsigned int trigger)
+{
+ printf("Source: %s%s\n", (mode == SM_DIAGMODE_DEMOD) ?
+ "demodulator (eye diagram)" : "input (oscilloscope)",
+ (trigger & SM_DIAGFLAG_DCDGATE) ? " gated with DCD" : "");
+}
+
+/* ---------------------------------------------------------------------- */
+
+static const char *usage_str =
+"[-d display] [-i smif] [-c] [-e]\n"
+" -d: display host\n"
+" -i: specify the name of the baycom kernel driver interface\n"
+" -c: toggle carrier trigger\n"
+" -e: eye diagram mode\n\n"
+" -p: constellation plot\n\n";
+
+int main(int argc, char *argv[])
+{
+ char *disp = NULL;
+ unsigned int mode = HDRVC_DIAGMODE_INPUT;
+ unsigned int trigger = 0;
+ unsigned int ifflags;
+ short data[256];
+ char *cp;
+ int ret;
+ unsigned int samplesperbit;
+
+ progname = *argv;
+ printf("%s: Version 0.2; (C) 1996-1997 by Thomas Sailer HB9JNX/AE4WA\n", *argv);
+ hdrvc_args(&argc, argv, "sm0");
+ while ((ret = getopt(argc, argv, "d:ecp")) != -1) {
+ switch (ret) {
+ case 'd':
+ disp = optarg;
+ break;
+ case 'e':
+ mode = HDRVC_DIAGMODE_DEMOD;
+ trigger = HDRVC_DIAGFLAG_DCDGATE;
+ break;
+ case 'c':
+ trigger ^= HDRVC_DIAGFLAG_DCDGATE;
+ break;
+ case 'p':
+ mode = HDRVC_DIAGMODE_CONSTELLATION;
+ break;
+ default:
+ printf("usage: %s %s", *argv, usage_str);
+ exit(-1);
+ }
+ }
+ hdrvc_init();
+#ifdef HDRVC_KERNEL
+ ifflags = hdrvc_get_ifflags();
+ if (!(ifflags & IFF_UP)) {
+ fprintf(stderr, "interface %s down\n", hdrvc_ifname());
+ exit(1);
+ }
+ if (!(ifflags & IFF_RUNNING)) {
+ fprintf(stderr, "interface %s not running\n", hdrvc_ifname());
+ exit(1);
+ }
+#endif /* HDRVC_KERNEL */
+ printmode(mode, trigger);
+ for (;;) {
+ if ((ret = hdrvc_diag2(mode, trigger, data, sizeof(data) / sizeof(short),
+ &samplesperbit)) < 0) {
+ perror("hdrvc_diag2");
+ exit(1);
+ }
+ if (ret > 0) {
+ if (!display) {
+ openwindow(disp, mode == HDRVC_DIAGMODE_CONSTELLATION,
+ samplesperbit);
+ clearwindow();
+ }
+ if (mode == SM_DIAGMODE_CONSTELLATION)
+ drawconstell(data, ret);
+ else
+ drawdata(data, ret, mode == HDRVC_DIAGMODE_INPUT,
+ mode == HDRVC_DIAGMODE_INPUT ? 5:xmul);
+ } else
+ usleep(100000L);
+ if (display) {
+ if ((cp = getkey())) {
+ for (; *cp; cp++) {
+ printf("char pressed: '%c'\n", *cp);
+ switch (*cp) {
+ case 'c':
+ case 'C':
+ clearwindow();
+ printmode(mode, trigger);
+ break;
+ case 'q':
+ case 'Q':
+ closewindow();
+ break;
+ case 'i':
+ case 'I':
+ if (mode == HDRVC_DIAGMODE_CONSTELLATION)
+ break;
+ mode = HDRVC_DIAGMODE_INPUT;
+ clearwindow();
+ printmode(mode, trigger);
+ break;
+ case 'e':
+ case 'E':
+ if (mode == HDRVC_DIAGMODE_CONSTELLATION)
+ break;
+ mode = HDRVC_DIAGMODE_DEMOD;
+ clearwindow();
+ printmode(mode, trigger);
+ break;
+ case 'd':
+ case 'D':
+ trigger ^= HDRVC_DIAGFLAG_DCDGATE;
+ clearwindow();
+ printmode(mode, trigger);
+ break;
+ }
+ }
+ }
+ if (!display)
+ exit(0);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
diff --git a/hdlcutil/smmixer.c b/hdlcutil/smmixer.c
new file mode 100644
index 0000000..3cfc7e7
--- /dev/null
+++ b/hdlcutil/smmixer.c
@@ -0,0 +1,781 @@
+/*****************************************************************************/
+
+/*
+ * smmixer.c -- kernel soundcard radio modem driver mixer utility.
+ *
+ * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Please note that the GPL allows you to use the driver, NOT the radio.
+ * In order to use the radio, you need a license from the communications
+ * authority of your country.
+ *
+ *
+ * History:
+ * 0.1 26.06.96 Started
+ * 0.2 11.05.97 introduced hdrvcomm.h
+ */
+
+/*****************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <net/if.h>
+#include "hdrvcomm.h"
+
+#include <linux/soundmodem.h>
+/* ---------------------------------------------------------------------- */
+
+static char *progname;
+static unsigned int mixdevice;
+
+/* ---------------------------------------------------------------------- */
+
+static int do_mix_ioctl(int cmd, struct sm_mixer_data *mixdat)
+{
+ struct sm_ioctl par;
+ int i;
+
+ par.cmd = cmd;
+ par.data.mix = *mixdat;
+#ifdef HDRVC_KERNEL
+ i = hdrvc_sm_ioctl(cmd, &par);
+#endif
+ *mixdat = par.data.mix;
+ return i;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static unsigned char get_mixer_reg(unsigned char addr)
+{
+ int i;
+ struct sm_mixer_data mixdat;
+
+ mixdat.reg = addr;
+ if ((i = do_mix_ioctl(SMCTL_GETMIXER, &mixdat)) < 0) {
+ perror("do_mix_ioctl: SMCTL_GETMIXER");
+ exit(1);
+ }
+ if (!i)
+ fprintf(stderr, "warning: mixer device %u register %u not "
+ "accessible for reading!\n", mixdat.mixer_type,
+ addr);
+ if (mixdat.mixer_type != mixdevice) {
+ fprintf(stderr, "error: mixer type changed !?\n");
+ exit(2);
+ }
+ return mixdat.data;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void set_mixer_reg(unsigned char addr, unsigned char data)
+{
+ struct sm_mixer_data mixdat;
+
+ mixdat.reg = addr;
+ mixdat.data = data;
+ mixdat.mixer_type = mixdevice;
+ if (do_mix_ioctl(SMCTL_SETMIXER, &mixdat) < 0) {
+ perror("do_mix_ioctl: SMCTL_SETMIXER");
+ exit(1);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void display_mixer_ad1848(void)
+{
+ static const char *src[4] = { "Line", "Aux1", "Mic", "Dac" };
+ unsigned char data;
+
+ data = get_mixer_reg(0);
+ printf("Left input: Source: %-4s Gain: %3ddB\n", src[(data>>6)&3],
+ (((data & 0xe0) == 0xa0) ? 20 : 0) + (data & 0xf) * 3 / 2);
+ data = get_mixer_reg(1);
+ printf("Right input: Source: %-4s Gain: %3ddB\n", src[(data>>6)&3],
+ (((data & 0xe0) == 0xa0) ? 20 : 0) + (data & 0xf) * 3 / 2);
+ data = get_mixer_reg(2);
+ if (!(data & 0x80))
+ printf("Left Aux1 mixing: Gain: %3ddB\n",
+ (8 - (int)(data & 0x1f)) * 3 / 2);
+ data = get_mixer_reg(3);
+ if (!(data & 0x80))
+ printf("Right Aux1 mixing: Gain: %3ddB\n",
+ (8 - (int)(data & 0x1f)) * 3 / 2);
+ data = get_mixer_reg(4);
+ if (!(data & 0x80))
+ printf("Left Aux2 mixing: Gain: %3ddB\n",
+ (8 - (int)(data & 0x1f)) * 3 / 2);
+ data = get_mixer_reg(5);
+ if (!(data & 0x80))
+ printf("Right Aux2 mixing: Gain: %3ddB\n",
+ (8 - (int)(data & 0x1f)) * 3 / 2);
+ data = get_mixer_reg(6);
+ if (data & 0x80)
+ printf("Left output: muted\n");
+ else
+ printf("Left output: Gain: %3ddB\n",
+ ((int)(data & 0x3f)) * (-3) / 2);
+ data = get_mixer_reg(7);
+ if (data & 0x80)
+ printf("Right output: muted\n");
+ else
+ printf("Right output: Gain: %3ddB\n",
+ ((int)(data & 0x3f)) * (-3) / 2);
+ data = get_mixer_reg(13);
+ if (data & 1)
+ printf("Digital mix: Gain: %3ddB\n",
+ ((int)((data >> 2) & 0x3f)) * (-3) / 2);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void display_mixer_cs423x(void)
+{
+ unsigned char data;
+
+ display_mixer_ad1848();
+ data = get_mixer_reg(26);
+ printf("Mono: %s%s%s Gain: %3ddB\n",
+ (data & 0x80) ? "input muted, " : "",
+ (data & 0x40) ? "output muted, " : "",
+ (data & 0x20) ? "bypass, " : "",
+ (int)(data & 0xf) * (-3));
+ data = get_mixer_reg(27);
+ if (data & 0x80)
+ printf("Left output: muted\n");
+ else
+ printf("Left output: Gain: %3ddB\n",
+ ((int)(data & 0xf)) * (-2));
+ data = get_mixer_reg(29);
+ if (data & 0x80)
+ printf("Right output: muted\n");
+ else
+ printf("Right output: Gain: %3ddB\n",
+ ((int)(data & 0xf)) * (-2));
+
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void display_mixer_ct1335(void)
+{
+ unsigned char data;
+
+ data = get_mixer_reg(0x2);
+ printf("Master volume: %3ddB\n",
+ (((int)((data >> 1) & 7)) - 7) * 46 / 7);
+ data = get_mixer_reg(0xa);
+ printf("Voice volume: %3ddB\n",
+ (((int)((data >> 1) & 3)) - 3) * 46 / 3);
+ data = get_mixer_reg(0x6);
+ printf("MIDI volume: %3ddB\n",
+ (((int)((data >> 1) & 7)) - 7) * 46 / 7);
+ data = get_mixer_reg(0x8);
+ printf("CD volume: %3ddB\n",
+ (((int)((data >> 1) & 7)) - 7) * 46 / 7);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void display_mixer_ct1345(void)
+{
+ static const char *src[4] = { "Mic", "CD", "Mic", "Line" };
+ unsigned char data, data2;
+
+ data = get_mixer_reg(0xc);
+ data2 = get_mixer_reg(0xe);
+ printf("Input source: %s\n", src[(data >> 1) & 3]);
+ if (!(data & data2 & 0x20)) {
+ printf("Filter: Low pass %s kHz: ", (data & 0x8) ?
+ "8.8" : "3.2");
+ if (data & 0x20)
+ printf("output\n");
+ else
+ printf("input%s\n", (data2 & 0x20) ? "" : ", output");
+ }
+ if (data2 & 2)
+ printf("stereo\n");
+
+ data = get_mixer_reg(0x22);
+ printf("Master volume: Left: %3ddB Right: %3ddB\n",
+ (((int)((data >> 5) & 7)) - 7) * 46 / 7,
+ (((int)((data >> 1) & 7)) - 7) * 46 / 7);
+ data = get_mixer_reg(0x4);
+ printf("Voice volume: Left: %3ddB Right: %3ddB\n",
+ (((int)((data >> 5) & 7)) - 7) * 46 / 7,
+ (((int)((data >> 1) & 7)) - 7) * 46 / 7);
+ data = get_mixer_reg(0x26);
+ printf("MIDI volume: Left: %3ddB Right: %3ddB\n",
+ (((int)((data >> 5) & 7)) - 7) * 46 / 7,
+ (((int)((data >> 1) & 7)) - 7) * 46 / 7);
+ data = get_mixer_reg(0x28);
+ printf("CD volume: Left: %3ddB Right: %3ddB\n",
+ (((int)((data >> 5) & 7)) - 7) * 46 / 7,
+ (((int)((data >> 1) & 7)) - 7) * 46 / 7);
+ data = get_mixer_reg(0x2e);
+ printf("Line volume: Left: %3ddB Right: %3ddB\n",
+ (((int)((data >> 5) & 7)) - 7) * 46 / 7,
+ (((int)((data >> 1) & 7)) - 7) * 46 / 7);
+ data = get_mixer_reg(0x0a);
+ printf("Mic mixing volume: %3ddB\n",
+ (((int)((data >> 1) & 3)) - 3) * 46 / 3);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void display_mixer_ct1745(void)
+{
+ unsigned char data, data2;
+
+ printf("Master volume: Left: %3ddB Right: %3ddB\n",
+ ((int)((get_mixer_reg(0x30) >> 3) & 0x1f) - 31) * 2,
+ ((int)((get_mixer_reg(0x31) >> 3) & 0x1f) - 31) * 2);
+ printf("Voice volume: Left: %3ddB Right: %3ddB\n",
+ ((int)((get_mixer_reg(0x32) >> 3) & 0x1f) - 31) * 2,
+ ((int)((get_mixer_reg(0x33) >> 3) & 0x1f) - 31) * 2);
+ printf("MIDI volume: Left: %3ddB Right: %3ddB\n",
+ ((int)((get_mixer_reg(0x34) >> 3) & 0x1f) - 31) * 2,
+ ((int)((get_mixer_reg(0x35) >> 3) & 0x1f) - 31) * 2);
+ printf("CD volume: Left: %3ddB Right: %3ddB\n",
+ ((int)((get_mixer_reg(0x36) >> 3) & 0x1f) - 31) * 2,
+ ((int)((get_mixer_reg(0x37) >> 3) & 0x1f) - 31) * 2);
+ printf("Line volume: Left: %3ddB Right: %3ddB\n",
+ ((int)((get_mixer_reg(0x38) >> 3) & 0x1f) - 31) * 2,
+ ((int)((get_mixer_reg(0x39) >> 3) & 0x1f) - 31) * 2);
+ printf("Mic volume: %3ddB\n",
+ ((int)((get_mixer_reg(0x3a) >> 3) & 0x1f) - 31) * 2);
+ printf("PC speaker volume: %3ddB\n",
+ ((int)((get_mixer_reg(0x3b) >> 6) & 0x3) - 3) * 6);
+ printf("Mic gain: %s\n",
+ (get_mixer_reg(0x43) & 1) ? "fixed 20dB" : "AGC");
+ printf("Output gain: Left: %3ddB Right: %3ddB\n",
+ ((int)((get_mixer_reg(0x41) >> 6) & 3)) * 6,
+ ((int)((get_mixer_reg(0x42) >> 6) & 3)) * 6);
+ printf("Input gain: Left: %3ddB Right: %3ddB\n",
+ ((int)((get_mixer_reg(0x3f) >> 6) & 3)) * 6,
+ ((int)((get_mixer_reg(0x40) >> 6) & 3)) * 6);
+ data = (get_mixer_reg(0x44) >> 4) & 0xf;
+ if (data > 7)
+ data--;
+ data2 = (get_mixer_reg(0x45) >> 4) & 0xf;
+ if (data2 > 7)
+ data2--;
+ printf("Treble: Left: %3ddB Right: %3ddB\n",
+ ((int)data - 7) * 2, ((int)data2 - 7) * 2);
+ data = (get_mixer_reg(0x46) >> 4) & 0xf;
+ if (data > 7)
+ data--;
+ data2 = (get_mixer_reg(0x47) >> 4) & 0xf;
+ if (data2 > 7)
+ data2--;
+ printf("Bass: Left: %3ddB Right: %3ddB\n",
+ ((int)data - 7) * 2, ((int)data2 - 7) * 2);
+ data = get_mixer_reg(0x3c);
+ printf("Output sources left: PCSpeaker Voice.L%s%s%s\n",
+ (data & 1) ? " Mic" : "", (data & 4) ? " CD.L" : "",
+ (data & 0x10) ? " Line.L" : "");
+ printf("Output sources right: PCSpeaker Voice.R%s%s%s\n",
+ (data & 1) ? " Mic" : "", (data & 2) ? " CD.R" : "",
+ (data & 8) ? " Line.R" : "");
+ data = get_mixer_reg(0x3d);
+ printf("Input sources left: %s%s%s%s%s%s%s\n",
+ (data & 1) ? " Mic" : "", (data & 2) ? " CD.R" : "",
+ (data & 4) ? " CD.L" : "", (data & 8) ? " Line.R" : "",
+ (data & 0x10) ? " Line.L" : "", (data & 0x20) ? " Midi.R" : "",
+ (data & 0x40) ? " Midi.L" : "");
+ data = get_mixer_reg(0x3e);
+ printf("Input sources right: %s%s%s%s%s%s%s\n",
+ (data & 1) ? " Mic" : "", (data & 2) ? " CD.R" : "",
+ (data & 4) ? " CD.L" : "", (data & 8) ? " Line.R" : "",
+ (data & 0x10) ? " Line.L" : "", (data & 0x20) ? " Midi.R" : "",
+ (data & 0x40) ? " Midi.L" : "");
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int parse_ad_src(const char *cp)
+{
+ if (!strcasecmp(cp, "line"))
+ return 0;
+ if (!strcasecmp(cp, "aux1"))
+ return 1;
+ if (!strcasecmp(cp, "mic"))
+ return 2;
+ if (!strcasecmp(cp, "dac"))
+ return 3;
+ return -1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int set_mixer_ad1848(int argc, char *argv[])
+{
+ unsigned int mask = 0;
+ int olvll = 0, olvlr = 0;
+ int isrcl = 0, isrcr = 0;
+ int ilvll = 0, ilvlr = 0;
+ unsigned int data;
+
+ for (; argc >= 1; argc--, argv++) {
+ if (!strncasecmp(argv[0], "ol=", 3)) {
+ olvll = strtol(argv[0]+3, NULL, 0);
+ mask |= 1;
+ if (olvll < -46 || olvll > 0) {
+ fprintf(stderr, "output level out of range "
+ "-100..0dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "or=", 3)) {
+ olvlr = strtol(argv[0]+3, NULL, 0);
+ mask |= 2;
+ if (olvlr < -46 || olvlr > 0) {
+ fprintf(stderr, "output level out of range "
+ "-100..0dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "o=", 2)) {
+ olvll = olvlr = strtol(argv[0]+2, NULL, 0);
+ mask |= 3;
+ if (olvll < -46 || olvll > 0) {
+ fprintf(stderr, "output level out of range "
+ "-100..0dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "il=", 3)) {
+ ilvll = strtol(argv[0]+3, NULL, 0);
+ mask |= 4;
+ if (ilvll < 0 || ilvll > 43) {
+ fprintf(stderr, "input gain out of range "
+ "0..43dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "ir=", 3)) {
+ ilvlr = strtol(argv[0]+3, NULL, 0);
+ mask |= 8;
+ if (ilvll < 0 || ilvll > 43) {
+ fprintf(stderr, "input gain out of range "
+ "0..43dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "i=", 2)) {
+ ilvll = ilvlr = strtol(argv[0]+2, NULL, 0);
+ mask |= 12;
+ if (ilvll < 0 || ilvll > 43) {
+ fprintf(stderr, "input gain out of range "
+ "0..43dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "sl=", 3)) {
+ mask |= 16;
+ if ((isrcl = parse_ad_src(argv[0]+3)) < 0) {
+ fprintf(stderr, "invalid input source, must "
+ "be either line, aux1, mic or dac\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "sr=", 3)) {
+ mask |= 32;
+ if ((isrcr = parse_ad_src(argv[0]+3)) < 0) {
+ fprintf(stderr, "invalid input source, must "
+ "be either line, aux1, mic or dac\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "s=", 2)) {
+ mask |= 48;
+ if ((isrcl = isrcr = parse_ad_src(argv[0]+2)) < 0) {
+ fprintf(stderr, "invalid input source, must "
+ "be either line, aux1, mic or dac\n");
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "invalid parameter \"%s\"\n", argv[0]);
+ return -1;
+ }
+ }
+ data = get_mixer_reg(0x00);
+ if (mask & 4) {
+ data &= 0xc0;
+ if (ilvll > 23) {
+ data |= 0x20;
+ ilvll -= 20;
+ }
+ data |= ilvll * 2 / 3;
+ }
+ if (mask & 16)
+ data = (data & 0x3f) | (isrcl << 6);
+ if ((data & 0xc0) != 0x80)
+ data &= ~0x20;
+ set_mixer_reg(0x00, data);
+ data = get_mixer_reg(0x01);
+ if (mask & 8) {
+ data &= 0xc0;
+ if (ilvlr > 23) {
+ data |= 0x20;
+ ilvlr -= 20;
+ }
+ data |= ilvlr * 2 / 3;
+ }
+ if (mask & 32)
+ data = (data & 0x3f) | (isrcr << 6);
+ if ((data & 0xc0) != 0x80)
+ data &= ~0x20;
+ set_mixer_reg(0x01, data);
+ set_mixer_reg(0x02, 0x80);
+ set_mixer_reg(0x03, 0x80);
+ set_mixer_reg(0x04, 0x80);
+ set_mixer_reg(0x05, 0x80);
+ if (mask & 1) {
+ if (olvll < -95)
+ set_mixer_reg(0x06, 0x80);
+ else
+ set_mixer_reg(0x06, (olvll * (-2) / 3));
+ }
+ if (mask & 2) {
+ if (olvlr < -95)
+ set_mixer_reg(0x07, 0x80);
+ else
+ set_mixer_reg(0x07, (olvlr * (-2) / 3));
+ }
+ set_mixer_reg(0x0d, 0x00);
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int set_mixer_ct1335(int argc, char *argv[])
+{
+ unsigned int mask = 0;
+ int olvl = 0;
+
+ for (; argc >= 1; argc--, argv++) {
+ if (!strncasecmp(argv[0], "o=", 2)) {
+ olvl = strtol(argv[0]+2, NULL, 0);
+ mask |= 1;
+ if (olvl < -46 || olvl > 0) {
+ fprintf(stderr, "output level out of range "
+ "-46..0dB\n");
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "invalid parameter \"%s\"\n", argv[0]);
+ return -1;
+ }
+ }
+ if (mask & 1)
+ set_mixer_reg(0x02, (((olvl * 7 / 46) + 7) << 1));
+ set_mixer_reg(0x06, 0x00);
+ set_mixer_reg(0x08, 0x00);
+ set_mixer_reg(0x0a, 0x06);
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int set_mixer_ct1345(int argc, char *argv[])
+{
+ unsigned int mask = 0;
+ int olvll = 0, olvlr = 0;
+ int isrc = 0;
+ unsigned int data;
+
+ for (; argc >= 1; argc--, argv++) {
+ if (!strncasecmp(argv[0], "ol=", 3)) {
+ olvll = strtol(argv[0]+3, NULL, 0);
+ mask |= 1;
+ if (olvll < -46 || olvll > 0) {
+ fprintf(stderr, "output level out of range "
+ "-46..0dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "or=", 3)) {
+ olvlr = strtol(argv[0]+3, NULL, 0);
+ mask |= 2;
+ if (olvlr < -46 || olvlr > 0) {
+ fprintf(stderr, "output level out of range "
+ "-46..0dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "o=", 2)) {
+ olvll = olvlr = strtol(argv[0]+2, NULL, 0);
+ mask |= 3;
+ if (olvll < -46 || olvll > 0) {
+ fprintf(stderr, "output level out of range "
+ "-46..0dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "s=", 2)) {
+ mask |= 4;
+ if (!strcasecmp(argv[0]+2, "mic"))
+ isrc = 0;
+ else if (!strcasecmp(argv[0]+2, "cd"))
+ isrc = 1;
+ else if (!strcasecmp(argv[0]+2, "line"))
+ isrc = 3;
+ else {
+ fprintf(stderr, "invalid input source, must "
+ "be either mic, cd or line\n");
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "invalid parameter \"%s\"\n", argv[0]);
+ return -1;
+ }
+ }
+ set_mixer_reg(0x04, 0xee);
+ set_mixer_reg(0x0a, 0x00);
+ if (mask & 4)
+ data = (isrc & 3) << 1;
+ else
+ data = get_mixer_reg(0x0c) & 0x06;
+ set_mixer_reg(0x0c, data | 0x20);
+ set_mixer_reg(0x0e, 0x20);
+ data = get_mixer_reg(0x22);
+ if (mask & 1)
+ data = (data & 0x0f) | (((olvll * 7 / 46) + 7) << 5);
+ if (mask & 2)
+ data = (data & 0xf0) | (((olvlr * 7 / 46) + 7) << 1);
+ set_mixer_reg(0x22, data);
+ set_mixer_reg(0x26, 0x00);
+ set_mixer_reg(0x28, 0x00);
+ set_mixer_reg(0x2e, 0x00);
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int set_mixer_ct1745(int argc, char *argv[])
+{
+ unsigned int mask = 0;
+ int olvll = 0, olvlr = 0;
+ int ilvll = 0, ilvlr = 0;
+ unsigned int insrc = 0;
+ unsigned int data;
+
+ for (; argc >= 1; argc--, argv++) {
+ if (!strncasecmp(argv[0], "ol=", 3)) {
+ olvll = strtol(argv[0]+3, NULL, 0);
+ mask |= 1;
+ if (olvll < -62 || olvll > 18) {
+ fprintf(stderr, "output level out of range "
+ "-62..18dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "or=", 3)) {
+ olvlr = strtol(argv[0]+3, NULL, 0);
+ mask |= 2;
+ if (olvlr < -62 || olvlr > 18) {
+ fprintf(stderr, "output level out of range "
+ "-62..18dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "o=", 2)) {
+ olvll = olvlr = strtol(argv[0]+2, NULL, 0);
+ mask |= 3;
+ if (olvll < -62 || olvll > 18) {
+ fprintf(stderr, "output level out of range "
+ "-62..18dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "il=", 3)) {
+ ilvll = strtol(argv[0]+3, NULL, 0);
+ mask |= 4;
+ if (ilvll < -62 || ilvll > 18) {
+ fprintf(stderr, "input gain out of range "
+ "-62..18dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "ir=", 3)) {
+ ilvlr = strtol(argv[0]+3, NULL, 0);
+ mask |= 8;
+ if (ilvll < -62 || ilvll > 18) {
+ fprintf(stderr, "input gain out of range "
+ "-62..18dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "i=", 2)) {
+ ilvll = ilvlr = strtol(argv[0]+2, NULL, 0);
+ mask |= 12;
+ if (ilvll < -62 || ilvll > 18) {
+ fprintf(stderr, "input gain out of range "
+ "-62..18dB\n");
+ return -1;
+ }
+ } else if (!strncasecmp(argv[0], "s=", 2)) {
+ mask |= 16;
+ if (!strcasecmp(argv[0]+2, "mic"))
+ insrc |= 1;
+ else if (!strcasecmp(argv[0]+2, "cd.r"))
+ insrc |= 2;
+ else if (!strcasecmp(argv[0]+2, "cd.l"))
+ insrc |= 4;
+ else if (!strcasecmp(argv[0]+2, "cd"))
+ insrc |= 6;
+ else if (!strcasecmp(argv[0]+2, "line.r"))
+ insrc |= 0x08;
+ else if (!strcasecmp(argv[0]+2, "line.l"))
+ insrc |= 0x10;
+ else if (!strcasecmp(argv[0]+2, "line"))
+ insrc |= 0x18;
+ else if (!strcasecmp(argv[0]+2, "midi.r"))
+ insrc |= 0x20;
+ else if (!strcasecmp(argv[0]+2, "midi.l"))
+ insrc |= 0x40;
+ else if (!strcasecmp(argv[0]+2, "midi"))
+ insrc |= 0x60;
+ else {
+ fprintf(stderr, "invalid input source, must "
+ "be either line, cd, mic or midi\n");
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "invalid parameter \"%s\"\n", argv[0]);
+ return -1;
+ }
+ }
+ if (mask & 3) {
+ set_mixer_reg(0x3c, 0); /* output src: only voice and pcspk */
+ set_mixer_reg(0x44, 4<<4); /* treble.l: -6dB */
+ set_mixer_reg(0x45, 4<<4); /* treble.r: -6dB */
+ set_mixer_reg(0x46, 6<<4); /* bass.l: -2dB */
+ set_mixer_reg(0x47, 6<<4); /* bass.r: -2dB */
+ set_mixer_reg(0x3b, 0); /* PC speaker vol -18dB */
+ }
+ if (mask & 12)
+ set_mixer_reg(0x43, 1); /* mic: agc off, fixed 20dB gain */
+ if (mask & 1) {
+ data = 0;
+ while (olvll > 0) {
+ olvll -= 6;
+ data += 0x40;
+ }
+ set_mixer_reg(0x41, data); /* output gain */
+ set_mixer_reg(0x30, 0xf8); /* master vol */
+ set_mixer_reg(0x32, (olvll / 2 + 31) << 3); /* voice vol */
+ }
+ if (mask & 2) {
+ data = 0;
+ while (olvlr > 0) {
+ olvlr -= 6;
+ data += 0x40;
+ }
+ set_mixer_reg(0x42, data); /* output gain */
+ set_mixer_reg(0x31, 0xf8); /* master vol */
+ set_mixer_reg(0x33, (olvlr / 2 + 31) << 3); /* voice vol */
+ }
+ if (mask & 4) {
+ data = 0;
+ while (ilvll > 0) {
+ ilvll -= 6;
+ data += 0x40;
+ }
+ set_mixer_reg(0x3f, data); /* input gain */
+ data = (ilvll / 2 + 31) << 3;
+ set_mixer_reg(0x34, data); /* midi vol */
+ set_mixer_reg(0x36, data); /* cd vol */
+ set_mixer_reg(0x38, data); /* line vol */
+ set_mixer_reg(0x3a, data); /* mic vol */
+ }
+ if (mask & 8) {
+ data = 0;
+ while (ilvlr > 0) {
+ ilvlr -= 6;
+ data += 0x40;
+ }
+ set_mixer_reg(0x40, data); /* input gain */
+ data = (ilvlr / 2 + 31) << 3;
+ set_mixer_reg(0x35, data); /* midi vol */
+ set_mixer_reg(0x37, data); /* cd vol */
+ set_mixer_reg(0x39, data); /* line vol */
+ set_mixer_reg(0x3a, data); /* mic vol */
+ }
+ if (mask & 16) {
+ set_mixer_reg(0x3d, insrc); /* input sources */
+ set_mixer_reg(0x3e, insrc); /* input sources */
+ }
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static const char *usage_str =
+"[-i smif]\n\n";
+
+int main(int argc, char *argv[])
+{
+ int c;
+ struct sm_mixer_data mixdat;
+
+ progname = *argv;
+ printf("%s: Version 0.2; (C) 1996-1997 by Thomas Sailer HB9JNX/AE4WA\n", *argv);
+ hdrvc_args(&argc, argv, "sm0");
+ while ((c = getopt(argc, argv, "")) != -1) {
+ switch (c) {
+ default:
+ printf("usage: %s %s", *argv, usage_str);
+ exit(-1);
+ }
+ }
+ hdrvc_init();
+ mixdat.reg = 0;
+ if (do_mix_ioctl(SMCTL_GETMIXER, &mixdat) < 0) {
+ perror("do_mix_ioctl: SMCTL_GETMIXER");
+ exit(1);
+ }
+ mixdevice = mixdat.mixer_type;
+ switch (mixdevice) {
+ case SM_MIXER_INVALID:
+ printf("invalid mixer device\n");
+ exit(1);
+ case SM_MIXER_AD1848:
+ if (optind < argc)
+ set_mixer_ad1848(argc - optind, argv + optind);
+ display_mixer_ad1848();
+ break;
+ case SM_MIXER_CRYSTAL:
+ if (optind < argc)
+ set_mixer_ad1848(argc - optind, argv + optind);
+ display_mixer_cs423x();
+ break;
+ case SM_MIXER_CT1335:
+ if (optind < argc)
+ set_mixer_ct1335(argc - optind, argv + optind);
+ display_mixer_ct1335();
+ break;
+ case SM_MIXER_CT1345:
+ if (optind < argc)
+ set_mixer_ct1345(argc - optind, argv + optind);
+ display_mixer_ct1345();
+ break;
+ case SM_MIXER_CT1745:
+ if (optind < argc)
+ set_mixer_ct1745(argc - optind, argv + optind);
+ display_mixer_ct1745();
+ break;
+ default:
+ printf("unknown mixer device %d\n", mixdevice);
+ exit(1);
+ }
+ exit(0);
+}
+
+/* ---------------------------------------------------------------------- */
diff --git a/hdlcutil/usersmdiag.h b/hdlcutil/usersmdiag.h
new file mode 100644
index 0000000..5335002
--- /dev/null
+++ b/hdlcutil/usersmdiag.h
@@ -0,0 +1,118 @@
+/*****************************************************************************/
+
+/*
+ * usersmdiag.h -- Diagnostics interface.
+ *
+ * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ * Swiss Federal Institute of Technology (ETH), Electronics Lab
+ *
+ * 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This is the Linux realtime sound output driver
+ */
+
+/*****************************************************************************/
+
+#ifndef _USERSMDIAG_H
+#define _USERSMDIAG_H
+
+/* --------------------------------------------------------------------- */
+
+#define USERSM_KEY_PROJ '0'
+
+/* --------------------------------------------------------------------- */
+
+#define USERSM_CMD_REQ_CHACCESS_PAR 0x00020
+#define USERSM_CMD_ACK_CHACCESS_PAR 0x10021
+#define USERSM_CMD_SET_CHACCESS_PAR 0x00022
+
+#define USERSM_CMD_CALIBRATE 0x00030
+#define USERSM_CMD_REQ_CHANNELSTATE 0x00031
+#define USERSM_CMD_ACK_CHANNELSTATE 0x10032
+
+#define USERSM_CMD_REQ_DIAG 0x00040
+#define USERSM_CMD_ACK_DIAG 0x10041
+
+#define USERSM_CMD_REQ_DRVNAME 0x00050
+#define USERSM_CMD_ACK_DRVNAME 0x10051
+#define USERSM_CMD_REQ_DRVMODE 0x00052
+#define USERSM_CMD_ACK_DRVMODE 0x10053
+
+/*
+ * diagnose modes; same as in <linux/soundmodem.h>
+ */
+#define USERSM_DIAGMODE_OFF 0
+#define USERSM_DIAGMODE_INPUT 1
+#define USERSM_DIAGMODE_DEMOD 2
+#define USERSM_DIAGMODE_CONSTELLATION 3
+
+/*
+ * diagnose flags; same as in <linux/soundmodem.h>
+ */
+#define USERSM_DIAGFLAG_DCDGATE (1<<0)
+#define USERSM_DIAGFLAG_VALID (1<<1)
+
+/* --------------------------------------------------------------------- */
+
+#define DIAGDATALEN 64
+
+/* --------------------------------------------------------------------- */
+
+struct usersmmsg {
+ struct usersm_hdr {
+ long type;
+ unsigned int channel;
+ } hdr;
+ union {
+ struct usersm_chaccess_par {
+ int tx_delay; /* the transmitter keyup delay in 10ms units */
+ int tx_tail; /* the transmitter keyoff delay in 10ms units */
+ int slottime; /* the slottime in 10ms; usually 10 = 100ms */
+ int ppersist; /* the p-persistence 0..255 */
+ int fulldup; /* some driver do not support full duplex, setting */
+ /* this just makes them send even if DCD is on */
+ } cp;
+
+ int calib;
+
+ struct usersm_channel_state {
+ int ptt;
+ int dcd;
+ int ptt_keyed;
+ unsigned long tx_packets;
+ unsigned long tx_errors;
+ unsigned long rx_packets;
+ unsigned long rx_errors;
+ } cs;
+
+ struct usersm_diag {
+ unsigned int mode;
+ unsigned int flags;
+ unsigned int samplesperbit;
+ unsigned int datalen;
+ } diag;
+
+ struct usersm_diag_out {
+ struct usersm_diag diag;
+ short samples[DIAGDATALEN];
+ } diag_out;
+
+ unsigned char by[0];
+ } data;
+};
+
+/* --------------------------------------------------------------------- */
+#endif /* _USERSMDIAG_H */