Compare commits
74 Commits
v2.10.1-rc
...
master
Author | SHA1 | Date |
---|---|---|
Harald Welte | 5255769504 | |
Harald Welte | e9a4598c1f | |
Harald Welte | de9bd096c9 | |
Harald Welte | 89b6df7593 | |
Harald Welte | 68395096f0 | |
Harald Welte | 3b90fdbba1 | |
Keith Morgan | 31cca182bf | |
Tzafrir Cohen | 75eedd6fa6 | |
Tzafrir Cohen | b54ec6efd3 | |
Oron Peled | 754d981621 | |
Oron Peled | dc95a1164f | |
Tzafrir Cohen | 9631938e90 | |
Tzafrir Cohen | 55679791b5 | |
Tzafrir Cohen | ba09742a3f | |
Tzafrir Cohen | e4197cc499 | |
Tzafrir Cohen | abd139ae91 | |
Dima Stoliarov | 6b2c6d72d8 | |
Tzafrir Cohen | f64500c986 | |
Tzafrir Cohen | 424157834d | |
Tzafrir Cohen | 95d03118cb | |
Oron Peled | 99e3c572d1 | |
Tzafrir Cohen | 6057ef25e9 | |
Oron Peled | e1da7b5284 | |
Tzafrir Cohen | f105a09eda | |
Oron Peled | 212b247e68 | |
Oron Peled | f225a5692c | |
Tzafrir Cohen | cffc5158cc | |
Oron Peled | 42850dba35 | |
Oron Peled | 06ae8473d7 | |
Oron Peled | dbb5ba6db6 | |
Oron Peled | 2097f1adc5 | |
Oron Peled | d02361e99f | |
Oron Peled | 77a3d8b0a7 | |
Oron Peled | bd49fc9d95 | |
Oron Peled | 0e6b068e89 | |
Oron Peled | 9c61e40187 | |
Oron Peled | 5ee15a2337 | |
Oron Peled | 01faf597d6 | |
Tzafrir Cohen | 48b25e849f | |
Tzafrir Cohen | d239b8dc4d | |
Tzafrir Cohen | 4676ad6671 | |
Tzafrir Cohen | b471526700 | |
Russ Meyerriecks | 855772135c | |
Oron Peled | ec1ebffa89 | |
Tzafrir Cohen | 9afcde3f1e | |
Russ Meyerriecks | 9a181ccfbc | |
Tzafrir Cohen | 10c1cd196e | |
Tzafrir Cohen | 65ba28fe4a | |
Oron Peled | 66e2c3ba11 | |
Oron Peled | 94ca4a1bb4 | |
Oron Peled | af920cd079 | |
Tzafrir Cohen | b375bb80b8 | |
Oron Peled | 0090086bce | |
Oron Peled | f21b592f68 | |
Oron Peled | d63812bd73 | |
Oron Peled | bf9500ab32 | |
Oron Peled | 703db3bcc3 | |
Oron Peled | b5b32a438f | |
Oron Peled | 4cc7df1089 | |
Oron Peled | ac6f437317 | |
Oron Peled | b054abb7e9 | |
Oron Peled | ee83afa669 | |
Oron Peled | 5ac7fef4b2 | |
Oron Peled | 6df9a492a0 | |
Oron Peled | fc620819b6 | |
Oron Peled | 723b3ce87f | |
Oron Peled | 5fd1ce5ca0 | |
Oron Peled | 41532ca8a1 | |
Oron Peled | fbb6c1a17e | |
Oron Peled | 131d694054 | |
Oron Peled | 010c4d836c | |
Oron Peled | 025b9a5593 | |
Oron Peled | c863d1d2c2 | |
Tzafrir Cohen | 77730a9059 |
|
@ -1,16 +1,36 @@
|
|||
*~
|
||||
*.o
|
||||
*.lo
|
||||
*.a
|
||||
*.so
|
||||
*.la
|
||||
.*.o.d
|
||||
.*.lo.d
|
||||
*.asciidoc
|
||||
*.html
|
||||
.deps
|
||||
.libs
|
||||
.dirstamp
|
||||
.version
|
||||
/.pc
|
||||
Makefile
|
||||
Makefile.in
|
||||
auxdir/
|
||||
build_tools/menuselect-deps
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
autoconfig.h
|
||||
autoconfig.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.guess
|
||||
config.ignore
|
||||
configure
|
||||
dahdi_cfg
|
||||
dahdi_diag
|
||||
dahdi_maint
|
||||
dahdi_monitor
|
||||
dahdi_pcap
|
||||
dahdi_scan
|
||||
dahdi_speed
|
||||
dahdi_test
|
||||
|
@ -22,17 +42,19 @@ hdlcgen
|
|||
hdlcstress
|
||||
hdlctest
|
||||
hdlcverify
|
||||
libtonezone.a
|
||||
libtonezone.so
|
||||
libtool
|
||||
m4/
|
||||
makeopts
|
||||
patgen
|
||||
patlooptest
|
||||
pattest
|
||||
sethdlc
|
||||
stamp-h1
|
||||
timertest
|
||||
tonezone.lo
|
||||
tonezones.txt
|
||||
version.c
|
||||
xpp/*.check
|
||||
xpp/.depend
|
||||
xpp/.octasic.depend
|
||||
xpp/.perlcheck
|
||||
|
@ -48,4 +70,10 @@ xpp/test_parse
|
|||
xpp/twinstar.8
|
||||
xpp/xpp_blink.8
|
||||
xpp/xpp_sync.8
|
||||
xpp/xtalk/xlist_test
|
||||
xpp/xtalk/xtalk_raw_test
|
||||
xpp/xtalk/xtalk_send
|
||||
xpp/xtalk/xtalk_test
|
||||
xpp/xtalk/xusb_test
|
||||
xpp/xtalk/xusb_test_bypath
|
||||
zonedata.lo
|
||||
|
|
390
Makefile
390
Makefile
|
@ -1,390 +0,0 @@
|
|||
#
|
||||
# Makefile for DAHDI tools
|
||||
#
|
||||
# Copyright (C) 2001-2010 Digium, Inc.
|
||||
#
|
||||
#
|
||||
|
||||
ifeq ($(strip $(foreach var,clean distclean dist-clean update,$(findstring $(var),$(MAKECMDGOALS)))),)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(foreach var,clean distclean dist-clean update,$(findstring $(var),$(MAKECMDGOALS)))),)
|
||||
ifneq ($(wildcard makeopts),)
|
||||
include makeopts
|
||||
endif
|
||||
endif
|
||||
|
||||
SUBDIRS_UTILS_ALL:= ppp
|
||||
SUBDIRS_UTILS := xpp
|
||||
|
||||
OPTFLAGS=-O2
|
||||
CFLAGS+=-I. $(OPTFLAGS) -g -fPIC -Wall -DBUILDING_TONEZONE #-DTONEZONE_DRIVER
|
||||
ifneq (,$(findstring ppc,$(UNAME_M)))
|
||||
CFLAGS+=-fsigned-char
|
||||
endif
|
||||
ifneq (,$(findstring x86_64,$(UNAME_M)))
|
||||
CFLAGS+=-m64
|
||||
endif
|
||||
|
||||
ifeq ($(DAHDI_DEVMODE),yes)
|
||||
CFLAGS+=-Werror -Wunused -Wundef $(DAHDI_DECLARATION_AFTER_STATEMENT) -Wmissing-format-attribute -Wformat-security #-Wformat=2
|
||||
endif
|
||||
|
||||
ROOT_PREFIX=
|
||||
|
||||
# extra cflags to build dependencies. Recursively expanded.
|
||||
MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP
|
||||
|
||||
CFLAGS+=$(DAHDI_INCLUDE)
|
||||
|
||||
CHKCONFIG := $(wildcard /sbin/chkconfig)
|
||||
UPDATE_RCD := $(wildcard /usr/sbin/update-rc.d)
|
||||
ifeq (,$(DESTDIR))
|
||||
ifneq (,$(CHKCONFIG))
|
||||
ADD_INITD := $(CHKCONFIG) --add dahdi
|
||||
else
|
||||
ifneq (,$(UPDATE_RCD))
|
||||
ADD_INITD := $(UPDATE_RCD) dahdi defaults 15 30
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
INITRD_DIR := $(firstword $(wildcard $(DESTDIR)/etc/rc.d/init.d $(DESTDIR)/etc/init.d))
|
||||
ifneq (,$(INITRD_DIR))
|
||||
INIT_TARGET := $(INITRD_DIR)/dahdi
|
||||
COPY_INITD := install -D dahdi.init $(INIT_TARGET)
|
||||
endif
|
||||
|
||||
RCCONF_FILE = /etc/dahdi/init.conf
|
||||
MODULES_FILE = /etc/dahdi/modules
|
||||
GENCONF_FILE = /etc/dahdi/genconf_parameters
|
||||
MODPROBE_FILE = /etc/modprobe.d/dahdi.conf
|
||||
BLACKLIST_FILE = /etc/modprobe.d/dahdi.blacklist.conf
|
||||
BASH_COMP_DIR = /etc/bash_completion.d
|
||||
BASH_COMP_FILE = $(BASH_COMP_DIR)/dahdi
|
||||
|
||||
NETSCR_DIR := $(firstword $(wildcard $(DESTDIR)/etc/sysconfig/network-scripts ))
|
||||
ifneq (,$(NETSCR_DIR))
|
||||
NETSCR_TARGET := $(NETSCR_DIR)/ifup-hdlc
|
||||
COPY_NETSCR := install -D ifup-hdlc $(NETSCR_TARGET)
|
||||
endif
|
||||
|
||||
TOOLSVERSION=$(shell build_tools/make_version . dahdi/tools)
|
||||
|
||||
LTZ_A:=libtonezone.a
|
||||
LTZ_A_OBJS:=zonedata.o tonezone.o version.o
|
||||
LTZ_SO:=libtonezone.so
|
||||
LTZ_SO_OBJS:=zonedata.lo tonezone.lo version.o
|
||||
LTZ_SO_MAJOR_VER:=2
|
||||
LTZ_SO_MINOR_VER:=0
|
||||
|
||||
# sbindir, libdir, includedir and mandir are defined in makeopts
|
||||
# (from configure).
|
||||
BIN_DIR:=$(sbindir)
|
||||
LIB_DIR:=$(libdir)
|
||||
INC_DIR:=$(includedir)/dahdi
|
||||
MAN_DIR:=$(mandir)/man8
|
||||
DATA_DIR:=${datadir}/dahdi
|
||||
CONFIG_DIR:=$(sysconfdir)/dahdi
|
||||
CONFIG_FILE:=$(CONFIG_DIR)/system.conf
|
||||
UDEVRULES_DIR:=$(sysconfdir)/udev/rules.d
|
||||
|
||||
# Utilities we build with a standard build procedure:
|
||||
UTILS = dahdi_tool dahdi_test dahdi_monitor dahdi_speed sethdlc dahdi_cfg \
|
||||
fxstest fxotune dahdi_diag dahdi_scan
|
||||
|
||||
# some tests:
|
||||
UTILS += patgen pattest patlooptest hdlcstress hdlctest hdlcgen \
|
||||
hdlcverify timertest dahdi_maint
|
||||
|
||||
|
||||
BINS:=fxotune dahdi_cfg dahdi_monitor dahdi_speed dahdi_test dahdi_scan dahdi_maint
|
||||
ifeq (1,$(PBX_NEWT))
|
||||
BINS += dahdi_tool
|
||||
endif
|
||||
ifeq (1,$(PBX_HDLC))
|
||||
BINS += sethdlc
|
||||
endif
|
||||
ASSIGNED_DATA_SCRIPTS:=\
|
||||
dahdi_handle_device \
|
||||
dahdi_span_config \
|
||||
dahdi_auto_assign_compat \
|
||||
span_config.d/10-dahdi-cfg \
|
||||
span_config.d/20-fxotune \
|
||||
span_config.d/50-asterisk \
|
||||
handle_device.d/10-span-types \
|
||||
handle_device.d/20-span-assignments
|
||||
|
||||
ASSIGNED_UTILS:=dahdi_span_assignments dahdi_span_types \
|
||||
dahdi_waitfor_span_assignments
|
||||
ASSIGNED_CONF:=assigned-spans.conf.sample span-types.conf.sample
|
||||
|
||||
MAN_PAGES:= \
|
||||
$(wildcard $(BINS:%=doc/%.8)) \
|
||||
$(wildcard $(ASSIGNED_UTILS:%=doc/%.8))
|
||||
|
||||
TEST_BINS:=patgen pattest patlooptest hdlcstress hdlctest hdlcgen hdlcverify timertest dahdi_maint
|
||||
# All the man pages. Not just installed ones:
|
||||
GROFF_PAGES := $(wildcard doc/*.8 xpp/*.8)
|
||||
GROFF_HTML := $(GROFF_PAGES:%=%.html)
|
||||
|
||||
GENERATED_DOCS := $(GROFF_HTML) README.html README.Astribank.html
|
||||
|
||||
all: prereq programs
|
||||
|
||||
libs: $(LTZ_SO) $(LTZ_A)
|
||||
|
||||
utils-subdirs:
|
||||
@for dir in $(SUBDIRS_UTILS); do \
|
||||
$(MAKE) -C $$dir; \
|
||||
done
|
||||
|
||||
programs: libs utils
|
||||
|
||||
utils: $(BINS) utils-subdirs
|
||||
|
||||
version.c: FORCE
|
||||
@TOOLSVERSION="${TOOLSVERSION}" build_tools/make_version_c > $@.tmp
|
||||
@if cmp -s $@.tmp $@ ; then :; else \
|
||||
mv $@.tmp $@ ; \
|
||||
fi
|
||||
@rm -f $@.tmp
|
||||
|
||||
tests: $(TEST_BINS)
|
||||
|
||||
$(UTILS): %: %.o
|
||||
|
||||
$(UTILS): version.o
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $<
|
||||
|
||||
%.lo: %.c
|
||||
$(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $<
|
||||
|
||||
%: %.o
|
||||
$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
|
||||
|
||||
prereq: config.status
|
||||
|
||||
dahdi_tool: CFLAGS+=$(NEWT_INCLUDE)
|
||||
dahdi_tool: LIBS+=$(NEWT_LIB)
|
||||
|
||||
dahdi_speed: CFLAGS+=-O0
|
||||
|
||||
$(LTZ_A): $(LTZ_A_OBJS)
|
||||
ar rcs $@ $^
|
||||
ranlib $@
|
||||
|
||||
$(LTZ_SO): $(LTZ_SO_OBJS)
|
||||
$(CC) $(CFLAGS) -shared -Wl,-soname,$(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) -o $@ $^ -lm
|
||||
|
||||
dahdi_cfg: $(LTZ_A)
|
||||
dahdi_cfg: LIBS+=-lm -lpthread
|
||||
dahdi_pcap:
|
||||
$(CC) $(CFLAGS) dahdi_pcap.c -lpcap -o $@ $<
|
||||
|
||||
|
||||
fxstest: $(LTZ_SO)
|
||||
fxstest: LIBS+=-lm
|
||||
fxotune: LIBS+=-lm
|
||||
|
||||
tonezones.txt: zonedata.c
|
||||
perl -ne 'next unless (/\.(country|description) = *"([^"]*)/); \
|
||||
print (($$1 eq "country")? "* $$2\t":"$$2\n");' $< \
|
||||
>$@
|
||||
|
||||
%.asciidoc: %.sample
|
||||
perl -n -e \
|
||||
'if (/^#($$|\s)(.*)/){ if (!$$in_doc){print "\n"}; $$in_doc=1; print "$$2\n" } else { if ($$in_doc){print "\n"}; $$in_doc=0; print " $$_" }' \
|
||||
$< \
|
||||
| perl -p -e 'if (/^ #?(\w+)=/ && ! exists $$cfgs{$$1}){my $$cfg = $$1; $$cfgs{$$cfg} = 1; s/^/\n[[cfg_$$cfg]]\n/}' >$@
|
||||
|
||||
docs: $(GENERATED_DOCS)
|
||||
|
||||
genconf_parameters.sample: xpp/genconf_parameters
|
||||
cp $< $@
|
||||
|
||||
README.html: README system.conf.asciidoc init.conf.asciidoc tonezones.txt \
|
||||
UPGRADE.txt genconf_parameters.asciidoc assigned-spans.conf.asciidoc \
|
||||
span-types.conf.asciidoc
|
||||
$(ASCIIDOC) -n -a toc -a toclevels=4 $<
|
||||
|
||||
README.Astribank.html: xpp/README.Astribank
|
||||
$(ASCIIDOC) -o $@ -n -a toc -a toclevels=4 $<
|
||||
|
||||
# on Debian: this requires the full groff, not just groff-base.
|
||||
%.8.html: %.8
|
||||
man -Thtml $^ >$@
|
||||
|
||||
htmlman: $(GROFF_HTML)
|
||||
|
||||
install: all install-programs
|
||||
@echo "###################################################"
|
||||
@echo "###"
|
||||
@echo "### DAHDI tools installed successfully."
|
||||
@echo "### If you have not done so before, install init scripts with:"
|
||||
@echo "###"
|
||||
@echo "### make config"
|
||||
@echo "###"
|
||||
@echo "###################################################"
|
||||
|
||||
install-programs: install-utils install-libs
|
||||
|
||||
install-utils: utils install-utils-subdirs
|
||||
ifneq (,$(BINS))
|
||||
install -d $(DESTDIR)$(BIN_DIR)
|
||||
install $(BINS) $(DESTDIR)$(BIN_DIR)/
|
||||
install -d $(DESTDIR)$(MAN_DIR)
|
||||
install -m 644 $(MAN_PAGES) $(DESTDIR)$(MAN_DIR)/
|
||||
endif
|
||||
ifeq (,$(wildcard $(DESTDIR)$(CONFIG_FILE)))
|
||||
$(INSTALL) -d $(DESTDIR)$(CONFIG_DIR)
|
||||
$(INSTALL) -m 644 system.conf.sample $(DESTDIR)$(CONFIG_FILE)
|
||||
endif
|
||||
install -d $(DESTDIR)$(DATA_DIR)
|
||||
tar cf - -C hotplug $(ASSIGNED_DATA_SCRIPTS) | tar xf - -C $(DESTDIR)$(DATA_DIR)/
|
||||
install $(ASSIGNED_UTILS) $(DESTDIR)/$(BIN_DIR)/
|
||||
install -m 644 $(ASSIGNED_CONF) $(DESTDIR)/$(CONFIG_DIR)/
|
||||
install -d $(DESTDIR)$(BASH_COMP_DIR)
|
||||
install -m 644 dahdi-bash-completion $(DESTDIR)$(BASH_COMP_FILE)
|
||||
|
||||
install-libs: libs
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)/$(LIB_DIR)
|
||||
$(INSTALL) -m 755 $(LTZ_A) $(DESTDIR)$(LIB_DIR)/
|
||||
$(INSTALL) -m 755 $(LTZ_SO) $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER)
|
||||
ifeq (,$(DESTDIR))
|
||||
if [ `id -u` = 0 ]; then \
|
||||
/sbin/ldconfig || : ;\
|
||||
fi
|
||||
endif
|
||||
rm -f $(DESTDIR)$(LIB_DIR)/$(LTZ_SO)
|
||||
$(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \
|
||||
$(DESTDIR)$(LIB_DIR)/$(LTZ_SO).$(LTZ_SO_MAJOR_VER)
|
||||
$(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \
|
||||
$(DESTDIR)$(LIB_DIR)/$(LTZ_SO)
|
||||
# Overwrite the 1.0 links out there. dahdi-tools 2.0.0 installed
|
||||
# 1.0 links but dahdi-tools changed them to 2.0 in order to explicitly
|
||||
# break applications linked with zaptel. But, this also meant that
|
||||
# applications linked with libtonezone.so.1.0 broke when dahdi-tools
|
||||
# 2.1.0 was installed.
|
||||
$(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \
|
||||
$(DESTDIR)$(LIB_DIR)/$(LTZ_SO).1.0
|
||||
$(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \
|
||||
$(DESTDIR)$(LIB_DIR)/$(LTZ_SO).1
|
||||
ifneq (no,$(USE_SELINUX))
|
||||
ifeq (,$(DESTDIR))
|
||||
/sbin/restorecon -v $(DESTDIR)$(LIB_DIR)/$(LTZ_SO)
|
||||
endif
|
||||
endif
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)/$(INC_DIR)
|
||||
$(INSTALL) -m 644 tonezone.h $(DESTDIR)$(INC_DIR)/
|
||||
|
||||
install-utils-subdirs:
|
||||
@for dir in $(SUBDIRS_UTILS); do \
|
||||
$(MAKE) -C $$dir install; \
|
||||
done
|
||||
|
||||
install-tests: tests
|
||||
ifneq (,$(TEST_BINS))
|
||||
install -d $(DESTDIR)$(BIN_DIR)
|
||||
install $(TEST_BINS) $(DESTDIR)$(BIN_DIR)/
|
||||
endif
|
||||
|
||||
config:
|
||||
ifneq (,$(COPY_INITD))
|
||||
$(COPY_INITD)
|
||||
endif
|
||||
ifeq (,$(wildcard $(DESTDIR)$(RCCONF_FILE)))
|
||||
$(INSTALL) -D -m 644 init.conf.sample $(DESTDIR)$(RCCONF_FILE)
|
||||
endif
|
||||
ifeq (,$(wildcard $(DESTDIR)$(MODULES_FILE)))
|
||||
$(INSTALL) -D -m 644 modules.sample $(DESTDIR)$(MODULES_FILE)
|
||||
endif
|
||||
ifeq (,$(wildcard $(DESTDIR)$(GENCONF_FILE)))
|
||||
$(INSTALL) -D -m 644 xpp/genconf_parameters $(DESTDIR)$(GENCONF_FILE)
|
||||
endif
|
||||
ifeq (,$(wildcard $(DESTDIR)$(MODPROBE_FILE)))
|
||||
$(INSTALL) -D -m 644 modprobe.conf.sample $(DESTDIR)$(MODPROBE_FILE)
|
||||
endif
|
||||
ifeq (,$(wildcard $(DESTDIR)$(BLACKLIST_FILE)))
|
||||
$(INSTALL) -D -m 644 blacklist.sample $(DESTDIR)$(BLACKLIST_FILE)
|
||||
endif
|
||||
$(INSTALL) -d $(DESTDIR)$(UDEVRULES_DIR)
|
||||
$(INSTALL) -D -m 644 dahdi.rules $(DESTDIR)$(UDEVRULES_DIR)/
|
||||
ifneq (,$(COPY_NETSCR))
|
||||
$(COPY_NETSCR)
|
||||
endif
|
||||
ifneq (,$(ADD_INITD))
|
||||
$(ADD_INITD)
|
||||
endif
|
||||
@echo "DAHDI has been configured."
|
||||
@echo ""
|
||||
@echo "List of detected DAHDI devices:"
|
||||
@echo ""
|
||||
@if [ `xpp/dahdi_hardware | tee /dev/stderr | wc -l` -eq 0 ]; then \
|
||||
echo "No hardware found"; \
|
||||
else \
|
||||
echo ""; \
|
||||
echo "run 'dahdi_genconf modules' to load support for only " ;\
|
||||
echo "the DAHDI hardware installed in this system. By "; \
|
||||
echo "default support for all DAHDI hardware is loaded at "; \
|
||||
echo "DAHDI start. "; \
|
||||
fi
|
||||
|
||||
update:
|
||||
@if [ -d .svn ]; then \
|
||||
echo "Updating from Subversion..." ; \
|
||||
svn update | tee update.out; \
|
||||
rm -f .version; \
|
||||
if [ `grep -c ^C update.out` -gt 0 ]; then \
|
||||
echo ; echo "The following files have conflicts:" ; \
|
||||
grep ^C update.out | cut -b4- ; \
|
||||
fi ; \
|
||||
rm -f update.out; \
|
||||
else \
|
||||
echo "Not under version control"; \
|
||||
fi
|
||||
|
||||
dist:
|
||||
@./build_tools/make_dist "dahdi-tools" "$(TOOLSVERSION)"
|
||||
|
||||
clean:
|
||||
rm -f $(BINS) $(TEST_BINS)
|
||||
rm -f *.o dahdi_cfg tzdriver sethdlc
|
||||
rm -f $(LTZ_SO) $(LTZ_A) *.lo
|
||||
@for dir in $(SUBDIRS_UTILS_ALL); do \
|
||||
$(MAKE) -C $$dir clean; \
|
||||
done
|
||||
@for dir in $(SUBDIRS_UTILS); do \
|
||||
$(MAKE) -C $$dir clean; \
|
||||
done
|
||||
rm -f libtonezone*
|
||||
rm -f fxotune
|
||||
rm -f core
|
||||
rm -f dahdi_cfg-shared fxstest
|
||||
rm -rf $(GENERATED_DOCS) *.asciidoc tonezones.txt
|
||||
rm -f dahdi_pcap
|
||||
|
||||
distclean: dist-clean
|
||||
|
||||
dist-clean: clean
|
||||
rm -f makeopts
|
||||
rm -f config.log config.status
|
||||
rm -f .*.d
|
||||
|
||||
config.status: configure
|
||||
@CFLAGS="" ./configure
|
||||
@echo "****"
|
||||
@echo "**** The configure script was just executed, so 'make' needs to be"
|
||||
@echo "**** restarted."
|
||||
@echo "****"
|
||||
@exit 1
|
||||
|
||||
.PHONY: distclean dist-clean clean all install programs tests devel data config update install-programs install-libs install-utils-subdirs utils-subdirs prereq dist
|
||||
|
||||
FORCE:
|
||||
|
||||
ifneq ($(wildcard .*.d),)
|
||||
include .*.d
|
||||
endif
|
|
@ -0,0 +1,197 @@
|
|||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
LEGACY_MAKE = \
|
||||
$(MAKE) -f $(srcdir)/Makefile.legacy \
|
||||
top_srcdir=$(top_srcdir) \
|
||||
srcdir=$(srcdir)
|
||||
|
||||
CFLAGS += -g -Wall -O2 $(DAHDI_INCLUDE)
|
||||
if DAHDI_DEVMODE
|
||||
CFLAGS += \
|
||||
-Werror \
|
||||
-Wunused \
|
||||
-Wundef \
|
||||
$(DAHDI_DECLARATION_AFTER_STATEMENT) \
|
||||
-Wmissing-format-attribute \
|
||||
-Wformat-security \
|
||||
#-Wformat=2
|
||||
endif
|
||||
|
||||
SUBDIRS = xpp doc hotplug trunkdev
|
||||
|
||||
if PPPD
|
||||
SUBDIRS += ppp
|
||||
endif
|
||||
|
||||
noinst_HEADERS = \
|
||||
bittest.h \
|
||||
dahdi_tools_version.h \
|
||||
fxotune.h \
|
||||
wavformat.h \
|
||||
#
|
||||
|
||||
sbin_PROGRAMS = \
|
||||
dahdi_test \
|
||||
dahdi_maint \
|
||||
dahdi_monitor \
|
||||
dahdi_cfg \
|
||||
dahdi_speed \
|
||||
dahdi_scan \
|
||||
fxotune
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
fxstest \
|
||||
patgen \
|
||||
pattest \
|
||||
patlooptest \
|
||||
dahdi_diag \
|
||||
timertest
|
||||
|
||||
dist_sbin_SCRIPTS = \
|
||||
dahdi_span_assignments \
|
||||
dahdi_waitfor_span_assignments \
|
||||
dahdi_span_types
|
||||
|
||||
if PBX_HDLC
|
||||
sbin_PROGRAMS += sethdlc
|
||||
noinst_PROGRAMS += hdlcstress hdlctest hdlcgen hdlcverify
|
||||
endif
|
||||
|
||||
# Libtool versioning for libtonezone:
|
||||
# Bump when interface changes
|
||||
LTZ_CURRENT = 2
|
||||
# Bump if interface change is backward compatible
|
||||
LTZ_AGE = 0
|
||||
# Bump if only implementation change
|
||||
LTZ_REVISION = 0
|
||||
|
||||
lib_LTLIBRARIES = libtonezone.la
|
||||
|
||||
libtonezone_la_SOURCES = \
|
||||
zonedata.c \
|
||||
tonezone.c \
|
||||
version.c
|
||||
dahdiinclude_HEADERS = tonezone.h
|
||||
libtonezone_la_CFLAGS = $(CFLAGS) -I$(srcdir) -DBUILDING_TONEZONE
|
||||
libtonezone_la_LDFLAGS = -version-info "$(LTZ_CURRENT):$(LTZ_REVISION):$(LTZ_AGE)"
|
||||
libtonezone_la_LIBADD = -lm
|
||||
|
||||
if PBX_PCAP
|
||||
noinst_PROGRAMS += dahdi_pcap
|
||||
dahdi_pcap_LDADD = -lpcap
|
||||
endif
|
||||
|
||||
patlooptest_LDADD = libtonezone.la
|
||||
fxstest_LDADD = libtonezone.la
|
||||
fxotune_LDADD = -lm
|
||||
dahdi_speed_CFLAGS = -O2
|
||||
|
||||
dahdi_maint_SOURCES = dahdi_maint.c version.c
|
||||
|
||||
if PBX_NEWT
|
||||
sbin_PROGRAMS += dahdi_tool
|
||||
dahdi_tool_CFLAGS = $(CFLAGS) $(NEWT_INCLUDE)
|
||||
dahdi_tool_LDADD = $(NEWT_LIB)
|
||||
endif
|
||||
|
||||
dahdi_cfg_LDFLAGS = -lpthread
|
||||
dahdi_cfg_LDADD = libtonezone.la
|
||||
|
||||
udevrulesdir = @udevrulesdir@
|
||||
udevrules_DATA = dahdi.rules
|
||||
|
||||
all-local:
|
||||
$(LEGACY_MAKE) all
|
||||
|
||||
clean-local:
|
||||
$(LEGACY_MAKE) clean
|
||||
|
||||
install-exec-hook:
|
||||
$(LEGACY_MAKE) install
|
||||
@echo "Compatibility symlinks (should be removed in the future)"
|
||||
ln -sf libtonezone.so.2.0.0 $(DESTDIR)$(libdir)/libtonezone.so.2.0
|
||||
|
||||
bashcompdir = $(sysconfdir)/bash_completion.d
|
||||
|
||||
install-data-hook:
|
||||
mkdir -p $(DESTDIR)$(bashcompdir)
|
||||
install -m 644 $(srcdir)/dahdi-bash-completion $(DESTDIR)$(bashcompdir)/dahdi
|
||||
|
||||
# Handle these files specially -- install them only with 'install-config'
|
||||
special_config_files = \
|
||||
init.conf.sample \
|
||||
blacklist.sample \
|
||||
modprobe.conf.sample \
|
||||
#
|
||||
|
||||
install-config:
|
||||
mkdir -p $(DESTDIR)$(dahdiconfdir)
|
||||
mkdir -p $(DESTDIR)$(sysconfdir)/modprobe.d
|
||||
install -m644 xpp/genconf_parameters $(DESTDIR)$(dahdiconfdir)/genconf_parameters
|
||||
install -m644 init.conf.sample $(DESTDIR)$(dahdiconfdir)/init.conf
|
||||
install -m644 blacklist.sample $(DESTDIR)$(sysconfdir)/modprobe.d/dahdi-blacklist.conf
|
||||
install -m644 modprobe.conf.sample $(DESTDIR)$(sysconfdir)/modprobe.d/dahdi.conf
|
||||
$(LEGACY_MAKE) config
|
||||
|
||||
dahdiconfdir = @sysconfdir@/dahdi
|
||||
dahdiconf_DATA = \
|
||||
system.conf.sample \
|
||||
assigned-spans.conf.sample \
|
||||
span-types.conf.sample \
|
||||
modules.sample \
|
||||
#
|
||||
|
||||
build_scripts = \
|
||||
build_tools/dahdi_svn_tarball \
|
||||
build_tools/dahdi_sysfs_copy \
|
||||
build_tools/dump_sys_state \
|
||||
build_tools/make_firmware_object.in \
|
||||
build_tools/make_tree \
|
||||
build_tools/make_version \
|
||||
build_tools/test_kernel_git \
|
||||
build_tools/uninstall-modules \
|
||||
#
|
||||
|
||||
.version:
|
||||
if ./build_tools/make_version . dahdi/tools > $@.tmp; then \
|
||||
mv "$@.tmp" "$@"; \
|
||||
fi
|
||||
|
||||
uninstall-hook:
|
||||
$(RM) $(DESTDIR)$(sysconfdir)/dahdi/span-types.conf.sample
|
||||
$(RM) $(DESTDIR)$(sysconfdir)/dahdi/assigned-spans.conf.sample
|
||||
$(RM) $(DESTDIR)$(sysconfdir)/dahdi/system.conf
|
||||
$(RM) $(DESTDIR)$(bashcompdir)/dahdi
|
||||
|
||||
docs:
|
||||
$(LEGACY_MAKE) $@
|
||||
|
||||
DISTCLEANFILES = makeopts config.log config.status .*.d
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
m4/libtool.m4 \
|
||||
m4/ltoptions.m4 \
|
||||
m4/ltsugar.m4 \
|
||||
m4/ltversion.m4 \
|
||||
m4/lt~obsolete.m4 \
|
||||
#
|
||||
|
||||
EXTRA_DIST = \
|
||||
.version \
|
||||
LICENSE \
|
||||
LICENSE.LGPL \
|
||||
UPGRADE.txt \
|
||||
bootstrap.sh \
|
||||
Makefile.legacy \
|
||||
dahdi.init \
|
||||
dahdi.xml \
|
||||
dahdi_pcap.c \
|
||||
ifup-hdlc \
|
||||
dahdi-bash-completion \
|
||||
$(special_config_files) \
|
||||
$(dahdiconf_DATA) \
|
||||
$(udevrules_DATA) \
|
||||
$(build_scripts) \
|
||||
#
|
||||
|
||||
.PHONY: docs config
|
|
@ -0,0 +1,133 @@
|
|||
#
|
||||
# Makefile for DAHDI tools
|
||||
#
|
||||
# Copyright (C) 2001-2010 Digium, Inc.
|
||||
#
|
||||
#
|
||||
|
||||
ifeq ($(strip $(foreach var,clean,$(findstring $(var),$(MAKECMDGOALS)))),)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(foreach var,clean,$(findstring $(var),$(MAKECMDGOALS)))),)
|
||||
ifneq ($(wildcard makeopts),)
|
||||
include makeopts
|
||||
endif
|
||||
endif
|
||||
|
||||
CHKCONFIG := $(wildcard /sbin/chkconfig)
|
||||
UPDATE_RCD := $(wildcard /usr/sbin/update-rc.d)
|
||||
ifeq (,$(DESTDIR))
|
||||
ifneq (,$(CHKCONFIG))
|
||||
ADD_INITD := $(CHKCONFIG) --add dahdi
|
||||
else
|
||||
ifneq (,$(UPDATE_RCD))
|
||||
ADD_INITD := $(UPDATE_RCD) dahdi defaults 15 30
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
INITRD_DIR := $(firstword $(wildcard $(DESTDIR)/etc/rc.d/init.d $(DESTDIR)/etc/init.d))
|
||||
ifneq (,$(INITRD_DIR))
|
||||
INIT_TARGET := $(INITRD_DIR)/dahdi
|
||||
COPY_INITD := install -D dahdi.init $(INIT_TARGET)
|
||||
endif
|
||||
|
||||
NETSCR_DIR := $(firstword $(wildcard $(DESTDIR)/etc/sysconfig/network-scripts ))
|
||||
ifneq (,$(NETSCR_DIR))
|
||||
NETSCR_TARGET := $(NETSCR_DIR)/ifup-hdlc
|
||||
COPY_NETSCR := install -D ifup-hdlc $(NETSCR_TARGET)
|
||||
endif
|
||||
|
||||
# sbindir, libdir, includedir and mandir are defined in makeopts
|
||||
# (from configure).
|
||||
LIB_DIR:=$(libdir)
|
||||
|
||||
# All the man pages. Not just installed ones:
|
||||
GROFF_PAGES := $(wildcard doc/*.8 xpp/*.8)
|
||||
GROFF_HTML := $(GROFF_PAGES:%=%.html)
|
||||
|
||||
GENERATED_DOCS := $(GROFF_HTML) README.html README.Astribank.html
|
||||
|
||||
all:
|
||||
|
||||
tonezones.txt: zonedata.c
|
||||
perl -ne 'next unless (/\.(country|description) = *"([^"]*)/); \
|
||||
print (($$1 eq "country")? "* $$2\t":"$$2\n");' $< \
|
||||
>$@
|
||||
|
||||
%.asciidoc: %.sample
|
||||
perl -n -e \
|
||||
'if (/^#($$|\s)(.*)/){ if (!$$in_doc){print "\n"}; $$in_doc=1; print "$$2\n" } else { if ($$in_doc){print "\n"}; $$in_doc=0; print " $$_" }' \
|
||||
$< \
|
||||
| perl -p -e 'if (/^ #?(\w+)=/ && ! exists $$cfgs{$$1}){my $$cfg = $$1; $$cfgs{$$cfg} = 1; s/^/\n[[cfg_$$cfg]]\n/}' >$@
|
||||
|
||||
docs: $(GENERATED_DOCS)
|
||||
|
||||
genconf_parameters.sample: xpp/genconf_parameters
|
||||
cp $< $@
|
||||
|
||||
README.html: README system.conf.asciidoc init.conf.asciidoc tonezones.txt \
|
||||
UPGRADE.txt genconf_parameters.asciidoc assigned-spans.conf.asciidoc \
|
||||
span-types.conf.asciidoc
|
||||
TZ=UTC $(ASCIIDOC) -n -a toc -a toclevels=4 $<
|
||||
|
||||
README.Astribank.html: xpp/README.Astribank
|
||||
TZ=UTC $(ASCIIDOC) -o $@ -n -a toc -a toclevels=4 $<
|
||||
|
||||
# on Debian: this requires the full groff, not just groff-base.
|
||||
%.8.html: %.8
|
||||
man -Thtml $^ >$@
|
||||
|
||||
htmlman: $(GROFF_HTML)
|
||||
|
||||
install: all install-programs
|
||||
@echo "###################################################"
|
||||
@echo "###"
|
||||
@echo "### DAHDI tools installed successfully."
|
||||
@echo "### If you have not done so before, install init scripts with:"
|
||||
@echo "###"
|
||||
@echo "### make install-config"
|
||||
@echo "###"
|
||||
@echo "###################################################"
|
||||
|
||||
install-programs: install-libs
|
||||
|
||||
install-libs:
|
||||
ifneq (no,$(USE_SELINUX))
|
||||
ifeq (,$(DESTDIR))
|
||||
/sbin/restorecon -v $(DESTDIR)$(LIB_DIR)/$(LTZ_SO)
|
||||
endif
|
||||
endif
|
||||
|
||||
config:
|
||||
ifneq (,$(COPY_INITD))
|
||||
$(COPY_INITD)
|
||||
endif
|
||||
ifneq (,$(COPY_NETSCR))
|
||||
$(COPY_NETSCR)
|
||||
endif
|
||||
ifneq (,$(ADD_INITD))
|
||||
$(ADD_INITD)
|
||||
endif
|
||||
@echo "DAHDI has been configured."
|
||||
@echo ""
|
||||
@echo "List of detected DAHDI devices:"
|
||||
@echo ""
|
||||
@if [ `xpp/dahdi_hardware | tee /dev/stderr | wc -l` -eq 0 ]; then \
|
||||
echo "No hardware found"; \
|
||||
else \
|
||||
echo ""; \
|
||||
echo "run 'dahdi_genconf modules' to load support for only " ;\
|
||||
echo "the DAHDI hardware installed in this system. By "; \
|
||||
echo "default support for all DAHDI hardware is loaded at "; \
|
||||
echo "DAHDI start. "; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
rm -f *.o tzdriver
|
||||
rm -f core
|
||||
rm -rf $(GENERATED_DOCS) *.asciidoc tonezones.txt
|
||||
|
||||
.PHONY: clean all install devel data config install-programs install-libs
|
||||
|
||||
FORCE:
|
60
README
60
README
|
@ -15,8 +15,9 @@ dahdi-linux before building dahdi-tools.
|
|||
Build System
|
||||
~~~~~~~~~~~~
|
||||
GCC and friends. Generally you will need to install the package gcc.
|
||||
There may be cases where you will need a specific version of gcc to build
|
||||
kernel modules.
|
||||
|
||||
Autotools (autoconf, automake and libtool) are needed if you clone from
|
||||
Git.
|
||||
|
||||
|
||||
Extra Libraries
|
||||
|
@ -24,20 +25,25 @@ Extra Libraries
|
|||
Some libraries are needed for extra utilities that are provided with
|
||||
DAHDI.
|
||||
|
||||
- libusb is needed for building fpga_load, needed for firmware loading of
|
||||
the Xorcom Astribank.
|
||||
- libusb is needed for building astribank_hexload, needed for firmware
|
||||
loading of the Xorcom Astribank.
|
||||
- libnewt is needed to build the optional but useful utility dahdi_tool.
|
||||
- libpcap is needed for building dahdi_pcap.
|
||||
- pppd is needed to build the dahdi pppd plugin.
|
||||
|
||||
|
||||
Installation
|
||||
~~~~~~~~~~~~
|
||||
Note: If using `sudo` to build/install, you may need to add /sbin to your PATH.
|
||||
----------------------------------
|
||||
# Only if you cloned from git:
|
||||
autoreconf -i
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
# To install init scripts and config files:
|
||||
#make config
|
||||
# To install some extra configuration files:
|
||||
#make install-config
|
||||
----------------------------------
|
||||
|
||||
|
||||
|
@ -49,18 +55,11 @@ There are some make targets that are provided to build or install just
|
|||
parts of DAHDI:
|
||||
|
||||
. Build targets:
|
||||
- make: Build DAHDI user-space programs and libraries. partial
|
||||
targets of it:
|
||||
* make 'utilname': builds 'utilname' alone (e.g: `make dahdi_diag`)
|
||||
* make utils: Build just the programs.
|
||||
* make libs: Build libtonezone.
|
||||
* make tests: Build testing binaries.
|
||||
- make: Build DAHDI user-space programs and libraries.
|
||||
- make docs: Generate some extra documentation files.
|
||||
. Install targets:
|
||||
- make install: Install everything. Sub-targets of it:
|
||||
* make install-utils: Installs most things.
|
||||
* make install-libs: Installs libtonezone.
|
||||
- make config: install configuration files (overriding existing ones).
|
||||
- make install-test: Install testing binaries.
|
||||
- make install: Install everything
|
||||
- make install-config: install configuration files
|
||||
|
||||
|
||||
Installation to a Subtree
|
||||
|
@ -76,8 +75,8 @@ This can be useful for any partial install target from the list above.
|
|||
|
||||
Options For ./configure
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The configure script executes various tests and based on them generates
|
||||
makeopts. You can pass it --with options and variable settings, for
|
||||
The configure script executes various tests and the build will depend on
|
||||
their result. You can pass it --with options and variable settings, for
|
||||
instance:
|
||||
|
||||
./configure --without-ncurses CC="gcc-4.10"
|
||||
|
@ -117,6 +116,29 @@ The configuration file of the dahdi init.d script is
|
|||
/etc/dahdi/init.conf . That file is used to override defaults that are
|
||||
set at the beginning of the init.d script.
|
||||
|
||||
/etc/dahdi/assigned-spans.conf
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Assigns span number and initial channel number for spans in each device.
|
||||
Just like system.conf it may be generated with dahdi_genconf:
|
||||
|
||||
dahdi_span_assignments auto
|
||||
dahdi_genconf
|
||||
|
||||
It may also be edited manually to allow reserving span and channel
|
||||
numbers for specific devices.
|
||||
|
||||
/etc/dahdi/span-types.conf
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Theoretically, this file is similar to assigned-spans.conf. It allows
|
||||
setting the type (E1/T1) of a "PRI" span. This cannot be configured
|
||||
anywhere else: it needs to be done before the span is assigned as it
|
||||
changes the number of channels the span has.
|
||||
|
||||
In practice most systems don't mix E1 and T1 and thus this file will
|
||||
typically have at most a single wild-card line setting all cards to be
|
||||
either E1 or T1.
|
||||
|
||||
|
||||
Reference Configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Sample system.conf
|
||||
|
|
114
autoconfig.h.in
114
autoconfig.h.in
|
@ -1,114 +0,0 @@
|
|||
/* autoconfig.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if your system has the DAHDI headers. */
|
||||
#undef HAVE_DAHDI
|
||||
|
||||
/* Define if your system has the DAHDI23 headers. */
|
||||
#undef HAVE_DAHDI23
|
||||
|
||||
/* Define DAHDI23 headers version */
|
||||
#undef HAVE_DAHDI23_VERSION
|
||||
|
||||
/* Define DAHDI headers version */
|
||||
#undef HAVE_DAHDI_VERSION
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <linux/soundcard.h> header file. */
|
||||
#undef HAVE_LINUX_SOUNDCARD_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define this to indicate the ${NEWT_DESCRIP} library */
|
||||
#undef HAVE_NEWT
|
||||
|
||||
/* Define to indicate the ${NEWT_DESCRIP} library version */
|
||||
#undef HAVE_NEWT_VERSION
|
||||
|
||||
/* Define to 1 if you have the `semtimedop' function. */
|
||||
#undef HAVE_SEMTIMEDOP
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/soundcard.h> header file. */
|
||||
#undef HAVE_SYS_SOUNDCARD_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define this to indicate the ${USB_DESCRIP} library */
|
||||
#undef HAVE_USB
|
||||
|
||||
/* Define to indicate the ${USB_DESCRIP} library version */
|
||||
#undef HAVE_USB_VERSION
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
|
@ -1,26 +0,0 @@
|
|||
#! /bin/sh
|
||||
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo >&2 "Usage: $0 <package> <version>"
|
||||
exit 1
|
||||
fi
|
||||
package="$1"
|
||||
version="$2"
|
||||
tarball_prefix="$package-$version"
|
||||
echo "I: Making dist tarball for $tarball_prefix"
|
||||
tarball_name="$tarball_prefix.tar.gz"
|
||||
|
||||
tmp_work_dir=".tmp"
|
||||
tmp_version_dir="$tmp_work_dir/$tarball_prefix"
|
||||
|
||||
if [ "$DESTDIR" != '' ]; then
|
||||
destdir="$DESTDIR/"
|
||||
fi
|
||||
output="$destdir$tarball_name"
|
||||
|
||||
mkdir -p "$tmp_version_dir"
|
||||
git archive --format tar HEAD | tar xf - -C "$tmp_version_dir"
|
||||
echo "$version" > "$tmp_version_dir/.version"
|
||||
tar czf "$output" -C "$tmp_work_dir" "$tarball_prefix"
|
||||
rm -rf "$tmp_work_dir"
|
||||
echo "I: tarball is ready: '$output'"
|
|
@ -68,6 +68,8 @@ elif [ -d ${1}/.git ]; then
|
|||
# options.
|
||||
VERSION=GIT-`git rev-parse --short --verify HEAD`${MODIFIED}
|
||||
fi
|
||||
VERSION=${VERSION##*/} # Remove leading slashes: upsteram/2.10.2
|
||||
VERSION=${VERSION#[1-9]%} # Remove 1% from tag (tag from Debian epoch)
|
||||
echo ${VERSION}
|
||||
else
|
||||
PARTS=`LANG=C git log --pretty=full | grep -F "git-svn-id:" | head -1 | awk '{print $2;}' | sed -e s:^.*/svn/$2/:: | sed -e 's:/: :g' | sed -e 's/@.*$//g'`
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
#!/bin/sh
|
||||
cat << END
|
||||
/*
|
||||
* version.c
|
||||
* Automatically generated
|
||||
*/
|
||||
|
||||
const char dahdi_tools_version[] = "DAHDI Tools Version - ${TOOLSVERSION}";
|
||||
|
||||
END
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
210
configure.ac
210
configure.ac
|
@ -2,29 +2,65 @@
|
|||
|
||||
AC_PREREQ(2.59)
|
||||
|
||||
m4_define([TOOLSVERSION],
|
||||
m4_define([short_version],
|
||||
m4_bpatsubst(m4_esyscmd([build_tools/make_version . dahdi/tools]),
|
||||
[\([0-9.]*\)\(\w\|\W\)*],
|
||||
[\1]))
|
||||
AC_INIT(dahdi, TOOLSVERSION, www.asterisk.org)
|
||||
AC_INIT([dahdi-tools], short_version, [www.asterisk.org])
|
||||
|
||||
# check existence of the package
|
||||
AC_CONFIG_SRCDIR([dahdi_cfg.c])
|
||||
AC_CONFIG_AUX_DIR([auxdir])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
|
||||
build_version=`build_tools/make_version . dahdi/tools`
|
||||
AC_SUBST([BUILD_VERSION], "$build_version")
|
||||
|
||||
# enable nice build output on automake1.11
|
||||
m4_pattern_allow([AM_DEFAULT_VERBOSITY])
|
||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],[AM_DEFAULT_VERBOSITY=1])
|
||||
AM_CONDITIONAL([SILENT_RULES], [test "$AM_DEFAULT_VERBOSITY" = '0'])
|
||||
|
||||
AC_COPYRIGHT("dahdi-tools")
|
||||
AC_REVISION($Revision$)
|
||||
|
||||
ac_default_prefix=/usr
|
||||
if test ${sysconfdir} = '${prefix}/etc'; then
|
||||
sysconfdir=/etc
|
||||
fi
|
||||
if test ${mandir} = '${prefix}/man'; then
|
||||
mandir=/usr/share/man
|
||||
fi
|
||||
# Preserve old defaults if called without --prefix or --prefix=/usr
|
||||
# prefix=/usr
|
||||
# sysconfdir=/etc
|
||||
|
||||
if test ${localstatedir} = '${prefix}/var'; then
|
||||
localstatedir=/var
|
||||
ac_default_prefix=/usr
|
||||
if test "$prefix" = 'NONE' -o "$prefix" = '/usr'; then
|
||||
if test ${sysconfdir} = '${prefix}/etc'; then
|
||||
sysconfdir=/etc
|
||||
fi
|
||||
if test ${mandir} = '${prefix}/man'; then
|
||||
mandir=/usr/share/man
|
||||
fi
|
||||
|
||||
if test ${localstatedir} = '${prefix}/var'; then
|
||||
localstatedir=/var
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([dahditoolsdir], ['${datadir}/dahdi'])
|
||||
AC_SUBST([dahdiincludedir], ['${includedir}/dahdi'])
|
||||
|
||||
# Where to install udev rules?
|
||||
# * Our default is $sysconfdir/udev/rules.d:
|
||||
# - This preserve legacy location.
|
||||
# - It doesn't write into modern vendor supplied location (/lib/udev/rules.d)
|
||||
# - It doesn't break "make distcheck" (where everything should be relative
|
||||
# to prefix.
|
||||
# * Packagers are encouraged to use --udevrules=/lib/udev/rules.d
|
||||
#
|
||||
m4_define([_UDEV_RULES_DIR_DEFAULT], [${sysconfdir}/udev/rules.d])dnl
|
||||
AC_ARG_WITH(udevrules,
|
||||
[AS_HELP_STRING([--with-udevrules=PATH],
|
||||
[Location of UDEV rules @<:@default=]_UDEV_RULES_DIR_DEFAULT[@:>@])],
|
||||
[udevrulesdir=$withval],
|
||||
[udevrulesdir=]'_UDEV_RULES_DIR_DEFAULT'
|
||||
)
|
||||
AC_SUBST([udevrulesdir], "$udevrulesdir")
|
||||
|
||||
# specify output header file
|
||||
AC_CONFIG_HEADER(autoconfig.h)
|
||||
|
@ -32,15 +68,18 @@ AC_CONFIG_HEADER(autoconfig.h)
|
|||
# This needs to be before any macros that use the C compiler
|
||||
AC_GNU_SOURCE
|
||||
|
||||
AC_CHECK_HEADERS([sys/soundcard.h linux/soundcard.h])
|
||||
|
||||
AC_CHECK_TOOL([LD], [ld])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_AWK
|
||||
AC_PROG_LIBTOOL
|
||||
AST_CHECK_GNU_MAKE
|
||||
|
||||
test_obj=conftest.o
|
||||
|
@ -70,6 +109,35 @@ AC_SUBST(DOWNLOAD)
|
|||
|
||||
AC_LANG(C)
|
||||
|
||||
AC_PATH_PROG([PERL], [perl])
|
||||
if test "$PERL" = ''; then
|
||||
AC_MSG_ERROR(perl is mandatory)
|
||||
fi
|
||||
# Where to install perl modules?
|
||||
# * Packagers are encouraged to use the result of "perl -V:vendorlib"
|
||||
# * Our default is:
|
||||
# - The result of "perl -V:sitelib" for our default prefix (/usr)
|
||||
# - The "$datadir/perl5" directory otherwise (e.g: during "make distcheck")
|
||||
#
|
||||
AC_MSG_CHECKING(for perl libdir)
|
||||
m4_define([_PERL_LIBDIR_DEFAULT], [${datadir}/perl5])dnl
|
||||
AC_ARG_WITH(perllib,
|
||||
[AS_HELP_STRING([--with-perllib=PATH],
|
||||
[Location of perl modules @<:@default=]_PERL_LIBDIR_DEFAULT[, or perl -V:sitelib@:>@])],
|
||||
[perllibdir=$withval],
|
||||
[
|
||||
if test "$prefix" = 'NONE' -o "$prefix" = '/usr'; then
|
||||
eval `"$PERL" -V:sitelib`
|
||||
perllibdir="$sitelib"
|
||||
else
|
||||
perllibdir='_PERL_LIBDIR_DEFAULT'
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_SUBST([perllibdir], "$perllibdir")
|
||||
AC_MSG_RESULT([$perllibdir])
|
||||
AM_CONDITIONAL([PERL], [test "$perllibdir" != ''])
|
||||
|
||||
AC_ARG_ENABLE(dev-mode,
|
||||
[ --enable-dev-mode Turn on developer mode],
|
||||
[case "${enableval}" in
|
||||
|
@ -78,6 +146,7 @@ AC_ARG_ENABLE(dev-mode,
|
|||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-dev-mode) ;;
|
||||
esac])
|
||||
AC_SUBST(DAHDI_DEVMODE)
|
||||
AM_CONDITIONAL([DAHDI_DEVMODE], [test "$DAHDI_DEVMODE" = 'yes'])
|
||||
|
||||
AC_MSG_CHECKING(for -Wdeclaration-after-statement support)
|
||||
if $(${CC} -Wdeclaration-after-statement -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then
|
||||
|
@ -89,17 +158,106 @@ else
|
|||
fi
|
||||
AC_SUBST(DAHDI_DECLARATION_AFTER_STATEMENT)
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([sys/soundcard.h linux/soundcard.h])
|
||||
AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netinet/in.h stdint.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_INLINE
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SSIZE_T
|
||||
AC_TYPE_UINT16_T
|
||||
AC_TYPE_UINT32_T
|
||||
AC_TYPE_UINT8_T
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([m], [cos])
|
||||
AC_CHECK_LIB([pthread], [pthread_create])
|
||||
|
||||
AST_EXT_LIB_SETUP([DAHDI], [DAHDI], [dahdi])
|
||||
AST_EXT_LIB_SETUP([NEWT], [newt], [newt])
|
||||
AST_EXT_LIB_SETUP([USB], [usb], [usb])
|
||||
AST_EXT_LIB_SETUP([PCAP], [pcap], [pcap])
|
||||
|
||||
AST_C_DEFINE_CHECK([DAHDI], [DAHDI_CODE], [dahdi/user.h])
|
||||
DAHDI23_DIR="${DAHDI_DIR}"
|
||||
AST_C_DEFINE_CHECK([DAHDI23], [DAHDI_CONFIG_NTTE], [dahdi/user.h])
|
||||
AST_C_DEFINE_CHECK([TRUNKDEV], [DAHDI_TRUNKDEV_CREATE], [dahdi/user.h])
|
||||
AST_EXT_LIB_CHECK([NEWT], [newt], [newtBell], [newt.h])
|
||||
AST_EXT_LIB_CHECK([USB], [usb], [usb_init], [usb.h])
|
||||
AST_EXT_LIB_CHECK([PCAP], [pcap], [pcap_compile], [pcap.h])
|
||||
|
||||
saved_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $DAHDI_INCLUDE"
|
||||
AC_CHECK_DECL([DAHDI_TXMIRROR], [DAHDI_TXMIRROR=1], [DAHDI_TXMIRROR=0], [#include <dahdi/user.h>])
|
||||
CPPFLAGS="$saved_CPPFLAGS"
|
||||
|
||||
AM_CONDITIONAL([PBX_NEWT], [test "$PBX_NEWT" = "1"])
|
||||
AM_CONDITIONAL([PBX_PCAP], [test "$PBX_PCAP" = "1" -a "$DAHDI_TXMIRROR" = "1"])
|
||||
AM_CONDITIONAL([PBX_TRUNKDEV], [test "$PBX_TRUNKDEV" = "1"])
|
||||
|
||||
AC_CHECK_FUNCS([semtimedop])
|
||||
AC_CHECK_FUNCS([alarm bzero gettimeofday memset pow regcomp select socket strcasecmp strchr strdup strerror strrchr strstr strtol strtoul])
|
||||
AC_FUNC_ERROR_AT_LINE
|
||||
AC_FUNC_MALLOC
|
||||
|
||||
# What the user asked for? libusb/libusbx
|
||||
AC_ARG_WITH([libusbx],
|
||||
[AS_HELP_STRING([--without-libusbx], [Disable libusbx @<:@default=check@:>@])],
|
||||
[],
|
||||
[with_libusbx=check])
|
||||
AC_ARG_WITH([libusb],
|
||||
[AS_HELP_STRING([--without-libusb], [Disable libusb-0.1 @<:@default=check@:>@])],
|
||||
[],
|
||||
[with_libusb=check])
|
||||
|
||||
# LIBUSBX tests
|
||||
have_libusbx=
|
||||
AS_IF([test "$with_libusbx" != "no"],
|
||||
[PKG_CHECK_MODULES([LIBUSBX], [libusb-1.0],
|
||||
[AC_CHECK_LIB([usb-1.0], [libusb_error_name],
|
||||
[
|
||||
have_libusbx="yes"
|
||||
AC_DEFINE([HAVE_LIBUSBX], [1], [Define to 1 if you have <libusb.h>.])
|
||||
AC_SUBST([PBX_USB], [1])
|
||||
], [
|
||||
if test "$with_libusbx" != "yes"; then
|
||||
AC_MSG_NOTICE([Ignoring old libusb-1.0, trying fallback to old libusb])
|
||||
fi
|
||||
])
|
||||
], [:])
|
||||
], [])
|
||||
|
||||
AS_IF([test "$with_libusbx" = "yes" -a "$have_libusbx" = ""],
|
||||
[AC_MSG_ERROR([No libusbx found (--with-libusbx was given)])])
|
||||
|
||||
# LIBUSB tests
|
||||
have_libusb=
|
||||
AS_IF([test "$with_libusb" != "no"],
|
||||
[AS_IF([test "$have_libusbx" != ""],
|
||||
[
|
||||
AS_IF([test "$with_libusbx" = "check"], [
|
||||
AC_MSG_NOTICE([Skipping LIBUSB tests (have good LIBUSBX)])
|
||||
])
|
||||
], [
|
||||
PKG_CHECK_MODULES([LIBUSB], [libusb],
|
||||
[
|
||||
have_libusb="yes"
|
||||
AC_SUBST([PBX_USB], [1])
|
||||
]
|
||||
[AC_DEFINE([HAVE_LIBUSB], [1], [Define to 1 if you have <usb.h>.])],
|
||||
[:]
|
||||
)
|
||||
])
|
||||
], [])
|
||||
|
||||
AS_IF([test "$with_libusb" = "yes" -a "$have_libusb" = ""],
|
||||
[AC_MSG_ERROR([No libusb found (--with-libusb was given)])])
|
||||
|
||||
AM_CONDITIONAL([LIBUSBX], [test "$have_libusbx" != ""])
|
||||
AM_CONDITIONAL([LIBUSB], [test "$have_libusb" != ""])
|
||||
AM_CONDITIONAL([PBX_USB], [test "$PBX_USB" = "1"])
|
||||
|
||||
|
||||
PBX_HDLC=0
|
||||
AC_MSG_CHECKING([for GENERIC_HDLC_VERSION version 4 in linux/hdlc.h])
|
||||
|
@ -138,6 +296,7 @@ if test "x${PBX_HDLC}" != "x1"; then
|
|||
fi
|
||||
|
||||
AC_SUBST(PBX_HDLC)
|
||||
AM_CONDITIONAL([PBX_HDLC], [test "$PBX_HDLC" = "1"])
|
||||
|
||||
AC_ARG_WITH(selinux,
|
||||
[AS_HELP_STRING([--with-selinux],
|
||||
|
@ -193,6 +352,9 @@ case "$with_ppp" in
|
|||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(PPPD_VERSION)
|
||||
AM_CONDITIONAL([PPPD], [test "$PPPD_VERSION" != ''])
|
||||
|
||||
if test "x${PBX_DAHDI}" != "x1"; then
|
||||
AC_MSG_NOTICE([***])
|
||||
AC_MSG_NOTICE([*** Building this package requires DAHDI support. *** ])
|
||||
|
@ -211,7 +373,27 @@ fi
|
|||
|
||||
AC_SUBST(PPPD_VERSION)
|
||||
|
||||
AC_CONFIG_FILES([makeopts])
|
||||
# Taken from octasic-helper
|
||||
AC_SUBST([USE_OCTASIC], [yes])
|
||||
AM_CONDITIONAL([USE_OCTASIC], [test "$USE_OCTASIC" = 'yes'])
|
||||
octasic_dir='$(top_srcdir)/xpp/oct612x'
|
||||
AC_SUBST([OCTASIC_CFLAGS], ["-I$octasic_dir/include -I$octasic_dir/octdeviceapi -I$octasic_dir/octdeviceapi/oct6100api"])
|
||||
|
||||
AC_SUBST([TOOLSVERSION], m4_esyscmd([build_tools/make_version . dahdi/tools]))
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
makeopts
|
||||
version.c
|
||||
Makefile
|
||||
doc/Makefile
|
||||
hotplug/Makefile
|
||||
ppp/Makefile
|
||||
xpp/Makefile
|
||||
xpp/xtalk/Makefile
|
||||
xpp/oct612x/Makefile
|
||||
xpp/perl_modules/Makefile
|
||||
trunkdev/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
AC_MSG_NOTICE(*** dahdi-tools build successfully configured ***)
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/sh
|
||||
# jenkins build helper script for dahdi-tools. This is how we build on jenkins.osmocom.org
|
||||
|
||||
if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then
|
||||
echo "Error: We need to have scripts/osmo-deps.sh from http://git.osmocom.org/osmo-ci/ in PATH !"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
set -ex
|
||||
|
||||
base="$PWD"
|
||||
deps="$base/deps"
|
||||
inst="$deps/install"
|
||||
export deps inst
|
||||
|
||||
osmo-clean-workspace.sh
|
||||
|
||||
mkdir "$deps" || true
|
||||
|
||||
cd "$deps"
|
||||
if [ -d dahdi-linux ]; then
|
||||
(cd dahdi-linux && git fetch && git checkout -f -B master origin/master)
|
||||
else
|
||||
git clone https://git.osmocom.org/dahdi-linux
|
||||
fi
|
||||
|
||||
cd $base
|
||||
|
||||
autoreconf -fi
|
||||
./configure --with-dahdi="$deps/dahdi-linux"
|
||||
$MAKE $PARALLEL_MAKE
|
||||
|
||||
osmo-clean-workspace.sh
|
|
@ -48,7 +48,7 @@ __dahdi_span_types() {
|
|||
has_cmd=0
|
||||
for (( i=0; i < COMP_CWORD; i++)); do
|
||||
case "${COMP_WORDS[$i]}" in
|
||||
dumpconfig | list | set)
|
||||
dumpconfig | list | set | compare)
|
||||
has_cmd=1
|
||||
break
|
||||
;;
|
||||
|
@ -69,7 +69,7 @@ __dahdi_span_types() {
|
|||
grep -l '[EJT]1' /sys/devices/pci0000:00/0000:00:10.4/usb1/1-1/xbus-00/*/spantype 2>/dev/null | sed -e 's|/spantype||') )
|
||||
else
|
||||
COMPREPLY=( ${COMPREPLY[@]} $(compgen -W \
|
||||
'dumpconfig list set' -- $cur) )
|
||||
'dumpconfig list set compare' -- $cur) )
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
|
38
dahdi_cfg.c
38
dahdi_cfg.c
|
@ -90,11 +90,9 @@ static struct dahdi_lineconfig lc[DAHDI_MAX_SPANS];
|
|||
|
||||
static struct dahdi_chanconfig cc[DAHDI_MAX_CHANNELS];
|
||||
|
||||
static int current_span = 0;
|
||||
static int only_span = 0;
|
||||
static int restrict_channels = 0;
|
||||
static int selected_channels[DAHDI_MAX_CHANNELS];
|
||||
static int chan2span[DAHDI_MAX_CHANNELS];
|
||||
static int declared_spans[DAHDI_MAX_SPANS];
|
||||
|
||||
static struct dahdi_attach_echocan ae[DAHDI_MAX_CHANNELS];
|
||||
|
@ -333,20 +331,9 @@ static char *trim(char *buf)
|
|||
|
||||
static int skip_channel(int x)
|
||||
{
|
||||
int spanno = chan2span[x];
|
||||
|
||||
if (restrict_channels) {
|
||||
if (!selected_channels[x])
|
||||
return 1;
|
||||
/* sanity check */
|
||||
if (only_span) {
|
||||
if (spanno != 0 && only_span != spanno) {
|
||||
fprintf(stderr,
|
||||
"Only span %d. Skip selected channel %d from span %d\n",
|
||||
only_span, x, spanno);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (only_span && !declared_spans[only_span]) {
|
||||
fprintf(stderr,
|
||||
|
@ -354,8 +341,6 @@ static int skip_channel(int x)
|
|||
only_span);
|
||||
exit(1);
|
||||
}
|
||||
if (only_span && only_span != spanno)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -442,7 +427,6 @@ int spanconfig(char *keyword, char *args)
|
|||
error("Span number should be a valid span number, not '%s'\n", realargs[0]);
|
||||
return -1;
|
||||
}
|
||||
current_span = span;
|
||||
declared_spans[span] = 1;
|
||||
res = sscanf(realargs[1], "%d", &timing);
|
||||
if ((res != 1) || (timing < 0) || (timing > MAX_TIMING)) {
|
||||
|
@ -615,7 +599,6 @@ static int chanconfig(char *keyword, char *args)
|
|||
int master=0;
|
||||
int dacschan = 0;
|
||||
char *idle;
|
||||
int is_digital;
|
||||
bzero(chans, sizeof(chans));
|
||||
strtok(args, ":");
|
||||
idle = strtok(NULL, ":");
|
||||
|
@ -627,7 +610,6 @@ static int chanconfig(char *keyword, char *args)
|
|||
if (res <= 0)
|
||||
return -1;
|
||||
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
|
||||
is_digital = 0;
|
||||
if (chans[x]) {
|
||||
if (slineno[x]) {
|
||||
error("Channel %d already configured as '%s' at line %d\n", x, sig[x], slineno[x]);
|
||||
|
@ -673,7 +655,6 @@ static int chanconfig(char *keyword, char *args)
|
|||
return -1;
|
||||
cc[x].sigtype = DAHDI_SIG_CAS;
|
||||
sig[x] = sigtype_to_str(cc[x].sigtype);
|
||||
is_digital = 1;
|
||||
} else if (!strcasecmp(keyword, "dacs")) {
|
||||
/* Setup channel for monitor */
|
||||
cc[x].idlebits = dacschan;
|
||||
|
@ -684,7 +665,6 @@ static int chanconfig(char *keyword, char *args)
|
|||
cc[dacschan].sigtype = DAHDI_SIG_DACS;
|
||||
sig[x] = sigtype_to_str(cc[dacschan].sigtype);
|
||||
dacschan++;
|
||||
is_digital = 1;
|
||||
} else if (!strcasecmp(keyword, "dacsrbs")) {
|
||||
/* Setup channel for monitor */
|
||||
cc[x].idlebits = dacschan;
|
||||
|
@ -694,7 +674,6 @@ static int chanconfig(char *keyword, char *args)
|
|||
cc[dacschan].idlebits = x;
|
||||
cc[dacschan].sigtype = DAHDI_SIG_DACS_RBS;
|
||||
sig[x] = sigtype_to_str(cc[dacschan].sigtype);
|
||||
is_digital = 1;
|
||||
dacschan++;
|
||||
} else if (!strcasecmp(keyword, "unused")) {
|
||||
cc[x].sigtype = 0;
|
||||
|
@ -702,7 +681,6 @@ static int chanconfig(char *keyword, char *args)
|
|||
} else if (!strcasecmp(keyword, "indclear") || !strcasecmp(keyword, "bchan")) {
|
||||
cc[x].sigtype = DAHDI_SIG_CLEAR;
|
||||
sig[x] = sigtype_to_str(cc[x].sigtype);
|
||||
is_digital = 1;
|
||||
} else if (!strcasecmp(keyword, "clear")) {
|
||||
sig[x] = sigtype_to_str(DAHDI_SIG_CLEAR);
|
||||
if (master) {
|
||||
|
@ -712,7 +690,6 @@ static int chanconfig(char *keyword, char *args)
|
|||
cc[x].sigtype = DAHDI_SIG_CLEAR;
|
||||
master = x;
|
||||
}
|
||||
is_digital = 1;
|
||||
} else if (!strcasecmp(keyword, "rawhdlc")) {
|
||||
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCRAW);
|
||||
if (master) {
|
||||
|
@ -722,7 +699,6 @@ static int chanconfig(char *keyword, char *args)
|
|||
cc[x].sigtype = DAHDI_SIG_HDLCRAW;
|
||||
master = x;
|
||||
}
|
||||
is_digital = 1;
|
||||
} else if (!strcasecmp(keyword, "nethdlc")) {
|
||||
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCNET);
|
||||
memset(cc[x].netdev_name, 0, sizeof(cc[x].netdev_name));
|
||||
|
@ -736,7 +712,6 @@ static int chanconfig(char *keyword, char *args)
|
|||
}
|
||||
master = x;
|
||||
}
|
||||
is_digital = 1;
|
||||
} else if (!strcasecmp(keyword, "fcshdlc")) {
|
||||
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCFCS);
|
||||
if (master) {
|
||||
|
@ -746,19 +721,15 @@ static int chanconfig(char *keyword, char *args)
|
|||
cc[x].sigtype = DAHDI_SIG_HDLCFCS;
|
||||
master = x;
|
||||
}
|
||||
is_digital = 1;
|
||||
} else if (!strcasecmp(keyword, "dchan")) {
|
||||
sig[x] = "D-channel";
|
||||
cc[x].sigtype = DAHDI_SIG_HDLCFCS;
|
||||
is_digital = 1;
|
||||
} else if (!strcasecmp(keyword, "hardhdlc")) {
|
||||
sig[x] = "Hardware assisted D-channel";
|
||||
cc[x].sigtype = DAHDI_SIG_HARDHDLC;
|
||||
is_digital = 1;
|
||||
} else if (!strcasecmp(keyword, "mtp2")) {
|
||||
sig[x] = "MTP2";
|
||||
cc[x].sigtype = DAHDI_SIG_MTP2;
|
||||
is_digital = 1;
|
||||
} else {
|
||||
fprintf(stderr, "Huh? (%s)\n", keyword);
|
||||
}
|
||||
|
@ -770,11 +741,6 @@ static int chanconfig(char *keyword, char *args)
|
|||
fprintf(stderr, "WARNING: idlebits are not valid on %s channels.\n", sig[x]);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_digital)
|
||||
chan2span[x] = current_span;
|
||||
else
|
||||
current_span = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -1617,6 +1583,10 @@ int main(int argc, char *argv[])
|
|||
fprintf(stderr, "%s\n", dahdi_tools_version);
|
||||
}
|
||||
|
||||
if (!restrict_channels && only_span) {
|
||||
error("-S requires -C\n");
|
||||
goto finish;
|
||||
}
|
||||
if (!restrict_channels && !only_span) {
|
||||
bool all_assigned = wait_for_all_spans_assigned(5);
|
||||
|
||||
|
|
36
dahdi_pcap.c
36
dahdi_pcap.c
|
@ -41,6 +41,7 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <linux/if_packet.h>
|
||||
|
||||
#define BLOCK_SIZE 512
|
||||
#define MAX_CHAN 16
|
||||
|
@ -100,7 +101,7 @@ int make_mirror(long type, int chan)
|
|||
return fd;
|
||||
}
|
||||
|
||||
int log_packet(struct chan_fds * fd, char is_read, pcap_dumper_t * dump)
|
||||
int log_packet(struct chan_fds * fd, char is_read, int we_are_network, pcap_dumper_t * dump)
|
||||
{
|
||||
unsigned char buf[BLOCK_SIZE * 4];
|
||||
int res = 0;
|
||||
|
@ -161,10 +162,10 @@ int log_packet(struct chan_fds * fd, char is_read, pcap_dumper_t * dump)
|
|||
hdr.caplen = res+sizeof(struct lapd_sll_hdr)-2;
|
||||
hdr.len = res+sizeof(struct lapd_sll_hdr)-2;
|
||||
|
||||
lapd->sll_pkttype = 3;
|
||||
lapd->sll_pkttype = htons(is_read ? PACKET_HOST : PACKET_OUTGOING);
|
||||
lapd->sll_hatype = 0;
|
||||
lapd->sll_halen = res;
|
||||
// lapd->sll_addr = ???
|
||||
lapd->sll_halen = htons(8);
|
||||
lapd->sll_addr[0] = we_are_network;
|
||||
lapd->sll_protocol[0] = 0x00;
|
||||
lapd->sll_protocol[1] = 0x30;
|
||||
|
||||
|
@ -197,10 +198,11 @@ void usage()
|
|||
printf("Usage: dahdi_pcap [OPTIONS]\n");
|
||||
printf("Capture packets from DAHDI channels to pcap file\n\n");
|
||||
printf("Options:\n");
|
||||
printf(" -p, --proto=[mtp2|lapd] The protocol to capture, default mtp2\n");
|
||||
printf(" -c, --chan=<channels> Comma separated list of channels to capture from, max %d. Mandatory\n", MAX_CHAN);
|
||||
printf(" -f, --file=<filename> The pcap file to capture to. Mandatory\n");
|
||||
printf(" -h, --help Display this text\n");
|
||||
printf(" -p, --proto=[mtp2|lapd] The protocol to capture, default mtp2\n");
|
||||
printf(" -c, --chan=<channels> Comma separated list of channels to capture from, max %d. Mandatory\n", MAX_CHAN);
|
||||
printf(" -r, --role=[network|user] Is the local side the network or user side in ISDN?\n");
|
||||
printf(" -f, --file=<filename> The pcap file to capture to. Mandatory\n");
|
||||
printf(" -h, --help Display this text\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -210,6 +212,7 @@ int main(int argc, char **argv)
|
|||
int num_chans = 0;
|
||||
int max_fd = 0;
|
||||
int proto = DLT_MTP2_WITH_PHDR;
|
||||
int we_are_network = 0;
|
||||
|
||||
int i;
|
||||
int packetcount;
|
||||
|
@ -220,12 +223,13 @@ int main(int argc, char **argv)
|
|||
static struct option long_options[] = {
|
||||
{"proto", required_argument, 0, 'p'},
|
||||
{"chan", required_argument, 0, 'c'},
|
||||
{"role", required_argument, 0, 'r'},
|
||||
{"file", required_argument, 0, 'f'},
|
||||
{"help", 0, 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "p:c:f:?",
|
||||
c = getopt_long(argc, argv, "p:c:r:f:?",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
@ -268,6 +272,16 @@ int main(int argc, char **argv)
|
|||
}
|
||||
max_fd++;
|
||||
break;
|
||||
case 'r':
|
||||
if (!strcasecmp("network", optarg))
|
||||
we_are_network = 1;
|
||||
else if (!strcasecmp("user", optarg))
|
||||
we_are_network = 0;
|
||||
else {
|
||||
fprintf(stderr, "Role must be user or network!\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
// File to capture to
|
||||
filename=optarg;
|
||||
|
@ -317,11 +331,11 @@ int main(int argc, char **argv)
|
|||
{
|
||||
if(FD_ISSET(chans[i].rfd, &rd_set))
|
||||
{
|
||||
packetcount += log_packet(&chans[i], 1, dump);
|
||||
packetcount += log_packet(&chans[i], 1, we_are_network, dump);
|
||||
}
|
||||
if(FD_ISSET(chans[i].tfd, &rd_set))
|
||||
{
|
||||
packetcount += log_packet(&chans[i], 0, dump);
|
||||
packetcount += log_packet(&chans[i], 0, we_are_network, dump);
|
||||
}
|
||||
}
|
||||
printf("Packets captured: %d\r", packetcount);
|
||||
|
|
|
@ -66,6 +66,8 @@ usage() {
|
|||
echo >&2 " add - assign spans, according to /etc/dahdi/assigned-spans.conf"
|
||||
echo >&2 " remove - unassign spans"
|
||||
echo >&2 " list - human-readable list of all spans"
|
||||
echo >&2 " matched - found spans matched in configuration"
|
||||
echo >&2 " unmatched - found spans not matched in configuration"
|
||||
echo >&2 " dumpconfig - dump current state as new configuration"
|
||||
echo >&2 ""
|
||||
echo >&2 " options:"
|
||||
|
@ -109,7 +111,7 @@ while true ; do
|
|||
break
|
||||
;;
|
||||
*)
|
||||
echo "Internal error!"
|
||||
echo >&2 "Internal error!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
@ -215,10 +217,10 @@ unassign_all_spans() {
|
|||
sort | while read spandir; do
|
||||
local_spanno=`cat "$spandir/local_spanno"`
|
||||
if [ "$dry_run" = true ]; then
|
||||
echo "(dry-run) unassign $device $local_spanno"
|
||||
echo >&2 "(dry-run) unassign $device $local_spanno"
|
||||
continue
|
||||
fi
|
||||
echo "unassign $device $local_spanno"
|
||||
echo >&2 "unassign $device $local_spanno"
|
||||
if ! echo "$local_spanno" > "$device/unassign_span"; then
|
||||
echo >&2 "$0: failed unassigning '$local_spanno' in '$device'"
|
||||
fi
|
||||
|
@ -245,12 +247,12 @@ assign_device_spans() {
|
|||
if [ -d "$span" ]; then
|
||||
span_local_spanno=`cat "$span/local_spanno"`
|
||||
if [ "$span_local_spanno" != "$local_spanno" ]; then
|
||||
echo "WARNING: $span_local_spanno != $local_spanno"
|
||||
echo >&2 "WARNING: $span_local_spanno != $local_spanno"
|
||||
fi
|
||||
echo "$device [$local_spanno] already assigned to span $spanno. Skipping..."
|
||||
echo >&2 "$device [$local_spanno] already assigned to span $spanno. Skipping..."
|
||||
continue
|
||||
fi
|
||||
echo "assign $device: $s"
|
||||
echo >&2 "assign $device: $s"
|
||||
if ! echo "$s" > "$device/assign_span"; then
|
||||
echo >&2 "$0: failed assigning '$s' to '$device'"
|
||||
fi
|
||||
|
@ -267,21 +269,21 @@ match_device() {
|
|||
# We use case to enable shell-style globbing in configuration
|
||||
case "$hardware_id" in
|
||||
$id)
|
||||
[ "$verbose" = true ] && echo "match by hwid ($id ~ $hardware_id): $spanspecs"
|
||||
[ "$verbose" = true ] && echo >&2 "match by hwid ($id ~ $hardware_id): $spanspecs"
|
||||
assign_device_spans "$device"
|
||||
;;
|
||||
esac
|
||||
# We use case to enable shell-style globbing in configuration
|
||||
case "$location" in
|
||||
$id)
|
||||
[ "$verbose" = true ] && echo "match by location ($id ~ $location): $spanspecs"
|
||||
[ "$verbose" = true ] && echo >&2 "match by location ($id ~ $location): $spanspecs"
|
||||
assign_device_spans "$device"
|
||||
;;
|
||||
esac
|
||||
# We use case to enable shell-style globbing in configuration
|
||||
case "$devpath" in
|
||||
$id)
|
||||
[ "$verbose" = true ] && echo "match by devpath ($id ~ $devpath): $spanspecs"
|
||||
[ "$verbose" = true ] && echo >&2 "match by devpath ($id ~ $devpath): $spanspecs"
|
||||
assign_device_spans "$device"
|
||||
;;
|
||||
esac
|
||||
|
@ -293,7 +295,7 @@ assign_devices() {
|
|||
echo >&2 "$0: Missing '$DAHDISASSIGNEDSPANSCONF'"
|
||||
exit 1
|
||||
fi
|
||||
echo "using '$DAHDISASSIGNEDSPANSCONF'"
|
||||
echo >&2 "using '$DAHDISASSIGNEDSPANSCONF'"
|
||||
for device in $DEVICES
|
||||
do
|
||||
match_device "$device"
|
||||
|
@ -303,13 +305,71 @@ assign_devices() {
|
|||
auto_assign_devices() {
|
||||
for device in $DEVICES
|
||||
do
|
||||
echo "auto-assign $device"
|
||||
echo >&2 "auto-assign $device"
|
||||
if [ "$dry_run" != true ]; then
|
||||
echo 1 > "$device/auto_assign"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
dev_match_conf() {
|
||||
local devpath="$1"
|
||||
local location="$2"
|
||||
local hardware_id="$3"
|
||||
local local_spanno="$4"
|
||||
filter_conf | while read id spanspecs
|
||||
do
|
||||
spanno=`echo "$spanspecs" | cut -d: -f1`
|
||||
match_dev=no
|
||||
# We use case to enable shell-style globbing in configuration
|
||||
case "$hardware_id" in
|
||||
$id)
|
||||
match_dev=yes
|
||||
;;
|
||||
esac
|
||||
# We use case to enable shell-style globbing in configuration
|
||||
case "$location" in
|
||||
$id)
|
||||
match_dev=yes
|
||||
;;
|
||||
esac
|
||||
# We use case to enable shell-style globbing in configuration
|
||||
case "$devpath" in
|
||||
$id)
|
||||
match_dev=yes
|
||||
;;
|
||||
esac
|
||||
if [ "$match_dev" = 'yes' -a "$local_spanno" = "$spanno" ]; then
|
||||
#printf "%-8s (%s) %-14s %s %s\n" "$local_spanno" "$spanno" "[$hardware_id]" "$location" "$devpath"
|
||||
echo "[$hardware_id]:$local_spanno"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
list_devices() {
|
||||
wanted="$1"
|
||||
if [ ! -f "$DAHDISASSIGNEDSPANSCONF" ]; then
|
||||
echo >&2 "$0: Missing '$DAHDISASSIGNEDSPANSCONF'"
|
||||
exit 1
|
||||
fi
|
||||
echo >&2 "using '$DAHDISASSIGNEDSPANSCONF'"
|
||||
for device in $DEVICES
|
||||
do
|
||||
devpath=`cd "$device" && pwd -P`
|
||||
location='@'`attr_clean "$device/location"`
|
||||
hardware_id=`attr_clean "$device/hardware_id"`
|
||||
for local_spanno in `cut -d: -f1 "$device/spantype"`
|
||||
do
|
||||
found=`dev_match_conf "$devpath" "$location" "$hardware_id" "$local_spanno"`
|
||||
if [ "$wanted" = "unmatched" ]; then
|
||||
[ -z "$found" ] && echo "[$hardware_id]:$local_spanno"
|
||||
else
|
||||
[ -z "$found" ] || echo "[$hardware_id]:$local_spanno"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
case "$action" in
|
||||
auto)
|
||||
auto_assign_devices
|
||||
|
@ -326,6 +386,12 @@ list)
|
|||
dumpconfig)
|
||||
dump_config
|
||||
;;
|
||||
matched)
|
||||
list_devices "matched"
|
||||
;;
|
||||
unmatched)
|
||||
list_devices "unmatched"
|
||||
;;
|
||||
*)
|
||||
echo >&2 "Bad action='$action'"
|
||||
usage
|
||||
|
|
|
@ -69,6 +69,7 @@ usage() {
|
|||
echo >&2 "Usage: $0 [options] action [devpath ...]"
|
||||
echo >&2 " action:"
|
||||
echo >&2 " set - set spans to E1/T1 according to /etc/dahdi/span-types.conf"
|
||||
echo >&2 " compare - show config values that differ from system"
|
||||
echo >&2 " list - human-readable list of all spans"
|
||||
echo >&2 " dumpconfig - dump current state in /etc/dahdi/span-types.conf format"
|
||||
echo >&2 ""
|
||||
|
@ -88,6 +89,8 @@ if [ $? != 0 ]; then
|
|||
usage
|
||||
fi
|
||||
|
||||
compare=false
|
||||
|
||||
# Note the quotes around `$TEMP': they are essential!
|
||||
eval set -- "$TEMP"
|
||||
|
||||
|
@ -321,13 +324,26 @@ handle_span() {
|
|||
echo >&2 "Set $devname span $spanno = $val"
|
||||
fi
|
||||
if [ "$dry_run" != 'true' ]; then
|
||||
echo "$spanno:$val" > "$attr_file"
|
||||
if [ "$compare" = 'true' ]; then
|
||||
config="$spanno:$val"
|
||||
system=`grep "$spanno:" "$attr_file"`
|
||||
if [ "$config" != "$system" ]; then
|
||||
|
||||
active_val=`echo $system | cut -d: -f2`
|
||||
echo "$devname $spanno $val $active_val" >>"$compare_results_file"
|
||||
fi
|
||||
else
|
||||
echo "$spanno:$val" > "$attr_file"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
set_all_devices() {
|
||||
span_differs='false'
|
||||
SPANS_DIFFER='false'
|
||||
|
||||
if [ ! -f "$DAHDISPANTYPESCONF" ]; then
|
||||
echo >&2 "$0: Missing configuration '$DAHDISPANTYPESCONF'"
|
||||
exit 1
|
||||
|
@ -348,6 +364,16 @@ set_all_devices() {
|
|||
esac
|
||||
done
|
||||
done
|
||||
if [ "$compare" = 'true' ]; then
|
||||
if [ -s "$compare_results_file" ]; then
|
||||
echo "# Device Unit Config Active"
|
||||
cat "$compare_results_file"
|
||||
rm -f "$compare_results_file"
|
||||
exit 5
|
||||
fi
|
||||
rm -f "$compare_results_file"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
case "$action" in
|
||||
|
@ -360,6 +386,11 @@ dumpconfig)
|
|||
set)
|
||||
set_all_devices
|
||||
;;
|
||||
compare)
|
||||
compare=true
|
||||
compare_results_file=`mktemp`
|
||||
set_all_devices
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
|
|
|
@ -64,7 +64,7 @@ void hup_handler(int sig)
|
|||
printf("\n--- Results after %d passes ---\n", pass);
|
||||
printf("Best: %.3f%% -- Worst: %.3f%% -- Average: %f%%\n",
|
||||
best, worst, pass ? total/pass : 100.00);
|
||||
printf("Cummulative Accuracy (not per pass): %0.3f\n",
|
||||
printf("Cumulative Accuracy (not per pass): %0.3f\n",
|
||||
pass ? accuracy : 0.0);
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
man_MANS = \
|
||||
dahdi_cfg.8 \
|
||||
dahdi_maint.8 \
|
||||
dahdi_monitor.8 \
|
||||
dahdi_scan.8 \
|
||||
dahdi_span_assignments.8 \
|
||||
dahdi_span_types.8 \
|
||||
dahdi_test.8 \
|
||||
dahdi_tool.8 \
|
||||
dahdi_waitfor_span_assignments.8 \
|
||||
fxotune.8
|
||||
|
||||
noinst_MANS = \
|
||||
dahdi_diag.8 \
|
||||
fxstest.8 \
|
||||
patgen.8 \
|
||||
pattest.8
|
||||
|
||||
EXTRA_DIST = $(man_MANS) $(noinst_MANS)
|
|
@ -41,10 +41,8 @@ Only shutdown spans.
|
|||
|
||||
.B \-S \fISPAN
|
||||
.RS
|
||||
Only apply changes to span no. \fISPAN\fR. For a digital span (with
|
||||
a 'span=' line in the configuration file) this will do. For an analog
|
||||
span you'll have to explicitly tell dahdi_cfg the range of channels,
|
||||
using \-C .
|
||||
Only apply changes to span no. \fISPAN\fR. You also need to specify the
|
||||
range of channels in the span explicitly with \-C.
|
||||
.RE
|
||||
|
||||
.B \-f
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
dahdi_span_types \- set line modes of DAHDI spans before assignment
|
||||
.SH SYNOPSIS
|
||||
|
||||
.B dahdi_span_types [\fIoptions\fB] <list|dumpconfig|set> \fB[\fIdevpath \fB...]
|
||||
.B dahdi_span_types [\fIoptions\fB] <list|dumpconfig|compare|set> \fB[\fIdevpath \fB...]
|
||||
|
||||
.SH DESCRIPTION
|
||||
The span type (the line mode: E1/T1/J1) must be set to a span before
|
||||
|
@ -58,6 +58,16 @@ device(s) specified in the command line (or all devices, if none
|
|||
specified).
|
||||
.RE
|
||||
|
||||
.B compare
|
||||
.RS
|
||||
Compare the settings on the system to those in the configuration file.
|
||||
For each line that applies to a device on the system, print it if the
|
||||
value to be set and the active value on the system differ.
|
||||
|
||||
The exit status is 0 if there is no difference and non-zero if a
|
||||
difference was detected.
|
||||
.RE
|
||||
|
||||
.B list
|
||||
.RS
|
||||
List line modes for all spans in the system which may be set with
|
||||
|
|
|
@ -7,7 +7,7 @@ dahdi_tool \- Shows status of DAHDI interfaces
|
|||
.B dahdi_tool
|
||||
|
||||
.SH DESCRIPTION
|
||||
dahdi_tool shows the current status the DAHDI inteface cards plugged
|
||||
dahdi_tool shows the current status the DAHDI interface cards plugged
|
||||
to the computer.
|
||||
|
||||
It displays values like Current Alarms, SyncSource, Tx/Rx
|
||||
|
|
|
@ -33,7 +33,7 @@ is generated in the current directory.
|
|||
fxotune just reads the settings from fxotune.conf into the FXO modules.
|
||||
|
||||
You are advised to run fxotune on all FXO ports you have that support
|
||||
it and that are connected. Note that the tunning is affected by e.g.
|
||||
it and that are connected. Note that the tuning is affected by e.g.
|
||||
the physical parameters of the connection, and thus if it has been
|
||||
radically changed, you may need to re-run fxotune.
|
||||
|
||||
|
@ -44,7 +44,7 @@ cards and clones) do not have the hardware to support such tuning.
|
|||
The tuning process needs a clear line to do the tuning. In order to do
|
||||
that, it runs in cycles of the following: sets the line off-hook, dials
|
||||
a dial string (which should set the PSTN provider waiting for the next
|
||||
digit), and then starts tuning. It has a limited ammount of time for
|
||||
digit), and then starts tuning. It has a limited amount of time for
|
||||
tuning before the PSTN gives up and gives a busy tone. So after a while
|
||||
it hangs up and starts a new cycle.
|
||||
|
||||
|
@ -180,7 +180,7 @@ so if you stop it half-way, you may get a half-configured system. If you
|
|||
have already tuned your FXO channels and wish to test-run fxotune again,
|
||||
you are advised to backup /etc/fxotune.conf .
|
||||
|
||||
The default for \-m is 18 seconds. This asusmes that you get a clear line
|
||||
The default for \-m is 18 seconds. This assumes that you get a clear line
|
||||
for at least 18 seconds. It is advised that you test that timeout earlier
|
||||
by connecting a phone to the FXO line, dialing 4 (or whatever dial string
|
||||
you put with \-n) and see how much time of silence you have.
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#define RANDOM "/dev/urandom" /* Not genuinely random */
|
||||
/* #define RANDOM "/dev/random" */ /* Quite genuinely random */
|
||||
|
||||
int myread(int fd, char *buf, int len)
|
||||
int myread(int fd, unsigned char *buf, int len)
|
||||
{
|
||||
int sofar;
|
||||
int res;
|
||||
|
|
|
@ -107,13 +107,12 @@ static struct fasthdlc_state fs;
|
|||
|
||||
void send_packet(unsigned char *buf, int len)
|
||||
{
|
||||
int res;
|
||||
int x;
|
||||
unsigned char outbuf[BLOCK_SIZE];
|
||||
int pos=0;
|
||||
unsigned int fcs = PPP_INITFCS;
|
||||
if (hdlcmode)
|
||||
res = write(fd, buf, len + 2);
|
||||
write(fd, buf, len + 2);
|
||||
else {
|
||||
for (x=0;x<len;x++) {
|
||||
if (fasthdlc_tx_load(&fs, buf[x]))
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
nobase_dist_dahditools_SCRIPTS = \
|
||||
dahdi_handle_device \
|
||||
dahdi_span_config \
|
||||
dahdi_auto_assign_compat \
|
||||
span_config.d/10-dahdi-cfg \
|
||||
span_config.d/20-fxotune \
|
||||
span_config.d/50-asterisk \
|
||||
handle_device.d/10-span-types \
|
||||
handle_device.d/20-span-assignments \
|
||||
#
|
|
@ -22,4 +22,9 @@ devices_by_registration_time | \
|
|||
done
|
||||
|
||||
# Now handle Astribanks
|
||||
LC_ALL=C dahdi_registration -Rv on
|
||||
unmatched="`dahdi_span_assignments unmatched`"
|
||||
if [ -n "$unmatched" ]; then
|
||||
# Only if astribanks are not matched in span-assignments.conf
|
||||
# TODO: have dahdi_registration run only on "$unmatched"
|
||||
LC_ALL=C dahdi_registration -Rv on
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#! /bin/sh
|
||||
|
||||
# Run xpp_sync whenever an Astribank is connected.
|
||||
|
||||
# May be set in /etc/dahdi/init.conf
|
||||
XPP_SYNC=${XPP_SYNC:-auto}
|
||||
|
||||
case "$ACTION" in
|
||||
add) ;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
|
||||
case "${DEVPATH##*/}" in
|
||||
astribanks:*) ;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
|
||||
xpp_sync "$XPP_SYNC"
|
|
@ -53,6 +53,10 @@ wcfxo
|
|||
wctdm
|
||||
|
||||
# Digium B410P: 4 NT/TE BRI ports
|
||||
# Digium B433P: 4 NT/TE BRI ports pci-e
|
||||
# Digium B434P: 4 NT/TE BRI ports
|
||||
# Digium B233P: 2 NT/TE BRI ports pci-e
|
||||
# Digium B234P: 2 NT/TE BRI ports
|
||||
wcb4xxp
|
||||
|
||||
# Digium TC400B: G729 / G723 Transcoding Engine
|
||||
|
|
2
patgen.c
2
patgen.c
|
@ -45,7 +45,6 @@
|
|||
#define BLOCK_SIZE 2041
|
||||
#define DEVICE "/dev/dahdi/channel"
|
||||
|
||||
static const char rcsid[] = "$Id$";
|
||||
char *prog_name;
|
||||
|
||||
static void usage(void)
|
||||
|
@ -53,7 +52,6 @@ static void usage(void)
|
|||
fprintf(stderr, "Usage: %s <dahdi_chan>\n", prog_name);
|
||||
fprintf(stderr, " e.g.: %s /dev/dahdi/55\n", prog_name);
|
||||
fprintf(stderr, " %s 455\n", prog_name);
|
||||
fprintf(stderr, "%s version %s\n", prog_name, rcsid);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -168,6 +168,7 @@ int main(int argc, char *argv[])
|
|||
int opt;
|
||||
int oldstyle_cmdline = 1;
|
||||
unsigned int event_count = 0;
|
||||
time_t start_time = 0;
|
||||
|
||||
/* Parse the command line arguments */
|
||||
while((opt = getopt(argc, argv, "b:s:t:r:v?h")) != -1) {
|
||||
|
@ -218,8 +219,6 @@ int main(int argc, char *argv[])
|
|||
if (oldstyle_cmdline && argc > optind +1) {
|
||||
timeout = strtoul(argv[optind+1], NULL, 10);
|
||||
}
|
||||
|
||||
time_t start_time = 0;
|
||||
|
||||
fd = channel_open(device, &bs);
|
||||
if (fd < 0)
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#define BLOCK_SIZE 2039
|
||||
#define DEVICE "/dev/dahdi/channel"
|
||||
|
||||
static const char rcsid[] = "$Id$";
|
||||
char *prog_name;
|
||||
|
||||
static void usage(void)
|
||||
|
@ -52,7 +51,6 @@ static void usage(void)
|
|||
fprintf(stderr, "Usage: %s <dahdi_chan>\n", prog_name);
|
||||
fprintf(stderr, " e.g.: %s /dev/dahdi/55\n", prog_name);
|
||||
fprintf(stderr, " %s 455\n", prog_name);
|
||||
fprintf(stderr, "%s version %s\n", prog_name, rcsid);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
29
ppp/Makefile
29
ppp/Makefile
|
@ -1,29 +0,0 @@
|
|||
#COPTS = -O2 -g
|
||||
|
||||
-include ../makeopts
|
||||
|
||||
CFLAGS += $(COPTS) -fPIC
|
||||
LDFLAGS += -shared
|
||||
|
||||
INCLUDE_DIR = $(includedir)/pppd
|
||||
|
||||
LIBDIR = $(libdir)/pppd/$(PPPD_VERSION)
|
||||
|
||||
PLUGINS := dahdi.so
|
||||
|
||||
all: $(PLUGINS)
|
||||
|
||||
%.so: %.c
|
||||
ifeq (,$(PPPD_VERSION))
|
||||
@echo "pppd version not found (in patchlevel.h)."
|
||||
@echo "Install ppp source/headers and/or ./configure --with-ppp=PATH."
|
||||
exit 1
|
||||
endif
|
||||
$(CC) -o $@ $(CFLAGS) $^ $(LDFLAGS)
|
||||
|
||||
install: $(PLUGINS)
|
||||
$(INSTALL) -d $(DESTDIR)$(LIBDIR)
|
||||
$(INSTALL) -m 0644 $? $(DESTDIR)$(LIBDIR)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.so *.a
|
|
@ -0,0 +1,7 @@
|
|||
plugindir = $(libdir)/pppd/$(PPPD_VERSION)
|
||||
plugin_LTLIBRARIES = dahdi.la
|
||||
|
||||
dahdi_la_CFLAGS = $(DAHDI_INCLUDE)
|
||||
dahdi_la_LDFLAGS = -module -avoid-version
|
||||
|
||||
CLEANFILES = dahdi.so
|
|
@ -0,0 +1,14 @@
|
|||
CFLAGS += -g -Wall -O2 $(DAHDI_INCLUDE)
|
||||
|
||||
if PBX_TRUNKDEV
|
||||
|
||||
sbin_PROGRAMS = \
|
||||
dahdi_trunkdev \
|
||||
$(NULL)
|
||||
|
||||
dahdi_trunkdev_SOURCES = \
|
||||
trunkdev-tool.c \
|
||||
dahdi-sysfs.c \
|
||||
$(NULL)
|
||||
|
||||
endif
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "dahdi-sysfs.h"
|
||||
|
||||
/* read a sysfs attribute from a file, stripping any trailing newline */
|
||||
char *sysfs_read_attr(const char *path)
|
||||
{
|
||||
FILE *f;
|
||||
char *buf;
|
||||
|
||||
f = fopen(path, "r");
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
buf = malloc(256);
|
||||
if (!buf)
|
||||
goto out_close;
|
||||
|
||||
if (!fgets(buf, 256, f))
|
||||
goto out_free;
|
||||
|
||||
if (strlen(buf) && buf[strlen(buf)-1] == '\n')
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
|
||||
fclose(f);
|
||||
printf("%s: %s\n", path, buf);
|
||||
return buf;
|
||||
|
||||
out_free:
|
||||
free(buf);
|
||||
out_close:
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *sysfs_read_span_attr(unsigned int spanno, const char *name)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
snprintf(path, sizeof(path), "/sys/bus/dahdi_spans/devices/span-%u/%s", spanno, name);
|
||||
return sysfs_read_attr(path);
|
||||
}
|
||||
|
||||
static int sysfs_read_span_attr_int(unsigned int spanno, const char *name)
|
||||
{
|
||||
char *attr;
|
||||
int attr_int;
|
||||
|
||||
attr = sysfs_read_span_attr(spanno, name);
|
||||
if (!attr)
|
||||
return -1;
|
||||
|
||||
attr_int = atoi(attr);
|
||||
free(attr);
|
||||
|
||||
return attr_int;
|
||||
}
|
||||
|
||||
/* return number of channels in span */
|
||||
int dahdi_span_get_basechan(unsigned int spanno)
|
||||
{
|
||||
return sysfs_read_span_attr_int(spanno, "basechan");
|
||||
}
|
||||
|
||||
/* return number of channels in span */
|
||||
int dahdi_span_get_channels(unsigned int spanno)
|
||||
{
|
||||
return sysfs_read_span_attr_int(spanno, "channels");
|
||||
}
|
||||
|
||||
char *dahdi_span_get_name(unsigned int spanno)
|
||||
{
|
||||
return sysfs_read_span_attr(spanno, "name");
|
||||
}
|
||||
|
||||
char *dahdi_span_get_desc(unsigned int spanno)
|
||||
{
|
||||
return sysfs_read_span_attr(spanno, "desc");
|
||||
}
|
||||
|
||||
char *dahdi_span_get_spantype(unsigned int spanno)
|
||||
{
|
||||
return sysfs_read_span_attr(spanno, "spantype");
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
char *sysfs_read_attr(const char *path);
|
||||
|
||||
int dahdi_span_get_basechan(unsigned int spanno);
|
||||
int dahdi_span_get_channels(unsigned int spanno);
|
||||
char *dahdi_span_get_name(unsigned int spanno);
|
||||
char *dahdi_span_get_desc(unsigned int spanno);
|
||||
char *dahdi_span_get_spantype(unsigned int spanno);
|
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
* trunkdev configuration program for DAHDI Telephony Interface
|
||||
*
|
||||
* Copyright (C) 2022 Harald Welte <laforge@osmocom.org>
|
||||
* Copyright (C) 2001-2008 Digium, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2 as published by the
|
||||
* Free Software Foundation. See the LICENSE file included with
|
||||
* this program for more details.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <dahdi/user.h>
|
||||
|
||||
#include "dahdi-sysfs.h"
|
||||
|
||||
static int g_fd = -1;
|
||||
|
||||
|
||||
/* wrapper around DAHDI_TRUNKDEV_CREATE */
|
||||
static int trunkdev_create(int fd, const char *name)
|
||||
{
|
||||
struct dahdi_trunkdev_create td_c = { 0 };
|
||||
int rc;
|
||||
|
||||
strncpy(td_c.name, name, sizeof(td_c.name));
|
||||
td_c.name[sizeof(td_c.name)-1] = 0;
|
||||
|
||||
rc = ioctl(fd, DAHDI_TRUNKDEV_CREATE, &td_c);
|
||||
if (rc)
|
||||
fprintf(stderr, "Error creating trunkdev '%s': %s\n", name, strerror(errno));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* wrapper around DAHDI_TRUNKDEV_DELETE */
|
||||
static int trunkdev_delete(int fd, const char *name)
|
||||
{
|
||||
struct dahdi_trunkdev_delete td_d = { 0 };
|
||||
int rc;
|
||||
|
||||
strncpy(td_d.name, name, sizeof(td_d.name));
|
||||
td_d.name[sizeof(td_d.name)-1] = 0;
|
||||
|
||||
rc = ioctl(fd, DAHDI_TRUNKDEV_DELETE, &td_d);
|
||||
if (rc)
|
||||
fprintf(stderr, "Error deleting trunkdev '%s': %s\n", name, strerror(errno));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* wrapper around DAHDI_TRUNKDEV_SPECIFY */
|
||||
static int trunkdev_specify(int fd, const char *name)
|
||||
{
|
||||
struct dahdi_trunkdev_open td_o = { 0 };
|
||||
int rc;
|
||||
|
||||
strncpy(td_o.name, name, sizeof(td_o.name));
|
||||
td_o.name[sizeof(td_o.name)-1] = 0;
|
||||
|
||||
rc = ioctl(fd, DAHDI_TRUNKDEV_OPEN, &td_o);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error opening trunkdev '%s': %s\n", name, strerror(errno));
|
||||
return rc;
|
||||
}
|
||||
return td_o.spanno;
|
||||
}
|
||||
|
||||
/* wrapper around DAHDI_SPANCONFIG (assuming E1 with CRC4) */
|
||||
static int spanconfig(int fd, int spanno)
|
||||
{
|
||||
struct dahdi_lineconfig dlc = {
|
||||
.span = spanno,
|
||||
.lbo = 0,
|
||||
.lineconfig = DAHDI_CONFIG_CRC4,
|
||||
.sync = 0,
|
||||
};
|
||||
|
||||
return ioctl(fd, DAHDI_SPANCONFIG, &dlc);
|
||||
}
|
||||
|
||||
/* wrapper around DAHDI_CHANCONFIG (assuming E1/ALAW/CLEAR; unless dchan -> HDLCFCS) */
|
||||
static int chanconfig(int fd, int channo, bool dchan)
|
||||
{
|
||||
struct dahdi_chanconfig dcc = {
|
||||
.chan = channo,
|
||||
.sigtype = DAHDI_SIG_CLEAR,
|
||||
.deflaw = DAHDI_LAW_ALAW,
|
||||
.master = 0,
|
||||
.idlebits = 0,
|
||||
};
|
||||
if (dchan)
|
||||
dcc.sigtype = DAHDI_SIG_HDLCFCS;
|
||||
|
||||
return ioctl(fd, DAHDI_CHANCONFIG, &dcc);
|
||||
}
|
||||
|
||||
static int chanconfig_hdlc_master(int fd, int channo, const char *netdev_name)
|
||||
{
|
||||
struct dahdi_chanconfig dcc = {
|
||||
.chan = channo,
|
||||
.sigtype = DAHDI_SIG_HDLCNET,
|
||||
.deflaw = DAHDI_LAW_ALAW,
|
||||
.master = 0,
|
||||
.idlebits = 0,
|
||||
};
|
||||
strncpy(dcc.netdev_name, netdev_name, sizeof(dcc.netdev_name));
|
||||
dcc.netdev_name[sizeof(dcc.netdev_name)-1] = '\0';
|
||||
|
||||
return ioctl(fd, DAHDI_CHANCONFIG, &dcc);
|
||||
}
|
||||
|
||||
static int chanconfig_hdlc_slave(int fd, int channo, int master)
|
||||
{
|
||||
struct dahdi_chanconfig dcc = {
|
||||
.chan = channo,
|
||||
.sigtype = DAHDI_SIG_SLAVE,
|
||||
.deflaw = DAHDI_LAW_ALAW,
|
||||
.master = master,
|
||||
.idlebits = 0,
|
||||
};
|
||||
|
||||
return ioctl(fd, DAHDI_CHANCONFIG, &dcc);
|
||||
}
|
||||
|
||||
/* high-level wrapper to configure an E1 span + all its channels */
|
||||
static int config(int spanno, const char *hdlc_netdev)
|
||||
{
|
||||
struct dahdi_spaninfo dsi = {
|
||||
.spanno = spanno,
|
||||
};
|
||||
int fd, rc;
|
||||
|
||||
fd = open("/dev/dahdi/ctl", O_RDWR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Unable to open /dev/dahd/ctl: %s\n", strerror(errno));
|
||||
return fd;
|
||||
}
|
||||
|
||||
rc = ioctl(fd, DAHDI_SPANSTAT, &dsi);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error during spanstat: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
printf("Span %u (%s: %s)\n", dsi.spanno, dsi.name, dsi.desc);
|
||||
printf(" numchans=%u, totalchans=%u\n", dsi.numchans, dsi.totalchans);
|
||||
|
||||
rc = spanconfig(fd, spanno);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error during spanconfig: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* resolve basechan + num_chan via sysfs */
|
||||
int basechan = dahdi_span_get_basechan(spanno);
|
||||
int num_chan = dahdi_span_get_channels(spanno);
|
||||
if (basechan < 0 || num_chan < 0) {
|
||||
fprintf(stderr, "Error getting basechan=%d or channels=%d for spanno=%d: %s\n",
|
||||
basechan, num_chan, spanno, strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (unsigned int i = basechan; i < basechan+num_chan; i++) {
|
||||
if (!hdlc_netdev) {
|
||||
/* ISDN: we assume a standard ISDN configuration with TS16 == D-channel */
|
||||
rc = chanconfig(fd, i, i == basechan + 15);
|
||||
} else {
|
||||
/* HDLC: we assume TS 1-31 as superchannel */
|
||||
if (i == basechan)
|
||||
rc = chanconfig_hdlc_master(fd, i, hdlc_netdev);
|
||||
else
|
||||
rc = chanconfig_hdlc_slave(fd, i, basechan);
|
||||
}
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error during spanconfig: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_help(void)
|
||||
{
|
||||
printf("\n");
|
||||
printf( "dahdi_trunkdev create NAME\n"
|
||||
" Create a new dahdi trunkdev named NAME\n"
|
||||
"dahdi_trunkdev delete NAME\n"
|
||||
" Delete an existing dahdi trunkdev named NAME\n"
|
||||
"dahdi_trunkdev config NAME\n"
|
||||
" Configure span + all channels of trunkdev named NAME for ISDN\n"
|
||||
"dahdi_trunkdev config-hdlc NAME\n"
|
||||
" Configure span + all channels of trunkdev named NAME for HDLC\n"
|
||||
"dahdi_trunkdev read NAME\n"
|
||||
" Continuously read + discard frames from trunkdev named NAME\n"
|
||||
"dahdi_trunkdev rdwr NAME\n"
|
||||
" Continuously read + loop back (write) frames of trunkdev named NAME\n");
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
printf("DAHDI trunkdev tool (C) 2022 by Harald Welte <laforge@osmocom.org>\n\n");
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "First argument must specify the command\n");
|
||||
print_help();
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "help") || !strcmp(argv[1], "--help")) {
|
||||
print_help();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
g_fd = open("/dev/dahdi/trunkdev", O_RDWR);
|
||||
if (g_fd < 0) {
|
||||
fprintf(stderr, "Unable to open trunkdev: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "create")) {
|
||||
/* dahdi_trunkdev create foo */
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Second argument must specify the name\n");
|
||||
exit(2);
|
||||
}
|
||||
rc = trunkdev_create(g_fd, argv[2]);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Unable to create trunkdev: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
printf("DAHDI trunkdev %s created; span number %d\n", argv[2], rc);
|
||||
} else if (!strcmp(argv[1], "delete")) {
|
||||
/* dahdi_trunkdev create foo */
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Second argument must specify the name\n");
|
||||
exit(2);
|
||||
}
|
||||
rc = trunkdev_delete(g_fd, argv[2]);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Unable to create trunkdev: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
printf("DAHDI trunkdev %s deleted\n", argv[2]);
|
||||
} else if (!strcmp(argv[1], "config")) {
|
||||
/* dahdi_trunkdev config foo */
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Second argument must specify the name\n");
|
||||
exit(2);
|
||||
}
|
||||
rc = trunkdev_specify(g_fd, argv[2]);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Unable to specify trunkdev: %s\n", strerror(errno));
|
||||
exit(2);
|
||||
}
|
||||
rc = config(rc, NULL);
|
||||
if (rc < 0)
|
||||
exit(2);
|
||||
printf("DAHDI trunkdev %s configured\n", argv[2]);
|
||||
} else if (!strcmp(argv[1], "config-hdlc")) {
|
||||
/* dahdi_trunkdev config-hdlc foo hdlc-foo */
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Second argument must specify the name\n");
|
||||
exit(2);
|
||||
}
|
||||
if (argc < 4) {
|
||||
fprintf(stderr, "Third argument must specify the net-device name\n");
|
||||
exit(2);
|
||||
}
|
||||
rc = trunkdev_specify(g_fd, argv[2]);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Unable to specify trunkdev: %s\n", strerror(errno));
|
||||
exit(2);
|
||||
}
|
||||
rc = config(rc, argv[3]);
|
||||
if (rc < 0)
|
||||
exit(2);
|
||||
printf("DAHDI trunkdev %s configured as netdev %s\n", argv[2], argv[3]);
|
||||
} else if (!strcmp(argv[1], "read") || !strcmp(argv[1], "rdwr")) {
|
||||
/* dahdi_trunkdev (read|rdwr) foo */
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Second argument must specify the name\n");
|
||||
exit(2);
|
||||
}
|
||||
rc = trunkdev_specify(g_fd, argv[2]);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Unable to specify trunkdev: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (!strcmp(argv[1], "read"))
|
||||
printf("Reading + Disccarding from DAHDI trunkdev %s\n", argv[2]);
|
||||
else
|
||||
printf("Reading + Writing (looping back) DAHDI trunkdev %s\n", argv[2]);
|
||||
while (1) {
|
||||
uint8_t buf[32*8];
|
||||
rc = read(g_fd, buf, sizeof(buf));
|
||||
if (rc <= 0) {
|
||||
fprintf(stderr, "Error %d reading: %s\n", rc, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
fputc('.', stdout);
|
||||
if (!strcmp(argv[1], "rdwr")) {
|
||||
rc = write(g_fd, buf, rc);
|
||||
if (rc <= 0) {
|
||||
fprintf(stderr, "Error %d writing: %s\n", rc, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
exit(23);
|
||||
|
||||
exit(0);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
/*
|
||||
* version.c.in
|
||||
*/
|
||||
|
||||
const char dahdi_tools_version[] = "DAHDI Tools Version - @TOOLSVERSION@";
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# A dracut.conf(5) snippet
|
||||
# Disable loading the Astribank (xpp_usb) drivers. This is because
|
||||
# it relies on files in the root filesystem:
|
||||
# See https://issues.asterisk.org/jira/browse/DAHLIN-352
|
||||
omit_drivers+=" xpp_usb "
|
202
xpp/Makefile
202
xpp/Makefile
|
@ -1,202 +0,0 @@
|
|||
PEDANTIC = -ansi -pedantic -std=c99
|
||||
|
||||
INSTALL = install
|
||||
INSTALL_DATA = install -m 644
|
||||
|
||||
#
|
||||
# Ugly hack to find kernel directories before/after the split
|
||||
# to kernel/user-space.
|
||||
#
|
||||
# These variables should be passed to us. But until then...
|
||||
#
|
||||
DAHDI_TOOLSDIR ?= ..
|
||||
DAHDI_KERNELDIR =
|
||||
|
||||
-include $(DAHDI_TOOLSDIR)/makeopts
|
||||
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
|
||||
# In 1.4 those are provided by autoconf through makeopts
|
||||
prefix ?= /usr
|
||||
datadir ?= $(prefix)/share
|
||||
mandir ?= $(datadir)/man
|
||||
sysconfdir ?= $(prefix)/etc
|
||||
udevrulesdir ?= $(sysconfdir)/udev/rules.d
|
||||
INSTALL ?= install
|
||||
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
|
||||
SBINDIR = $(prefix)/sbin
|
||||
DATADIR = $(datadir)/dahdi
|
||||
MANDIR = $(mandir)/man8
|
||||
HOTPLUG_USB_DIR = $(sysconfdir)/hotplug/usb
|
||||
PERLLIBDIR := $(shell eval `perl -V:sitelib`; echo "$$sitelib")
|
||||
PERL_DIRS := $(shell cd perl_modules; find * -name '[A-Z]*' -type d| xargs)
|
||||
PERL_MODS_PAT := *.pm $(PERL_DIRS:%=%/*.pm)
|
||||
PERL_MODS := $(shell cd perl_modules; echo $(PERL_MODS_PAT))
|
||||
|
||||
# Variables that should be defined above, but need sane defaults:
|
||||
# FIXME: Are those values really sane?
|
||||
HOSTCC ?= $(CC)
|
||||
|
||||
USE_OCTASIC := yes
|
||||
OCTASIC_DIR := oct612x
|
||||
|
||||
ifneq (no,$(USE_OCTASIC))
|
||||
|
||||
OCT_OBJS = $(shell $(OCTASIC_DIR)/octasic-helper objects $(OCTASIC_DIR))
|
||||
OCT_SRCS = $(shell echo $(OCT_OBJS) | tr -s ' ' '\n' | sed 's/\.o$$/.c/g')
|
||||
OCT_HERE_OBJS = $(shell echo $(OCT_OBJS) | tr -s ' ' '\n' | sed 's,^.*/,,')
|
||||
OCT_CFLAGS = $(shell $(OCTASIC_DIR)/octasic-helper cflags $(OCTASIC_DIR))
|
||||
OCT_DEFINES = \
|
||||
-DPTR_TYPE=uint32_t \
|
||||
-DcOCT6100_INTERNAL_SUPER_ARRAY_SIZE=1024 \
|
||||
-DcOCT6100_MAX_ECHO_CHANNELS=672 \
|
||||
-DcOCT6100_MAX_MIXER_EVENTS=1344
|
||||
|
||||
ECHO_LOADER_SRC = echo_loader.c parse_span_specs.c
|
||||
ECHO_LOADER = $(ECHO_LOADER_SRC:.c=.o)
|
||||
endif
|
||||
|
||||
%.8: %
|
||||
pod2man --section 8 $^ > $@ || $(RM) $@
|
||||
PERL_SCRIPTS = \
|
||||
dahdi_registration \
|
||||
xpp_sync \
|
||||
lsdahdi \
|
||||
xpp_blink \
|
||||
dahdi_genconf \
|
||||
dahdi_hardware \
|
||||
twinstar \
|
||||
#
|
||||
|
||||
PERL_MANS = $(PERL_SCRIPTS:%=%.8)
|
||||
|
||||
# List all our sources
|
||||
XUSB_SRCS = xtalk/xusb.c xtalk/xlist.c xtalk/debug.c
|
||||
XTALK_SRCS = xtalk/xtalk.c
|
||||
MPPTALK_SRCS = mpptalk.c
|
||||
ASTRIBANK_SRCS = astribank_usb.c
|
||||
ABHEXLOAD_SRCS = astribank_hexload.c hexfile.c pic_loader.c
|
||||
ABTOOL_SRCS = astribank_tool.c
|
||||
ABALLOW_SRCS = astribank_allow.c astribank_license.c
|
||||
|
||||
SRCS = \
|
||||
$(XUSB_SRCS) \
|
||||
$(XTALK_SRCS) \
|
||||
$(MPPTALK_SRCS) \
|
||||
$(ASTRIBANK_SRCS) \
|
||||
$(ABHEXLOAD_SRCS) \
|
||||
$(ABTOOL_SRCS) \
|
||||
$(ABALLOW_SRCS) \
|
||||
$(ECHO_LOADER_SRC)
|
||||
|
||||
# Derive object files from source list
|
||||
XUSB_OBJS = $(XUSB_SRCS:.c=.o)
|
||||
XTALK_OBJS = $(XTALK_SRCS:.c=.o) $(XUSB_OBJS)
|
||||
MPPTALK_OBJS = $(MPPTALK_SRCS:.c=.o) $(XTALK_OBJS)
|
||||
ASTRIBANK_OBJS = $(ASTRIBANK_SRCS:.c=.o) $(MPPTALK_OBJS)
|
||||
ABHEXLOAD_OBJS = $(ABHEXLOAD_SRCS:.c=.o) $(ASTRIBANK_OBJS) $(ECHO_LOADER) $(OCT_HERE_OBJS)
|
||||
ABTOOL_OBJS = $(ABTOOL_SRCS:.c=.o) $(ASTRIBANK_OBJS)
|
||||
ABALLOW_OBJS = $(ABALLOW_SRCS:.c=.o) $(ASTRIBANK_OBJS)
|
||||
|
||||
TARGETS = .perlcheck astribank_is_starting
|
||||
PROG_INSTALL = astribank_is_starting
|
||||
MAN_INSTALL = $(PROG_INSTALL:%=%.8)
|
||||
ifeq (1,$(PBX_USB))
|
||||
TARGETS += \
|
||||
astribank_tool \
|
||||
astribank_hexload \
|
||||
astribank_allow \
|
||||
test_parse
|
||||
PROG_INSTALL += astribank_tool astribank_hexload astribank_allow
|
||||
endif
|
||||
ifneq (,$(PERLLIBDIR))
|
||||
PROG_INSTALL += $(PERL_SCRIPTS)
|
||||
TARGETS += $(PERL_MANS)
|
||||
endif
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
docs: $(PERL_MANS)
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d $(DESTDIR)$(SBINDIR)
|
||||
$(INSTALL) $(PROG_INSTALL) $(DESTDIR)$(SBINDIR)/
|
||||
$(INSTALL) -d $(DESTDIR)$(DATADIR)
|
||||
$(INSTALL) xpp_fxloader astribank_hook $(DESTDIR)$(DATADIR)/
|
||||
$(INSTALL) waitfor_xpds $(DESTDIR)$(DATADIR)/
|
||||
$(INSTALL) -d $(DESTDIR)$(udevrulesdir)
|
||||
$(INSTALL_DATA) xpp.rules $(DESTDIR)$(udevrulesdir)/
|
||||
$(INSTALL) -d $(DESTDIR)$(MANDIR)
|
||||
$(INSTALL_DATA) $(MAN_INSTALL) $(DESTDIR)$(MANDIR)/
|
||||
$(INSTALL) -d $(DESTDIR)$(HOTPLUG_USB_DIR)
|
||||
$(INSTALL_DATA) xpp_fxloader.usermap $(DESTDIR)$(HOTPLUG_USB_DIR)/
|
||||
# for backward compatibility and for hotplug users:
|
||||
ln -sf $(DATADIR)/xpp_fxloader $(DESTDIR)$(HOTPLUG_USB_DIR)/
|
||||
ifneq (,$(PERLLIBDIR))
|
||||
$(INSTALL) -d $(DESTDIR)$(PERLLIBDIR)
|
||||
for i in $(PERL_DIRS); \
|
||||
do \
|
||||
$(INSTALL) -d "$(DESTDIR)$(PERLLIBDIR)/$$i"; \
|
||||
done
|
||||
for i in $(PERL_MODS); \
|
||||
do \
|
||||
$(INSTALL_DATA) "perl_modules/$$i" "$(DESTDIR)$(PERLLIBDIR)/$$i"; \
|
||||
done
|
||||
endif
|
||||
|
||||
CFLAGS += -I. -Ixtalk -Wall -Werror
|
||||
|
||||
astribank_hexload: $(ABHEXLOAD_OBJS)
|
||||
astribank_hexload: LIBS+=$(EXTRA_LIBS) $(USB_LIB)
|
||||
astribank_hexload: CFLAGS+=$(OCT_CFLAGS)
|
||||
|
||||
astribank_tool: $(ABTOOL_OBJS)
|
||||
astribank_tool: LIBS+=$(EXTRA_LIBS) $(USB_LIB)
|
||||
|
||||
astribank_allow: $(ABALLOW_OBJS)
|
||||
astribank_allow: LIBS+=$(EXTRA_LIBS) $(USB_LIB)
|
||||
|
||||
astribank_is_starting: astribank_is_starting.o
|
||||
astribank_is_starting: LIBS+=$(EXTRA_LIBS)
|
||||
|
||||
hex2iic: hex2iic.o iic.o hexfile.o
|
||||
|
||||
test_parse: test_parse.o hexfile.o
|
||||
test_parse: LIBS+=$(EXTRA_LIBS) $(USB_LIB)
|
||||
|
||||
ifneq (no,$(USE_OCTASIC))
|
||||
.octasic.depend: $(OCTASIC_DIR)/octasic-helper Makefile ../config.status
|
||||
$(CC) -MM $(OCT_CFLAGS) \
|
||||
`$(OCTASIC_DIR)/octasic-helper objects | \
|
||||
tr -s ' ' '\n' | \
|
||||
sed -e 's,.*,$(OCTASIC_DIR)/&,' -e 's/\.o$$/.c/'` > $@
|
||||
|
||||
-include .octasic.depend
|
||||
|
||||
$(OCT_HERE_OBJS): Makefile
|
||||
$(CC) -c $(CFLAGS) $(OCT_CFLAGS) $(OCT_DEFINES) $(OCT_SRCS)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
%: %.o
|
||||
$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
|
||||
|
||||
.perlcheck: $(PERL_SCRIPTS)
|
||||
for i in $^; do perl -I./perl_modules -c $$i || exit 1; done
|
||||
touch $@
|
||||
|
||||
clean:
|
||||
$(RM) .depend .octasic.depend *.o xtalk/*.o $(OCT_HERE_OBJS) $(TARGETS)
|
||||
|
||||
.PHONY: depend
|
||||
ifeq (1,$(PBX_USB))
|
||||
depend: .depend
|
||||
.depend: *.c *.h xtalk/*.c
|
||||
@echo "Calculating dependencies"
|
||||
@if ! $(CC) $(CFLAGS) $(OCT_CFLAGS) -MM $(SRCS) > $@; then $(RM) $@; exit 1; fi
|
||||
|
||||
include .depend
|
||||
endif
|
|
@ -0,0 +1,170 @@
|
|||
|
||||
all-local: $(perl_checks)
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
man_MANS =
|
||||
|
||||
|
||||
# FIXME: try to improve code, so we can use $(PEDANTIC)
|
||||
#PEDANTIC = -ansi -pedantic -std=c99
|
||||
GLOBAL_CFLAGS = -I$(srcdir) -I$(srcdir)/xtalk/include $(PEDANTIC) -Wall
|
||||
|
||||
if DAHDI_DEVMODE
|
||||
GLOBAL_CFLAGS += \
|
||||
-Werror \
|
||||
-Wunused \
|
||||
-Wundef \
|
||||
-Wmissing-format-attribute \
|
||||
-Wformat-security \
|
||||
-Wformat=2
|
||||
endif
|
||||
|
||||
if PERL
|
||||
SUBDIRS += perl_modules
|
||||
|
||||
%.8: %
|
||||
@if file "$^" | cut -d: -f2 | grep -q -iw perl; then \
|
||||
if pod2man --section 8 $^ > $@; then \
|
||||
echo " GEN $@"; \
|
||||
else \
|
||||
rm -f "$@"; \
|
||||
fi \
|
||||
fi
|
||||
|
||||
%.check: %
|
||||
@echo " CHECK $^"; \
|
||||
if ! perl -I./perl_modules -c $^ 2>/dev/null; then \
|
||||
perl -I./perl_modules -c $^; \
|
||||
fi
|
||||
@touch $@
|
||||
|
||||
perl_scripts = \
|
||||
dahdi_registration \
|
||||
xpp_sync \
|
||||
lsdahdi \
|
||||
xpp_blink \
|
||||
dahdi_genconf \
|
||||
dahdi_hardware \
|
||||
twinstar \
|
||||
#
|
||||
|
||||
perl_checks = $(perl_scripts:%=%.check)
|
||||
perl_mans = $(perl_scripts:%=%.8)
|
||||
|
||||
endif
|
||||
|
||||
dist_dahditools_SCRIPTS = xpp_fxloader astribank_hook waitfor_xpds
|
||||
udevrulesdir = @udevrulesdir@
|
||||
udevrules_DATA = xpp.rules
|
||||
|
||||
dist_sbin_SCRIPTS = $(perl_scripts)
|
||||
man_MANS += $(perl_mans)
|
||||
CLEANFILES = $(perl_checks) $(perl_mans)
|
||||
|
||||
dracutconfdir = @prefix@/lib/dracut/dracut.conf.d
|
||||
dracutconf_DATA = 50-dahdi.conf
|
||||
|
||||
if PBX_USB
|
||||
|
||||
SUBDIRS += oct612x xtalk
|
||||
|
||||
if LIBUSBX
|
||||
USB_CFLAGS = $(LIBUSBX_CFLAGS)
|
||||
USB_LIBS = $(LIBUSBX_LIBS)
|
||||
USB_NAME = libusbx
|
||||
else
|
||||
if LIBUSB
|
||||
USB_CFLAGS = $(LIBUSB_CFLAGS)
|
||||
USB_LIBS = $(LIBUSB_LIBS)
|
||||
USB_NAME = libusb
|
||||
endif
|
||||
endif
|
||||
|
||||
noinst_LTLIBRARIES = libastribank.la libecholoader.la libhexfile.la
|
||||
|
||||
libastribank_la_SOURCES = \
|
||||
astribank.c \
|
||||
astribank.h \
|
||||
mpptalk.c \
|
||||
mpptalk.h \
|
||||
astribank_license.c \
|
||||
astribank_license.h \
|
||||
#
|
||||
|
||||
libastribank_la_CFLAGS = $(GLOBAL_CFLAGS)
|
||||
libastribank_la_LIBADD = xtalk/libxtalk.la
|
||||
|
||||
if USE_OCTASIC
|
||||
libecholoader_la_SOURCES = \
|
||||
parse_span_specs.c \
|
||||
parse_span_specs.h \
|
||||
echo_loader.c \
|
||||
echo_loader.h \
|
||||
#
|
||||
|
||||
libecholoader_la_CFLAGS = $(GLOBAL_CFLAGS) $(OCTASIC_CFLAGS)
|
||||
endif
|
||||
|
||||
libhexfile_la_SOURCES = \
|
||||
hexfile.c \
|
||||
hexfile.h \
|
||||
#
|
||||
|
||||
sbin_PROGRAMS = \
|
||||
astribank_tool \
|
||||
astribank_hexload \
|
||||
astribank_allow \
|
||||
astribank_is_starting
|
||||
|
||||
check_PROGRAMS = test_parse
|
||||
test_parse_LDADD = libhexfile.la
|
||||
|
||||
astribank_tool_SOURCES = astribank_tool.c
|
||||
astribank_tool_CFLAGS = $(GLOBAL_CFLAGS)
|
||||
astribank_tool_LDFLAGS = $(USB_LIBS)
|
||||
astribank_tool_LDADD = libastribank.la
|
||||
|
||||
astribank_hexload_SOURCES = \
|
||||
astribank_hexload.c \
|
||||
pic_loader.c \
|
||||
pic_loader.h \
|
||||
#
|
||||
|
||||
astribank_hexload_CFLAGS = $(GLOBAL_CFLAGS) $(OCTASIC_CFLAGS)
|
||||
astribank_hexload_LDFLAGS = $(USB_LIBS)
|
||||
astribank_hexload_LDADD = \
|
||||
libhexfile.la \
|
||||
libastribank.la \
|
||||
libecholoader.la \
|
||||
oct612x/liboctasic.la \
|
||||
#
|
||||
|
||||
astribank_allow_CFLAGS = $(GLOBAL_CFLAGS)
|
||||
astribank_allow_LDFLAGS = $(USB_LIBS)
|
||||
astribank_allow_LDADD = libastribank.la
|
||||
|
||||
man_pages = \
|
||||
astribank_tool.8 \
|
||||
astribank_hexload.8 \
|
||||
astribank_allow.8 \
|
||||
astribank_is_starting.8
|
||||
|
||||
man_MANS += $(man_pages)
|
||||
|
||||
endif
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(man_pages) \
|
||||
$(udevrules_DATA) \
|
||||
README.Astribank \
|
||||
astribank_upgrade \
|
||||
dahdi.cgi \
|
||||
dahdi_drivers \
|
||||
genconf_parameters \
|
||||
twinstar_hook \
|
||||
twinstar_setup \
|
||||
xpp_modprobe \
|
||||
xpp_timing \
|
||||
#
|
||||
|
|
@ -47,9 +47,9 @@ Apart from the standard DAHDI build requirements, you also need:
|
|||
|
||||
* *libusb development headers* to build the Astribank firmware tools
|
||||
(astribank_tool, astribank_hexload, astribank_allow).
|
||||
This is typically the package libusb-dev on Debian (and derivatives
|
||||
like Ubuntu) or libusb-devel on RedHat (and derivatives like
|
||||
CentOS/Trixbox).
|
||||
This is typically the package libusb-1.0-0-dev on Debian (and
|
||||
derivatives such as Ubuntu) or libusbx-devel on RedHat (and derivatives
|
||||
such as CentOS).
|
||||
* *Echo Canceller Module firmware*: If you have an Astribank with an
|
||||
echo canceller module, see the following section.
|
||||
|
||||
|
@ -1257,8 +1257,8 @@ Astribanks Synchronization Source
|
|||
If there is more than one Astribank on the system, all the Astribanks
|
||||
keep their clock in sync. Optionally the Astribanks can synchronize
|
||||
their clock to the master DAHDI device (in case it is a different DAHDI
|
||||
device). Normally you just use the default init.d script or run
|
||||
explicitly:
|
||||
device). Normally it would be run automatically from the udev hooks
|
||||
run on device plug (handle_device), but you can also run it explicitly:
|
||||
|
||||
xpp_sync auto
|
||||
|
||||
|
@ -1488,6 +1488,9 @@ other side.
|
|||
current. That is: which ones are connected to an active FXS on the
|
||||
other side.
|
||||
|
||||
===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/hwid
|
||||
Prints <module type>.<module subtype>. Both are small numbers.
|
||||
|
||||
===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/offhook
|
||||
Shows ports that are (1) or are not (0) off-hook. When a channel is
|
||||
not off-hook. For BRI and E1/T1 the value is 1 if the span is in use.
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <xtalk/debug.h>
|
||||
#include <xtalk/xusb.h>
|
||||
#include "mpptalk.h"
|
||||
#include "astribank.h"
|
||||
|
||||
#define DBG_MASK 0x08
|
||||
|
||||
struct astribank {
|
||||
struct xusb_device *xusb_device;
|
||||
struct xusb_iface *xpp_iface;
|
||||
struct xusb_iface *mpp_iface;
|
||||
struct mpp_device *mpp;
|
||||
char *path;
|
||||
};
|
||||
|
||||
|
||||
struct astribank *astribank_new(const char *path)
|
||||
{
|
||||
struct astribank *ab;
|
||||
|
||||
ab = calloc(sizeof(*ab), 1);
|
||||
if (!ab) {
|
||||
ERR("%s: Failed allocating Astribank device\n", path);
|
||||
goto err;
|
||||
}
|
||||
ab->xusb_device = xusb_find_bypath(path);
|
||||
if (!ab->xusb_device) {
|
||||
ERR("%s: Cannot find Astribank\n", path);
|
||||
goto err;
|
||||
}
|
||||
ab->path = strdup(path);
|
||||
if (!ab->path) {
|
||||
ERR("%s: Failed allocating Astribank path\n", path);
|
||||
goto err;
|
||||
}
|
||||
return ab;
|
||||
err:
|
||||
astribank_destroy(ab);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void astribank_destroy(struct astribank *ab)
|
||||
{
|
||||
if (ab) {
|
||||
if (ab->path)
|
||||
free(ab->path);
|
||||
if (ab->xpp_iface)
|
||||
xusb_release(ab->xpp_iface);
|
||||
if (ab->mpp) {
|
||||
mpp_delete(ab->mpp); /* this also closes the underlying xusb */
|
||||
ab->mpp = NULL;
|
||||
}
|
||||
if (ab->xusb_device) {
|
||||
xusb_destroy(ab->xusb_device);
|
||||
ab->xusb_device = NULL;
|
||||
}
|
||||
free(ab);
|
||||
ab = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct xusb_iface *astribank_xpp_open(struct astribank *ab)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = xusb_claim(ab->xusb_device, 0, &ab->xpp_iface);
|
||||
if (ret < 0) {
|
||||
ERR("%s: Cannot claim XPP interface\n", ab->path);
|
||||
goto err;
|
||||
}
|
||||
DBG("%s: Claimed Astribank XPP interface\n", ab->path);
|
||||
return ab->xpp_iface;
|
||||
err:
|
||||
if (ab->xpp_iface)
|
||||
xusb_release(ab->xpp_iface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mpp_device *astribank_mpp_open(struct astribank *ab)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = xusb_claim(ab->xusb_device, 1, &ab->mpp_iface);
|
||||
if (ret < 0) {
|
||||
ERR("%s: Cannot claim MPP interface\n", ab->path);
|
||||
goto err;
|
||||
}
|
||||
DBG("%s: Claimed Astribank MPP interface\n", ab->path);
|
||||
ab->mpp = mpp_new(ab->mpp_iface);
|
||||
if (!ab->mpp) {
|
||||
ERR("Failed initializing MPP protocol\n");
|
||||
goto err;
|
||||
}
|
||||
ret = mpp_status_query(ab->mpp);
|
||||
if (ret < 0) {
|
||||
ERR("status query failed (ret=%d)\n", ret);
|
||||
goto err;
|
||||
}
|
||||
return ab->mpp;
|
||||
err:
|
||||
if (ab->mpp) {
|
||||
mpp_delete(ab->mpp); /* this also closes the underlying xusb */
|
||||
ab->mpp = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct xusb_device *xusb_dev_of_astribank(const struct astribank *ab)
|
||||
{
|
||||
assert(ab->xusb_device);
|
||||
return ab->xusb_device;
|
||||
}
|
||||
|
||||
const char *astribank_devpath(const struct astribank *ab)
|
||||
{
|
||||
return xusb_devpath(ab->xusb_device);
|
||||
}
|
||||
|
||||
const char *astribank_serial(const struct astribank *ab)
|
||||
{
|
||||
return xusb_serial(ab->xusb_device);
|
||||
}
|
||||
|
||||
void show_astribank_info(const struct astribank *ab)
|
||||
{
|
||||
struct xusb_device *xusb_device;
|
||||
|
||||
assert(ab != NULL);
|
||||
xusb_device = ab->xusb_device;
|
||||
assert(xusb_device != NULL);
|
||||
if(verbose <= LOG_INFO) {
|
||||
xusb_showinfo(xusb_device);
|
||||
} else {
|
||||
const struct xusb_spec *spec;
|
||||
|
||||
spec = xusb_spec(xusb_device);
|
||||
printf("USB Bus/Device: [%s]\n", xusb_devpath(xusb_device));
|
||||
printf("USB Firmware Type: [%s]\n", spec->name);
|
||||
printf("USB iSerialNumber: [%s]\n", xusb_serial(xusb_device));
|
||||
printf("USB iManufacturer: [%s]\n", xusb_manufacturer(xusb_device));
|
||||
printf("USB iProduct: [%s]\n", xusb_product(xusb_device));
|
||||
}
|
||||
}
|
||||
|
||||
int astribank_send(struct astribank *ab, int interface_num, const char *buf, int len, int timeout)
|
||||
{
|
||||
struct xusb_iface *iface;
|
||||
|
||||
if (interface_num == 0)
|
||||
iface = ab->xpp_iface;
|
||||
else if (interface_num == 1)
|
||||
iface = ab->mpp_iface;
|
||||
else {
|
||||
ERR("Unknown interface number (%d)\n", interface_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
return xusb_send(iface, buf, len, timeout);
|
||||
}
|
||||
|
||||
int astribank_recv(struct astribank *ab, int interface_num, char *buf, size_t len, int timeout)
|
||||
{
|
||||
struct xusb_iface *iface;
|
||||
|
||||
if (interface_num == 0)
|
||||
iface = ab->xpp_iface;
|
||||
else if (interface_num == 1)
|
||||
iface = ab->mpp_iface;
|
||||
else {
|
||||
ERR("Unknown interface number (%d)\n", interface_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
return xusb_recv(iface, buf, len, timeout);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef ASTRIBANK_H
|
||||
#define ASTRIBANK_H
|
||||
|
||||
#include <mpptalk.h>
|
||||
|
||||
struct astribank *astribank_new(const char *path);
|
||||
void astribank_destroy(struct astribank *ab);
|
||||
void show_astribank_info(const struct astribank *ab);
|
||||
|
||||
struct xusb_iface *astribank_xpp_open(struct astribank *ab);
|
||||
struct mpp_device *astribank_mpp_open(struct astribank *ab);
|
||||
|
||||
struct xusb_device *xusb_dev_of_astribank(const struct astribank *ab);
|
||||
const char *astribank_devpath(const struct astribank *ab);
|
||||
const char *astribank_serial(const struct astribank *ab);
|
||||
|
||||
int astribank_send(struct astribank *ab, int interface_num, const char *buf, int len, int timeout);
|
||||
int astribank_recv(struct astribank *ab, int interface_num, char *buf, size_t len, int timeout);
|
||||
|
||||
|
||||
#define AB_REPORT(report_type, astribank, fmt, ...) \
|
||||
report_type("%s [%s]: " fmt, \
|
||||
astribank_devpath(astribank), \
|
||||
astribank_serial(astribank), \
|
||||
## __VA_ARGS__)
|
||||
|
||||
#define AB_INFO(astribank, fmt, ...) \
|
||||
AB_REPORT(INFO, astribank, fmt, ## __VA_ARGS__)
|
||||
|
||||
#define AB_ERR(astribank, fmt, ...) \
|
||||
AB_REPORT(ERR, astribank, fmt, ## __VA_ARGS__)
|
||||
|
||||
#endif /* ASTRIBANK_H */
|
|
@ -31,13 +31,11 @@
|
|||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ctype.h>
|
||||
#include "mpp.h"
|
||||
#include <xtalk/debug.h>
|
||||
#include "mpptalk.h"
|
||||
#include <debug.h>
|
||||
#include "astribank.h"
|
||||
#include "astribank_license.h"
|
||||
|
||||
static const char rcsid[] = "$Id$";
|
||||
|
||||
#define DBG_MASK 0x80
|
||||
|
||||
static char *progname;
|
||||
|
@ -55,28 +53,11 @@ static void usage()
|
|||
exit(1);
|
||||
}
|
||||
|
||||
static int capabilities_burn(
|
||||
struct astribank_device *astribank,
|
||||
struct eeprom_table *eeprom_table,
|
||||
struct capabilities *capabilities,
|
||||
struct capkey *key)
|
||||
{
|
||||
int ret;
|
||||
|
||||
INFO("Burning capabilities\n");
|
||||
ret = mpp_caps_set(astribank, eeprom_table, capabilities, key);
|
||||
if(ret < 0) {
|
||||
ERR("Capabilities burning failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
INFO("Done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *devpath = NULL;
|
||||
struct astribank_device *astribank;
|
||||
struct astribank *astribank;
|
||||
struct mpp_device *mpp;
|
||||
struct eeprom_table eeprom_table;
|
||||
struct capabilities caps;
|
||||
struct capkey key;
|
||||
|
@ -127,16 +108,19 @@ int main(int argc, char *argv[])
|
|||
usage();
|
||||
}
|
||||
DBG("Startup %s\n", devpath);
|
||||
if((astribank = mpp_init(devpath, 1)) == NULL) {
|
||||
ERR("Failed initializing MPP\n");
|
||||
astribank = astribank_new(devpath);
|
||||
if(!astribank) {
|
||||
ERR("Failed initializing Astribank\n");
|
||||
return 1;
|
||||
}
|
||||
if(astribank->eeprom_type != EEPROM_TYPE_LARGE) {
|
||||
mpp = astribank_mpp_open(astribank);
|
||||
ret = mpp_eeprom_type(mpp);
|
||||
if(ret != EEPROM_TYPE_LARGE) {
|
||||
ERR("Cannot use this program with astribank EEPROM type %d (need %d)\n",
|
||||
astribank->eeprom_type, EEPROM_TYPE_LARGE);
|
||||
ret, EEPROM_TYPE_LARGE);
|
||||
return 1;
|
||||
}
|
||||
ret = mpp_caps_get(astribank, &eeprom_table, &caps, &key);
|
||||
ret = mpp_caps_get(mpp, &eeprom_table, &caps, &key);
|
||||
if(ret < 0) {
|
||||
ERR("Failed to get original capabilities: %d\n", ret);
|
||||
return 1;
|
||||
|
@ -158,8 +142,13 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
show_capabilities(&caps, stderr);
|
||||
if (capabilities_burn(astribank, &eeprom_table, &caps, &key) < 0)
|
||||
INFO("Burning capabilities\n");
|
||||
ret = mpp_caps_set(mpp, &eeprom_table, &caps, &key);
|
||||
if(ret < 0) {
|
||||
ERR("Capabilities burning failed: %d\n", ret);
|
||||
return 1;
|
||||
}
|
||||
INFO("Done\n");
|
||||
if (file != stdin)
|
||||
fclose(file);
|
||||
} else {
|
||||
|
@ -180,6 +169,6 @@ int main(int argc, char *argv[])
|
|||
if (file != stdout)
|
||||
fclose(file);
|
||||
}
|
||||
mpp_exit(astribank);
|
||||
astribank_destroy(astribank);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ Examples:
|
|||
1:T1,2:T1,*:E1 \- First and second ports are T1, the rest are E1.
|
||||
.RE
|
||||
|
||||
If the \fB\-S\fR is not given, the PRI default is determined by the existance of the \fB\-A-fR option.
|
||||
If the \fB\-S\fR is not given, the PRI default is determined by the existence of the \fB\-A-fR option.
|
||||
.RE
|
||||
|
||||
.SH SEE ALSO
|
||||
|
|
|
@ -28,13 +28,14 @@
|
|||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <debug.h>
|
||||
#include <autoconfig.h>
|
||||
#include <xtalk/debug.h>
|
||||
#include <xtalk/xusb.h>
|
||||
#include "hexfile.h"
|
||||
#include "mpptalk.h"
|
||||
#include "astribank.h"
|
||||
#include "pic_loader.h"
|
||||
#include "echo_loader.h"
|
||||
#include "astribank_usb.h"
|
||||
#include "../autoconfig.h"
|
||||
|
||||
#define DBG_MASK 0x80
|
||||
#define MAX_HEX_LINES 64000
|
||||
|
@ -61,7 +62,7 @@ static void usage()
|
|||
exit(1);
|
||||
}
|
||||
|
||||
int handle_hexline(struct astribank_device *astribank, struct hexline *hexline)
|
||||
int handle_hexline(struct mpp_device *mpp, struct hexline *hexline)
|
||||
{
|
||||
uint16_t len;
|
||||
uint16_t offset_dummy;
|
||||
|
@ -69,7 +70,7 @@ int handle_hexline(struct astribank_device *astribank, struct hexline *hexline)
|
|||
int ret;
|
||||
|
||||
assert(hexline);
|
||||
assert(astribank);
|
||||
assert(mpp);
|
||||
if(hexline->d.content.header.tt != TT_DATA) {
|
||||
DBG("Non data record type = %d\n", hexline->d.content.header.tt);
|
||||
return 0;
|
||||
|
@ -77,14 +78,19 @@ int handle_hexline(struct astribank_device *astribank, struct hexline *hexline)
|
|||
len = hexline->d.content.header.ll;
|
||||
offset_dummy = hexline->d.content.header.offset;
|
||||
data = hexline->d.content.tt_data.data;
|
||||
if((ret = mpp_send_seg(astribank, data, offset_dummy, len)) < 0) {
|
||||
if((ret = mpp_send_seg(mpp, data, offset_dummy, len)) < 0) {
|
||||
ERR("Failed hexfile send line: %d\n", ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_parse_errors(int level, const char *msg, ...)
|
||||
|
||||
#ifdef __GNUC__
|
||||
static void print_parse_errors(int level, const char *msg, ...) __attribute__((format(printf,2,3)));
|
||||
#endif
|
||||
|
||||
static void print_parse_errors(int level, const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
@ -95,7 +101,7 @@ void print_parse_errors(int level, const char *msg, ...)
|
|||
}
|
||||
}
|
||||
|
||||
static int load_hexfile(struct astribank_device *astribank, const char *hexfile, enum dev_dest dest)
|
||||
static int load_hexfile(struct mpp_device *mpp, const char *hexfile, enum dev_dest dest)
|
||||
{
|
||||
struct hexdata *hexdata = NULL;
|
||||
int finished = 0;
|
||||
|
@ -103,19 +109,24 @@ static int load_hexfile(struct astribank_device *astribank, const char *hexfile,
|
|||
unsigned i;
|
||||
char star[] = "+\\+|+/+-";
|
||||
const char *devstr;
|
||||
struct xusb_device *xusb_device;
|
||||
struct xusb_iface *xusb_iface;
|
||||
|
||||
|
||||
parse_hexfile_set_reporting(print_parse_errors);
|
||||
if((hexdata = parse_hexfile(hexfile, MAX_HEX_LINES)) == NULL) {
|
||||
perror(hexfile);
|
||||
return -errno;
|
||||
}
|
||||
devstr = xusb_devpath(astribank->xusb);
|
||||
xusb_iface = xubs_iface_of_mpp(mpp);
|
||||
xusb_device = xusb_deviceof(xusb_iface);
|
||||
devstr = xusb_devpath(xusb_device);
|
||||
INFO("%s [%s]: Loading %s Firmware: %s (version %s)\n",
|
||||
devstr,
|
||||
xusb_serial(astribank->xusb),
|
||||
xusb_serial(xusb_device),
|
||||
dev_dest2str(dest),
|
||||
hexdata->fname, hexdata->version_info);
|
||||
if((ret = mpp_send_start(astribank, dest, hexdata->version_info)) < 0) {
|
||||
if((ret = mpp_send_start(mpp, dest, hexdata->version_info)) < 0) {
|
||||
ERR("%s: Failed hexfile send start: %d\n", devstr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -137,7 +148,7 @@ static int load_hexfile(struct astribank_device *astribank, const char *hexfile,
|
|||
finished = 1;
|
||||
continue;
|
||||
}
|
||||
if((ret = handle_hexline(astribank, hexline)) < 0) {
|
||||
if((ret = handle_hexline(mpp, hexline)) < 0) {
|
||||
ERR("%s: Failed hexfile sending in lineno %d (ret=%d)\n", devstr, i, ret);;
|
||||
return ret;
|
||||
}
|
||||
|
@ -146,7 +157,7 @@ static int load_hexfile(struct astribank_device *astribank, const char *hexfile,
|
|||
putchar('\n');
|
||||
fflush(stdout);
|
||||
}
|
||||
if((ret = mpp_send_end(astribank)) < 0) {
|
||||
if((ret = mpp_send_end(mpp)) < 0) {
|
||||
ERR("%s: Failed hexfile send end: %d\n", devstr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -173,7 +184,6 @@ int main(int argc, char *argv[])
|
|||
int opt_sum = 0;
|
||||
enum dev_dest dest = DEST_NONE;
|
||||
const char options[] = "vd:D:EFOopAS:";
|
||||
int iface_num;
|
||||
int ret;
|
||||
|
||||
progname = argv[0];
|
||||
|
@ -242,7 +252,6 @@ int main(int argc, char *argv[])
|
|||
" and -p options are mutually exclusive, if neither is used then -o should present\n");
|
||||
usage();
|
||||
}
|
||||
iface_num = (opt_dest) ? 1 : 0;
|
||||
if(!opt_pic && !opt_ecver) {
|
||||
if(optind != argc - 1) {
|
||||
ERR("Got %d hexfile names (Need exactly one hexfile)\n",
|
||||
|
@ -265,29 +274,43 @@ int main(int argc, char *argv[])
|
|||
/*
|
||||
* MPP Interface
|
||||
*/
|
||||
struct astribank_device *astribank;
|
||||
struct astribank *astribank;
|
||||
struct mpp_device *mpp;
|
||||
|
||||
if((astribank = mpp_init(devpath, iface_num)) == NULL) {
|
||||
astribank = astribank_new(devpath);
|
||||
if(!astribank) {
|
||||
ERR("%s: Opening astribank failed\n", devpath);
|
||||
return 1;
|
||||
}
|
||||
//show_astribank_info(astribank);
|
||||
if(load_hexfile(astribank, argv[optind], dest) < 0) {
|
||||
mpp = astribank_mpp_open(astribank);
|
||||
if(!mpp) {
|
||||
ERR("%s: Opening astribank XPP interface failed\n", devpath);
|
||||
return 1;
|
||||
}
|
||||
show_astribank_info(astribank);
|
||||
if(load_hexfile(mpp, argv[optind], dest) < 0) {
|
||||
ERR("%s: Loading firmware to %s failed\n", devpath, dev_dest2str(dest));
|
||||
return 1;
|
||||
}
|
||||
astribank_close(astribank, 0);
|
||||
astribank_destroy(astribank);
|
||||
} else if(opt_pic || opt_echo || opt_ecver) {
|
||||
/*
|
||||
* XPP Interface
|
||||
*/
|
||||
struct astribank_device *astribank;
|
||||
struct astribank *astribank;
|
||||
struct xusb_iface *xpp_iface;
|
||||
|
||||
if((astribank = astribank_open(devpath, iface_num)) == NULL) {
|
||||
astribank = astribank_new(devpath);
|
||||
if (!astribank) {
|
||||
ERR("%s: Opening astribank failed\n", devpath);
|
||||
return 1;
|
||||
}
|
||||
//show_astribank_info(astribank);
|
||||
xpp_iface = astribank_xpp_open(astribank);
|
||||
if(!xpp_iface) {
|
||||
ERR("%s: Opening astribank XPP interface failed\n", devpath);
|
||||
return 1;
|
||||
}
|
||||
show_astribank_info(astribank);
|
||||
#if HAVE_OCTASIC
|
||||
if (opt_ecver) {
|
||||
if((ret = echo_ver(astribank)) < 0) {
|
||||
|
@ -310,7 +333,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
#endif
|
||||
}
|
||||
astribank_close(astribank, 0);
|
||||
astribank_destroy(astribank);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -94,22 +94,27 @@ wait_for_udev() {
|
|||
UDEV_SETTLE_MAX_TIME=10
|
||||
|
||||
echo "Waiting for udev to settle down..."
|
||||
if [ -x /sbin/udevsettle ]; then
|
||||
# Old system, stand-alone udevsettle command
|
||||
/sbin/udevsettle --timeout="$UDEV_SETTLE_MAX_TIME"
|
||||
udevsettle_cmd=
|
||||
if [ -x /bin/udevadm ]; then
|
||||
udevsettle_cmd="/bin/udevadm settle"
|
||||
elif [ -x /sbin/udevadm ]; then
|
||||
# Assume modern system, udevadm has settle parameter
|
||||
if ! /sbin/udevadm settle --timeout="$UDEV_SETTLE_MAX_TIME"
|
||||
then
|
||||
echo "udevadm failed ($?)."
|
||||
echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds."
|
||||
sleep "$UDEV_SETTLE_MAX_TIME"
|
||||
fi
|
||||
udevsettle_cmd="/sbin/udevadm settle"
|
||||
elif [ -x /sbin/udevsettle ]; then
|
||||
udevsettle_cmd="/sbin/udevsettle"
|
||||
else
|
||||
echo "No udevsettle/udevadm."
|
||||
echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds."
|
||||
sleep "$UDEV_SETTLE_MAX_TIME"
|
||||
return
|
||||
fi
|
||||
|
||||
if ! $udevsettle_cmd --timeout="$UDEV_SETTLE_MAX_TIME"
|
||||
then
|
||||
echo "udevadm failed ($?)."
|
||||
echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds."
|
||||
sleep "$UDEV_SETTLE_MAX_TIME"
|
||||
fi
|
||||
|
||||
sleep 1 # Wait a bit more (races)
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ Q: Why do you use a semaphore?
|
|||
A: because, unlike the filesystem, it is writable at any given time.
|
||||
|
||||
.SH BUGS
|
||||
Option ordering matter. The \fB\-v\fR and \fB\-d\fR options should preceed
|
||||
Option ordering matter. The \fB\-v\fR and \fB\-d\fR options should precede
|
||||
the actions (\fB\-a\fR, \fB\-r\fR and \fB\-w\fR).
|
||||
The \fB\-t\fItimeout\fR option should preceed the \fB\-w\fR option.
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
#include <xtalk/debug.h>
|
||||
#include "astribank_license.h"
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef ASTRIBANK_ALLOW_H
|
||||
#define ASTRIBANK_ALLOW_H
|
||||
|
||||
#include "mpp.h"
|
||||
#include "mpptalk.h"
|
||||
|
||||
enum license_markers {
|
||||
LICENSE_MARKER_NONE = 0,
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
#include <getopt.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "astribank_usb.h"
|
||||
#include <xtalk/debug.h>
|
||||
#include <xtalk/xusb.h>
|
||||
#include "mpptalk.h"
|
||||
#include <debug.h>
|
||||
#include <xusb.h>
|
||||
#include "astribank.h"
|
||||
|
||||
#define DBG_MASK 0x80
|
||||
/* if enabled, adds support for resetting pre-MPP USB firmware - if we
|
||||
|
@ -72,94 +72,15 @@ static int reset_kind(const char *arg)
|
|||
if(strcasecmp(reset_kinds[i].name, arg) == 0)
|
||||
return reset_kinds[i].type_code;
|
||||
}
|
||||
ERR("Uknown reset kind '%s'\n", arg);
|
||||
ERR("Unknown reset kind '%s'\n", arg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int show_hardware(struct astribank_device *astribank)
|
||||
{
|
||||
int ret;
|
||||
struct eeprom_table eeprom_table;
|
||||
struct capabilities capabilities;
|
||||
struct extrainfo extrainfo;
|
||||
|
||||
ret = mpp_caps_get(astribank, &eeprom_table, &capabilities, NULL);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
show_eeprom(&eeprom_table, stdout);
|
||||
show_astribank_status(astribank, stdout);
|
||||
if(astribank->eeprom_type == EEPROM_TYPE_LARGE) {
|
||||
show_capabilities(&capabilities, stdout);
|
||||
if(STATUS_FPGA_LOADED(astribank->status)) {
|
||||
uint8_t unit;
|
||||
uint8_t card_status;
|
||||
uint8_t card_type;
|
||||
uint8_t fpga_configuration;
|
||||
uint8_t status;
|
||||
|
||||
for(unit = 0; unit < 5; unit++) {
|
||||
ret = mpps_card_info(astribank, unit, &card_type, &card_status);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
printf("CARD %d: type=%x.%x %s\n", unit,
|
||||
((card_type >> 4) & 0xF), (card_type & 0xF),
|
||||
((card_status & 0x1) ? "PIC" : "NOPIC"));
|
||||
}
|
||||
ret = mpps_stat(astribank, unit, &fpga_configuration, &status);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
printf("FPGA: %-17s: %d\n", "Configuration num", fpga_configuration);
|
||||
printf("FPGA: %-17s: %s\n", "Watchdog Timer",
|
||||
(SER_STAT_WATCHDOG_READY(status)) ? "ready" : "expired");
|
||||
printf("FPGA: %-17s: %s\n", "XPD Alive",
|
||||
(SER_STAT_XPD_ALIVE(status)) ? "yes" : "no");
|
||||
}
|
||||
ret = mpp_extrainfo_get(astribank, &extrainfo);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
show_extrainfo(&extrainfo, stdout);
|
||||
if(CAP_EXTRA_TWINSTAR(&capabilities)) {
|
||||
twinstar_show(astribank, stdout);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_OLD_RESET
|
||||
/* Try to reset a device using USB_FW.hex, up to Xorcom rev. 6885 */
|
||||
int old_reset(const char* devpath)
|
||||
{
|
||||
struct astribank_device *astribank;
|
||||
int ret;
|
||||
struct {
|
||||
uint8_t op;
|
||||
} PACKED header = {0x20}; /* PT_RESET */
|
||||
char *buf = (char*) &header;
|
||||
|
||||
/* Note that the function re-opens the connection to the Astribank
|
||||
* as any reference to the previous connection was lost when mpp_open
|
||||
* returned NULL as the astribank reference. */
|
||||
astribank = astribank_open(devpath, 1);
|
||||
if (!astribank) {
|
||||
DBG("Failed re-opening astribank device for old_reset\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = xusb_send(astribank->xusb, buf, 1, 5000);
|
||||
|
||||
/* If we just had a reenumeration, we may get -ENODEV */
|
||||
if(ret < 0 && ret != -ENODEV)
|
||||
return ret;
|
||||
/* We don't astribank_close(), as it has likely been
|
||||
* reenumerated by now. */
|
||||
return 0;
|
||||
}
|
||||
#endif /* SUPPORT_OLD_RESET */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *devpath = NULL;
|
||||
struct astribank_device *astribank;
|
||||
struct astribank *astribank;
|
||||
struct mpp_device *mpp;
|
||||
const char options[] = "vd:D:nr:p:w:Q";
|
||||
int opt_renumerate = 0;
|
||||
char *opt_port = NULL;
|
||||
|
@ -218,20 +139,12 @@ int main(int argc, char *argv[])
|
|||
usage();
|
||||
}
|
||||
DBG("Startup %s\n", devpath);
|
||||
if((astribank = mpp_init(devpath, 1)) == NULL) {
|
||||
ERR("Failed initializing MPP\n");
|
||||
#ifdef SUPPORT_OLD_RESET
|
||||
DBG("opt_reset = %s\n", opt_reset);
|
||||
if (opt_reset) {
|
||||
DBG("Trying old reset method\n");
|
||||
if ((ret = old_reset(devpath)) != 0) {
|
||||
ERR("Old reset method failed as well: %d\n", ret);
|
||||
}
|
||||
}
|
||||
#endif /* SUPPORT_OLD_RESET */
|
||||
|
||||
astribank = astribank_new(devpath);
|
||||
if(!astribank) {
|
||||
ERR("Failed initializing Astribank\n");
|
||||
return 1;
|
||||
}
|
||||
mpp = astribank_mpp_open(astribank);
|
||||
/*
|
||||
* First process reset options. We want to be able
|
||||
* to reset minimal USB firmwares even if they don't
|
||||
|
@ -244,19 +157,19 @@ int main(int argc, char *argv[])
|
|||
ERR("Bad reset kind '%s'\n", opt_reset);
|
||||
return 1;
|
||||
}
|
||||
DBG("Reseting (%s)\n", opt_reset);
|
||||
if((ret = mpp_reset(astribank, full_reset)) < 0) {
|
||||
ERR("%s Reseting astribank failed: %d\n",
|
||||
DBG("Resetting (%s)\n", opt_reset);
|
||||
if((ret = mpp_reset(mpp, full_reset)) < 0) {
|
||||
ERR("%s Resetting astribank failed: %d\n",
|
||||
(full_reset) ? "Full" : "Half", ret);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
show_astribank_info(astribank);
|
||||
if(opt_query) {
|
||||
show_hardware(astribank);
|
||||
show_hardware(mpp);
|
||||
} else if(opt_renumerate) {
|
||||
DBG("Renumerate\n");
|
||||
if((ret = mpp_renumerate(astribank)) < 0) {
|
||||
if((ret = mpp_renumerate(mpp)) < 0) {
|
||||
ERR("Renumerating astribank failed: %d\n", ret);
|
||||
}
|
||||
} else if(opt_watchdog) {
|
||||
|
@ -264,24 +177,24 @@ int main(int argc, char *argv[])
|
|||
|
||||
DBG("TWINSTAR: Setting watchdog %s-guard\n",
|
||||
(watchdogstate) ? "on" : "off");
|
||||
if((ret = mpp_tws_setwatchdog(astribank, watchdogstate)) < 0) {
|
||||
if((ret = mpp_tws_setwatchdog(mpp, watchdogstate)) < 0) {
|
||||
ERR("Failed to set watchdog to %d\n", watchdogstate);
|
||||
return 1;
|
||||
}
|
||||
} else if(opt_port) {
|
||||
int new_portnum = strtoul(opt_port, NULL, 0);
|
||||
int tws_portnum = mpp_tws_portnum(astribank);
|
||||
int tws_portnum = mpp_tws_portnum(mpp);
|
||||
char *msg = (new_portnum == tws_portnum)
|
||||
? " Same same, never mind..."
|
||||
: "";
|
||||
|
||||
DBG("TWINSTAR: Setting portnum to %d.%s\n", new_portnum, msg);
|
||||
if((ret = mpp_tws_setportnum(astribank, new_portnum)) < 0) {
|
||||
if((ret = mpp_tws_setportnum(mpp, new_portnum)) < 0) {
|
||||
ERR("Failed to set USB portnum to %d\n", new_portnum);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
out:
|
||||
mpp_exit(astribank);
|
||||
astribank_destroy(astribank);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,276 +0,0 @@
|
|||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2008, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for memrchr() */
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <syslog.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <xusb.h>
|
||||
#include "astribank_usb.h"
|
||||
#include <debug.h>
|
||||
|
||||
static const char rcsid[] = "$Id$";
|
||||
|
||||
#define DBG_MASK 0x01
|
||||
#define TIMEOUT 500
|
||||
|
||||
#define TYPE_ENTRY(t,p,ni,n,ne,out,in,...) \
|
||||
{ \
|
||||
.my_vendor_id = 0xe4e4, \
|
||||
.my_product_id = (p), \
|
||||
.name = #t, \
|
||||
.num_interfaces = (ni), \
|
||||
.my_interface_num = (n), \
|
||||
.num_endpoints = (ne), \
|
||||
.my_ep_in = (in), \
|
||||
.my_ep_out = (out), \
|
||||
}
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
static const struct xusb_spec astribank_specs[] = {
|
||||
/* OLD Firmwares */
|
||||
TYPE_ENTRY("USB-OLDFXS", 0x1131, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
|
||||
TYPE_ENTRY("FPGA-OLDFXS", 0x1132, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
|
||||
TYPE_ENTRY("USB-BRI", 0x1141, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
|
||||
TYPE_ENTRY("FPGA-BRI", 0x1142, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
|
||||
TYPE_ENTRY("USB-OLD", 0x1151, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
|
||||
TYPE_ENTRY("FPGA-OLD", 0x1152, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
|
||||
|
||||
TYPE_ENTRY("USB-MULTI", 0x1161, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
|
||||
TYPE_ENTRY("FPGA-MULTI", 0x1162, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
|
||||
TYPE_ENTRY("BURNED-MULTI", 0x1164, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
|
||||
TYPE_ENTRY("USB-BURN", 0x1112, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
|
||||
};
|
||||
|
||||
static const struct xusb_spec astribank_pic_specs[] = {
|
||||
TYPE_ENTRY("USB_PIC", 0x1161, 2, 0, 2, XPP_EP_OUT, XPP_EP_IN),
|
||||
};
|
||||
#undef TYPE_ENTRY
|
||||
|
||||
//static int verbose = LOG_DEBUG;
|
||||
|
||||
/*
|
||||
* USB handling
|
||||
*/
|
||||
struct astribank_device *astribank_open(const char devpath[], int iface_num)
|
||||
{
|
||||
struct astribank_device *astribank = NULL;
|
||||
struct xusb *xusb;
|
||||
|
||||
DBG("devpath='%s' iface_num=%d\n", devpath, iface_num);
|
||||
if((astribank = malloc(sizeof(struct astribank_device))) == NULL) {
|
||||
ERR("Out of memory\n");
|
||||
goto fail;
|
||||
}
|
||||
memset(astribank, 0, sizeof(*astribank));
|
||||
if (iface_num) {
|
||||
xusb = xusb_find_bypath(astribank_specs, ARRAY_SIZE(astribank_specs), devpath);
|
||||
} else {
|
||||
xusb = xusb_find_bypath(astribank_pic_specs, ARRAY_SIZE(astribank_pic_specs), devpath);
|
||||
}
|
||||
if (!xusb) {
|
||||
ERR("%s: No device found\n", __func__);
|
||||
goto fail;
|
||||
}
|
||||
astribank->xusb = xusb;
|
||||
astribank->is_usb2 = (xusb_packet_size(xusb) == 512);
|
||||
astribank->my_interface_num = iface_num;
|
||||
if (xusb_claim_interface(astribank->xusb) < 0) {
|
||||
ERR("xusb_claim_interface failed\n");
|
||||
goto fail;
|
||||
}
|
||||
astribank->tx_sequenceno = 1;
|
||||
return astribank;
|
||||
fail:
|
||||
if (astribank) {
|
||||
free(astribank);
|
||||
astribank = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* MP device handling
|
||||
*/
|
||||
void show_astribank_info(const struct astribank_device *astribank)
|
||||
{
|
||||
struct xusb *xusb;
|
||||
|
||||
assert(astribank != NULL);
|
||||
xusb = astribank->xusb;
|
||||
assert(xusb != NULL);
|
||||
if(verbose <= LOG_INFO) {
|
||||
xusb_showinfo(xusb);
|
||||
} else {
|
||||
const struct xusb_spec *spec;
|
||||
|
||||
spec = xusb_spec(xusb);
|
||||
printf("USB Bus/Device: [%s]\n", xusb_devpath(xusb));
|
||||
printf("USB Firmware Type: [%s]\n", spec->name);
|
||||
printf("USB iSerialNumber: [%s]\n", xusb_serial(xusb));
|
||||
printf("USB iManufacturer: [%s]\n", xusb_manufacturer(xusb));
|
||||
printf("USB iProduct: [%s]\n", xusb_product(xusb));
|
||||
}
|
||||
}
|
||||
|
||||
void astribank_close(struct astribank_device *astribank, int disconnected)
|
||||
{
|
||||
assert(astribank != NULL);
|
||||
if (astribank->xusb) {
|
||||
xusb_close(astribank->xusb);
|
||||
astribank->xusb = NULL;
|
||||
}
|
||||
astribank->tx_sequenceno = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int flush_read(struct astribank_device *astribank)
|
||||
{
|
||||
char tmpbuf[BUFSIZ];
|
||||
int ret;
|
||||
|
||||
DBG("starting...\n");
|
||||
memset(tmpbuf, 0, BUFSIZ);
|
||||
ret = recv_usb(astribank, tmpbuf, BUFSIZ, 1);
|
||||
if(ret < 0 && ret != -ETIMEDOUT) {
|
||||
ERR("ret=%d\n", ret);
|
||||
return ret;
|
||||
} else if(ret > 0) {
|
||||
DBG("Got %d bytes:\n", ret);
|
||||
dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, tmpbuf, ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int release_isvalid(uint16_t release)
|
||||
{
|
||||
uint8_t rmajor = (release >> 8) & 0xFF;
|
||||
uint8_t rminor = release & 0xFF;
|
||||
|
||||
return (rmajor > 0) &&
|
||||
(rmajor < 10) &&
|
||||
(rminor > 0) &&
|
||||
(rminor < 10);
|
||||
}
|
||||
|
||||
int label_isvalid(const char *label)
|
||||
{
|
||||
int len;
|
||||
int goodlen;
|
||||
const char GOOD_CHARS[] =
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"0123456789"
|
||||
"-_.";
|
||||
|
||||
len = strlen(label);
|
||||
goodlen = strspn(label, GOOD_CHARS);
|
||||
if(len > LABEL_SIZE) {
|
||||
ERR("Label too long (%d > %d)\n", len, LABEL_SIZE);
|
||||
return 0;
|
||||
}
|
||||
if(goodlen != len) {
|
||||
ERR("Bad character in label (pos=%d)\n", goodlen);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int eeprom_fill(struct eeprom_table *eprm,
|
||||
const char *vendor,
|
||||
const char *product,
|
||||
const char *release,
|
||||
const char *label)
|
||||
{
|
||||
uint16_t val;
|
||||
|
||||
eprm->source = 0xC0;
|
||||
eprm->config_byte = 0;
|
||||
if(vendor) {
|
||||
val = strtoul(vendor, NULL, 0);
|
||||
if(!val) {
|
||||
ERR("Invalid vendor '%s'\n",
|
||||
vendor);
|
||||
return -EINVAL;
|
||||
}
|
||||
eprm->vendor = val;
|
||||
}
|
||||
if(product) {
|
||||
val = strtoul(product, NULL, 0);
|
||||
if(!val) {
|
||||
ERR("Invalid product '%s'\n",
|
||||
product);
|
||||
return -EINVAL;
|
||||
}
|
||||
eprm->product = val;
|
||||
}
|
||||
if(release) {
|
||||
int release_major = 0;
|
||||
int release_minor = 0;
|
||||
uint16_t value;
|
||||
|
||||
if(sscanf(release, "%d.%d", &release_major, &release_minor) != 2) {
|
||||
ERR("Failed to parse release number '%s'\n", release);
|
||||
return -EINVAL;
|
||||
}
|
||||
value = (release_major << 8) | release_minor;
|
||||
DBG("Parsed release(%d): major=%d, minor=%d\n",
|
||||
value, release_major, release_minor);
|
||||
if(!release_isvalid(value)) {
|
||||
ERR("Invalid release number 0x%X\n", value);
|
||||
return -EINVAL;
|
||||
}
|
||||
eprm->release = value;
|
||||
}
|
||||
if(label) {
|
||||
/* padding */
|
||||
if(!label_isvalid(label)) {
|
||||
ERR("Invalid label '%s'\n", label);
|
||||
return -EINVAL;
|
||||
}
|
||||
memset(eprm->label, 0, LABEL_SIZE);
|
||||
memcpy(eprm->label, label, strlen(label));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int astribank_has_twinstar(struct astribank_device *astribank)
|
||||
{
|
||||
uint16_t product_series;
|
||||
|
||||
assert(astribank != NULL);
|
||||
product_series = xusb_product_id(astribank->xusb);
|
||||
product_series &= 0xFFF0;
|
||||
if(product_series == 0x1160) /* New boards */
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
#ifndef ASTRIBANK_USB_H
|
||||
#define ASTRIBANK_USB_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2008, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <xusb.h>
|
||||
#include <xtalk.h>
|
||||
#include "mpp.h"
|
||||
|
||||
/*
|
||||
* Astribank handling
|
||||
*/
|
||||
|
||||
#define PACKET_SIZE 512
|
||||
|
||||
/* USB Endpoints */
|
||||
#define MP_EP_OUT 0x04 /* Managment processor */
|
||||
#define MP_EP_IN 0x88 /* Managment processor */
|
||||
|
||||
#define XPP_EP_OUT 0x02 /* XPP */
|
||||
#define XPP_EP_IN 0x86 /* XPP */
|
||||
|
||||
/* USB firmware types */
|
||||
#define USB_11xx 0
|
||||
#define USB_FIRMWARE_II 1
|
||||
#define USB_PIC 2
|
||||
|
||||
struct interface_type {
|
||||
int type_code;
|
||||
int num_interfaces;
|
||||
int my_interface_num;
|
||||
int num_endpoints;
|
||||
int my_ep_out;
|
||||
int my_ep_in;
|
||||
char *name;
|
||||
int endpoints[4]; /* for matching */
|
||||
};
|
||||
|
||||
enum eeprom_burn_state {
|
||||
BURN_STATE_NONE = 0,
|
||||
BURN_STATE_STARTED = 1,
|
||||
BURN_STATE_ENDED = 2,
|
||||
BURN_STATE_FAILED = 3,
|
||||
};
|
||||
|
||||
struct astribank_device {
|
||||
struct xusb *xusb;
|
||||
struct xtalk_device *xtalk_dev;
|
||||
usb_dev_handle *handle;
|
||||
int my_interface_num;
|
||||
int my_ep_out;
|
||||
int my_ep_in;
|
||||
char iInterface[BUFSIZ];
|
||||
int is_usb2;
|
||||
enum eeprom_type eeprom_type;
|
||||
enum eeprom_burn_state burn_state;
|
||||
uint8_t status;
|
||||
uint8_t mpp_proto_version;
|
||||
struct eeprom_table *eeprom;
|
||||
struct firmware_versions fw_versions;
|
||||
uint16_t tx_sequenceno;
|
||||
};
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
struct astribank_device *astribank_open(const char devpath[], int iface_num);
|
||||
void astribank_close(struct astribank_device *astribank, int disconnected);
|
||||
void show_astribank_info(const struct astribank_device *astribank);
|
||||
int send_usb(struct astribank_device *astribank, char *buf, int len, int timeout);
|
||||
int recv_usb(struct astribank_device *astribank, char *buf, size_t len, int timeout);
|
||||
int flush_read(struct astribank_device *astribank);
|
||||
int eeprom_fill(struct eeprom_table *eprm,
|
||||
const char *vendor,
|
||||
const char *product,
|
||||
const char *release,
|
||||
const char *label);
|
||||
int astribank_has_twinstar(struct astribank_device *astribank);
|
||||
int label_isvalid(const char *label);
|
||||
|
||||
#define AB_REPORT(report_type, astribank, fmt, ...) \
|
||||
report_type("%s [%s]: " fmt, \
|
||||
xusb_devpath((astribank)->xusb), \
|
||||
xusb_serial((astribank)->xusb), \
|
||||
## __VA_ARGS__)
|
||||
|
||||
#define AB_INFO(astribank, fmt, ...) \
|
||||
AB_REPORT(INFO, astribank, fmt, ## __VA_ARGS__)
|
||||
|
||||
#define AB_ERR(astribank, fmt, ...) \
|
||||
AB_REPORT(ERR, astribank, fmt, ## __VA_ARGS__)
|
||||
|
||||
#endif /* ASTRIBANK_USB_H */
|
|
@ -109,9 +109,15 @@ foreach my $xbus (Dahdi::Xpp::xbuses($sorter)) {
|
|||
system @cmd;
|
||||
warn "Failed '@cmd' (status=$?)\n" if $?;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defined($on) && $on) {
|
||||
if ($opts{'R'} || ! $default_auto_assign) {
|
||||
# wait for UDEV to do its stuff
|
||||
system "dahdi_waitfor_span_assignments assigned";
|
||||
}
|
||||
}
|
||||
foreach my $xbus (Dahdi::Xpp::xbuses($sorter)) {
|
||||
foreach my $xpd (Dahdi::Xpp::Xpd::telephony_devs($xbus->xpds())) {
|
||||
my $spanno = $xpd->xpd_getattr('span');
|
||||
myprintf "\t%-10s: ", $xpd->fqn;
|
||||
|
|
|
@ -28,12 +28,21 @@
|
|||
#include <limits.h>
|
||||
#include <regex.h>
|
||||
#include <sys/time.h>
|
||||
#include "echo_loader.h"
|
||||
#include "debug.h"
|
||||
#include <unistd.h>
|
||||
#include <oct6100api/oct6100_api.h>
|
||||
#include <xtalk/debug.h>
|
||||
#include <xtalk/xusb.h>
|
||||
#include <astribank.h>
|
||||
#include "echo_loader.h"
|
||||
#include "parse_span_specs.h"
|
||||
|
||||
#define DBG_MASK 0x03
|
||||
#ifdef __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
#define DBG_MASK 0x10
|
||||
#define TIMEOUT 1000
|
||||
#define ECHO_MAX_CHANS 128
|
||||
#define ECHO_RIN_STREAM 0
|
||||
|
@ -53,7 +62,7 @@ static float oct_fw_load_timeout = 2.0;
|
|||
struct echo_mod {
|
||||
tPOCT6100_INSTANCE_API pApiInstance;
|
||||
UINT32 ulEchoChanHndl[256];
|
||||
struct astribank_device *astribank;
|
||||
struct astribank *astribank;
|
||||
int maxchans;
|
||||
};
|
||||
|
||||
|
@ -100,9 +109,9 @@ static struct usb_buffer {
|
|||
} usb_buffer;
|
||||
|
||||
|
||||
static void usb_buffer_init(struct astribank_device *astribank, struct usb_buffer *ub)
|
||||
static void usb_buffer_init(struct astribank *astribank, struct usb_buffer *ub)
|
||||
{
|
||||
ub->max_len = xusb_packet_size(astribank->xusb);
|
||||
ub->max_len = xusb_packet_size(xusb_dev_of_astribank(astribank));
|
||||
ub->curr = 0;
|
||||
ub->min_send = INT_MAX;
|
||||
ub->max_send = 0;
|
||||
|
@ -120,7 +129,7 @@ static long usb_buffer_usec(struct usb_buffer *ub)
|
|||
(now.tv_usec - ub->start.tv_usec);
|
||||
}
|
||||
|
||||
static void usb_buffer_showstatistics(struct astribank_device *astribank, struct usb_buffer *ub)
|
||||
static void usb_buffer_showstatistics(struct astribank *astribank, struct usb_buffer *ub)
|
||||
{
|
||||
long usec;
|
||||
|
||||
|
@ -133,7 +142,7 @@ static void usb_buffer_showstatistics(struct astribank_device *astribank, struct
|
|||
usec / 1000, usec / ub->num_sends);
|
||||
}
|
||||
|
||||
static int usb_buffer_flush(struct astribank_device *astribank, struct usb_buffer *ub)
|
||||
static int usb_buffer_flush(struct astribank *astribank, struct usb_buffer *ub)
|
||||
{
|
||||
int ret;
|
||||
long t;
|
||||
|
@ -142,7 +151,7 @@ static int usb_buffer_flush(struct astribank_device *astribank, struct usb_buffe
|
|||
|
||||
if (ub->curr == 0)
|
||||
return 0;
|
||||
ret = xusb_send(astribank->xusb, ub->data, ub->curr, TIMEOUT);
|
||||
ret = astribank_send(astribank, 0, ub->data, ub->curr, TIMEOUT);
|
||||
if (ret < 0) {
|
||||
AB_ERR(astribank, "xusb_send failed: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -175,7 +184,7 @@ static int usb_buffer_flush(struct astribank_device *astribank, struct usb_buffe
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int usb_buffer_append(struct astribank_device *astribank, struct usb_buffer *ub,
|
||||
static int usb_buffer_append(struct astribank *astribank, struct usb_buffer *ub,
|
||||
char *buf, int len)
|
||||
{
|
||||
if (ub->curr + len >= ub->max_len) {
|
||||
|
@ -188,7 +197,7 @@ static int usb_buffer_append(struct astribank_device *astribank, struct usb_buff
|
|||
return len;
|
||||
}
|
||||
|
||||
static int usb_buffer_send(struct astribank_device *astribank, struct usb_buffer *ub,
|
||||
static int usb_buffer_send(struct astribank *astribank, struct usb_buffer *ub,
|
||||
char *buf, int len, int timeout, int recv_answer)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -209,7 +218,7 @@ static int usb_buffer_send(struct astribank_device *astribank, struct usb_buffer
|
|||
ret = usb_buffer_flush(astribank, ub);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = xusb_recv(astribank->xusb, buf, PACKET_SIZE, TIMEOUT);
|
||||
ret = astribank_recv(astribank, 0, buf, PACKET_SIZE, TIMEOUT);
|
||||
if (ret <= 0) {
|
||||
AB_ERR(astribank, "No USB packs to read: %s\n", strerror(-ret));
|
||||
return -EINVAL;
|
||||
|
@ -239,7 +248,7 @@ static int usb_buffer_send(struct astribank_device *astribank, struct usb_buffer
|
|||
return ret;
|
||||
}
|
||||
|
||||
int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver)
|
||||
int spi_send(struct astribank *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver)
|
||||
{
|
||||
int ret;
|
||||
char buf[PACKET_SIZE];
|
||||
|
@ -272,7 +281,7 @@ int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, i
|
|||
return ret;
|
||||
}
|
||||
|
||||
int test_send(struct astribank_device *astribank)
|
||||
int test_send(struct astribank *astribank)
|
||||
{
|
||||
int ret;
|
||||
char buf[PACKET_SIZE];
|
||||
|
@ -300,7 +309,7 @@ int test_send(struct astribank_device *astribank)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int echo_send_data(struct astribank_device *astribank, const unsigned int addr, const unsigned int data)
|
||||
int echo_send_data(struct astribank *astribank, const unsigned int addr, const unsigned int data)
|
||||
{
|
||||
int ret;
|
||||
/* DBG("SEND: %04X -> [%04X]\n", data, addr);
|
||||
|
@ -330,7 +339,7 @@ failed:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int echo_recv_data(struct astribank_device *astribank, const unsigned int addr)
|
||||
int echo_recv_data(struct astribank *astribank, const unsigned int addr)
|
||||
{
|
||||
unsigned int data = 0x00;
|
||||
int ret;
|
||||
|
@ -452,7 +461,7 @@ UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
|
|||
const unsigned int addr = f_pWriteParams->ulWriteAddress;
|
||||
const unsigned int data = f_pWriteParams->usWriteData;
|
||||
const struct echo_mod *echo_mod = (struct echo_mod *)(f_pWriteParams->pProcessContext);
|
||||
struct astribank_device *astribank = echo_mod->astribank;
|
||||
struct astribank *astribank = echo_mod->astribank;
|
||||
int ret;
|
||||
|
||||
ret = echo_send_data(astribank, addr, data);
|
||||
|
@ -469,7 +478,7 @@ UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParam
|
|||
unsigned int data;
|
||||
unsigned int len;
|
||||
const struct echo_mod *echo_mod;
|
||||
struct astribank_device *astribank;
|
||||
struct astribank *astribank;
|
||||
unsigned int i;
|
||||
|
||||
len = f_pSmearParams->ulWriteLength;
|
||||
|
@ -495,7 +504,7 @@ UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParam
|
|||
unsigned int data;
|
||||
unsigned int len = f_pBurstParams->ulWriteLength;
|
||||
const struct echo_mod *echo_mod = (struct echo_mod *)f_pBurstParams->pProcessContext;
|
||||
struct astribank_device *astribank = echo_mod->astribank;
|
||||
struct astribank *astribank = echo_mod->astribank;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
|
@ -516,7 +525,7 @@ UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
|
|||
{
|
||||
const unsigned int addr = f_pReadParams->ulReadAddress;
|
||||
const struct echo_mod *echo_mod;
|
||||
struct astribank_device *astribank;
|
||||
struct astribank *astribank;
|
||||
int ret;
|
||||
|
||||
echo_mod = (struct echo_mod *)f_pReadParams->pProcessContext;
|
||||
|
@ -535,7 +544,7 @@ UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
|
|||
unsigned int addr;
|
||||
unsigned int len;
|
||||
const struct echo_mod *echo_mod;
|
||||
struct astribank_device *astribank;
|
||||
struct astribank *astribank;
|
||||
unsigned int i;
|
||||
|
||||
len = f_pBurstParams->ulReadLength;
|
||||
|
@ -555,13 +564,13 @@ UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
|
|||
return cOCT6100_ERR_OK;
|
||||
}
|
||||
|
||||
inline int get_ver(struct astribank_device *astribank)
|
||||
inline int get_ver(struct astribank *astribank)
|
||||
{
|
||||
return spi_send(astribank, 0, 0, 1, 1);
|
||||
}
|
||||
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
UINT32 init_octasic(char *filename, struct astribank_device *astribank, struct span_specs *span_specs)
|
||||
UINT32 init_octasic(char *filename, struct astribank *astribank, struct span_specs *span_specs)
|
||||
{
|
||||
int cpld_ver;
|
||||
struct echo_mod *echo_mod;
|
||||
|
@ -838,7 +847,7 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, struct s
|
|||
}
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
int load_echo(struct astribank_device *astribank, char *filename, int default_is_alaw, const char *span_spec)
|
||||
int load_echo(struct astribank *astribank, char *filename, int default_is_alaw, const char *span_spec)
|
||||
{
|
||||
int ret;
|
||||
UINT32 octasic_status;
|
||||
|
@ -868,7 +877,7 @@ int load_echo(struct astribank_device *astribank, char *filename, int default_is
|
|||
return 0;
|
||||
}
|
||||
|
||||
int echo_ver(struct astribank_device *astribank)
|
||||
int echo_ver(struct astribank *astribank)
|
||||
{
|
||||
usb_buffer_init(astribank, &usb_buffer);
|
||||
return get_ver(astribank);
|
||||
|
|
|
@ -23,10 +23,10 @@
|
|||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "astribank_usb.h"
|
||||
#include "astribank.h"
|
||||
|
||||
int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver);
|
||||
int load_echo(struct astribank_device *astribank, char *filename, int is_alaw, const char *span_spec);
|
||||
int echo_ver(struct astribank_device *astribank);
|
||||
int spi_send(struct astribank *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver);
|
||||
int load_echo(struct astribank *astribank, char *filename, int is_alaw, const char *span_spec);
|
||||
int echo_ver(struct astribank *astribank);
|
||||
|
||||
#endif /* ECHO_LOADER_H */
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
#include <ctype.h>
|
||||
#include "hexfile.h"
|
||||
|
||||
static const char rcsid[] = "$Id$";
|
||||
|
||||
static parse_hexfile_report_func_t report_func = NULL;
|
||||
|
||||
parse_hexfile_report_func_t parse_hexfile_set_reporting(parse_hexfile_report_func_t rf)
|
||||
|
|
|
@ -72,7 +72,11 @@ struct hexdata {
|
|||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef void (*parse_hexfile_report_func_t)(int level, const char *msg, ...);
|
||||
typedef void (*parse_hexfile_report_func_t)(int level, const char *msg, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf,2,3)));
|
||||
#endif
|
||||
;
|
||||
|
||||
parse_hexfile_report_func_t parse_hexfile_set_reporting(parse_hexfile_report_func_t rf);
|
||||
void free_hexdata(struct hexdata *hexdata);
|
||||
|
|
202
xpp/mpp.h
202
xpp/mpp.h
|
@ -1,202 +0,0 @@
|
|||
#ifndef MPP_H
|
||||
#define MPP_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2008, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* MPP - Managment Processor Protocol definitions
|
||||
*/
|
||||
|
||||
#include <mpptalk_defs.h>
|
||||
#include <stdint.h>
|
||||
#include <xtalk.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#error "We do not know how your compiler packs structures"
|
||||
#endif
|
||||
|
||||
#define MK_PROTO_VERSION(major, minor) (((major) << 4) | (0x0F & (minor)))
|
||||
|
||||
#define MPP_PROTOCOL_VERSION MK_PROTO_VERSION(1,4)
|
||||
#define MPP_SUPPORTED_VERSION(x) ((x) == MK_PROTO_VERSION(1,3) || (x) == MK_PROTO_VERSION(1,4))
|
||||
|
||||
/*
|
||||
* The eeprom_table is common to all eeprom types.
|
||||
*/
|
||||
#define LABEL_SIZE 8
|
||||
struct eeprom_table {
|
||||
uint8_t source; /* C0 - small eeprom, C2 - large eeprom */
|
||||
uint16_t vendor;
|
||||
uint16_t product;
|
||||
uint16_t release; /* BCD encoded release */
|
||||
uint8_t config_byte; /* Must be 0 */
|
||||
uint8_t label[LABEL_SIZE];
|
||||
} PACKED;
|
||||
|
||||
#define VERSION_LEN 6
|
||||
struct firmware_versions {
|
||||
char usb[VERSION_LEN];
|
||||
char fpga[VERSION_LEN];
|
||||
char eeprom[VERSION_LEN];
|
||||
} PACKED;
|
||||
|
||||
struct capabilities {
|
||||
uint8_t ports_fxs;
|
||||
uint8_t ports_fxo;
|
||||
uint8_t ports_bri;
|
||||
uint8_t ports_pri;
|
||||
uint8_t extra_features; /* BIT(0) - TwinStar */
|
||||
uint8_t ports_echo;
|
||||
uint8_t reserved[2];
|
||||
uint32_t timestamp;
|
||||
} PACKED;
|
||||
|
||||
#define CAP_EXTRA_TWINSTAR(c) ((c)->extra_features & 0x01)
|
||||
#define CAP_EXTRA_TWINSTAR_SET(c) do {(c)->extra_features |= 0x01;} while (0)
|
||||
#define CAP_EXTRA_TWINSTAR_CLR(c) do {(c)->extra_features &= ~0x01;} while (0)
|
||||
|
||||
#define KEYSIZE 16
|
||||
|
||||
struct capkey {
|
||||
uint8_t k[KEYSIZE];
|
||||
} PACKED;
|
||||
|
||||
struct extrainfo {
|
||||
char text[EXTRAINFO_SIZE];
|
||||
} PACKED;
|
||||
|
||||
struct mpp_header {
|
||||
uint16_t len;
|
||||
uint16_t seq;
|
||||
uint8_t op; /* MSB: 0 - to device, 1 - from device */
|
||||
} PACKED;
|
||||
|
||||
enum mpp_ser_op {
|
||||
SER_CARD_INFO_GET = 0x1,
|
||||
SER_STAT_GET = 0x3,
|
||||
/* Status bits */
|
||||
#define SER_STAT_WATCHDOG_READY(s) ((s) & 0x01)
|
||||
#define SER_STAT_XPD_ALIVE(s) ((s) & 0x02)
|
||||
};
|
||||
|
||||
/* Individual commands structure */
|
||||
|
||||
CMD_DEF(MPP, STATUS_GET);
|
||||
|
||||
|
||||
CMD_DEF(MPP, STATUS_GET_REPLY,
|
||||
uint8_t i2cs_data;
|
||||
|
||||
#define STATUS_FPGA_LOADED(x) ((x) & 0x01)
|
||||
uint8_t status; /* BIT(0) - FPGA is loaded */
|
||||
struct firmware_versions fw_versions;
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, EEPROM_SET,
|
||||
struct eeprom_table data;
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, CAPS_GET);
|
||||
|
||||
CMD_DEF(MPP, CAPS_GET_REPLY,
|
||||
struct eeprom_table data;
|
||||
struct capabilities capabilities;
|
||||
struct capkey key;
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, CAPS_SET,
|
||||
struct eeprom_table data;
|
||||
struct capabilities capabilities;
|
||||
struct capkey key;
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, EXTRAINFO_GET);
|
||||
|
||||
CMD_DEF(MPP, EXTRAINFO_GET_REPLY,
|
||||
struct extrainfo info;
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, EXTRAINFO_SET,
|
||||
struct extrainfo info;
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, RENUM);
|
||||
|
||||
CMD_DEF(MPP, EEPROM_BLK_RD,
|
||||
uint16_t offset;
|
||||
uint16_t len;
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, EEPROM_BLK_RD_REPLY,
|
||||
uint16_t offset;
|
||||
uint8_t data[0];
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, DEV_SEND_START,
|
||||
uint8_t dest;
|
||||
char ihex_version[VERSION_LEN];
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, DEV_SEND_END);
|
||||
|
||||
CMD_DEF(MPP, DEV_SEND_SEG,
|
||||
uint16_t offset;
|
||||
uint8_t data[0];
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, RESET);
|
||||
CMD_DEF(MPP, HALF_RESET);
|
||||
|
||||
CMD_DEF(MPP, SER_SEND,
|
||||
uint8_t data[0];
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, SER_RECV,
|
||||
uint8_t data[0];
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, TWS_WD_MODE_SET,
|
||||
uint8_t wd_active;
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, TWS_WD_MODE_GET);
|
||||
CMD_DEF(MPP, TWS_WD_MODE_GET_REPLY,
|
||||
uint8_t wd_active;
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, TWS_PORT_SET,
|
||||
uint8_t portnum;
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, TWS_PORT_GET);
|
||||
CMD_DEF(MPP, TWS_PORT_GET_REPLY,
|
||||
uint8_t portnum;
|
||||
);
|
||||
|
||||
CMD_DEF(MPP, TWS_PWR_GET);
|
||||
CMD_DEF(MPP, TWS_PWR_GET_REPLY,
|
||||
uint8_t power;
|
||||
);
|
||||
|
||||
#endif /* MPP_H */
|
771
xpp/mpptalk.c
771
xpp/mpptalk.c
File diff suppressed because it is too large
Load Diff
194
xpp/mpptalk.h
194
xpp/mpptalk.h
|
@ -1,5 +1,5 @@
|
|||
#ifndef MPP_FUNCS_H
|
||||
#define MPP_FUNCS_H
|
||||
#ifndef MPPTALK_H
|
||||
#define MPPTALK_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2008, Xorcom
|
||||
|
@ -22,64 +22,152 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mpp.h"
|
||||
#include "astribank_usb.h"
|
||||
|
||||
struct astribank_device;
|
||||
struct eeprom_table;
|
||||
struct extrainfo;
|
||||
struct capabilities;
|
||||
struct capkey;
|
||||
|
||||
#define TIMEOUT 6000
|
||||
|
||||
/* high-level */
|
||||
struct astribank_device *mpp_init(const char devpath[], int iface_num);
|
||||
void mpp_exit(struct astribank_device *astribank);
|
||||
int mpp_proto_query(struct astribank_device *astribank);
|
||||
int mpp_status_query(struct astribank_device *astribank);
|
||||
int mpp_eeprom_set(struct astribank_device *astribank, const struct eeprom_table *et);
|
||||
int mpp_renumerate(struct astribank_device *astribank);
|
||||
int mpp_caps_get(struct astribank_device *astribank,
|
||||
struct eeprom_table *et,
|
||||
struct capabilities *cap,
|
||||
struct capkey *key);
|
||||
int mpp_caps_set(struct astribank_device *astribank,
|
||||
const struct eeprom_table *eeprom_table,
|
||||
const struct capabilities *capabilities,
|
||||
const struct capkey *key);
|
||||
int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info);
|
||||
int mpp_extrainfo_set(struct astribank_device *astribank, const struct extrainfo *info);
|
||||
int mpp_eeprom_blk_rd(struct astribank_device *astribank, uint8_t *buf, uint16_t offset, uint16_t len);
|
||||
int mpp_send_start(struct astribank_device *astribank, int dest, const char *ihex_version);
|
||||
int mpp_send_end(struct astribank_device *astribank);
|
||||
int mpp_send_seg(struct astribank_device *astribank, const uint8_t *data, uint16_t offset, uint16_t len);
|
||||
int mpp_reset(struct astribank_device *astribank, int full_reset);
|
||||
int mpp_serial_cmd(struct astribank_device *astribank, const uint8_t *in, uint8_t *out, uint16_t len);
|
||||
void show_eeprom(const struct eeprom_table *eprm, FILE *fp);
|
||||
void show_capabilities(const struct capabilities *capabilities, FILE *fp);
|
||||
void show_astribank_status(struct astribank_device *astribank, FILE *fp);
|
||||
void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp);
|
||||
int twinstar_show(struct astribank_device *astribank, FILE *fp);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Serial commands to FPGA
|
||||
* MPPTALK - Example XTALK dialect
|
||||
*/
|
||||
int mpps_card_info(struct astribank_device *astribank, int unit, uint8_t *card_type, uint8_t *card_status);
|
||||
int mpps_stat(struct astribank_device *astribank, int unit, uint8_t *maincard_version, uint8_t *status);
|
||||
|
||||
#include <xtalk/proto.h>
|
||||
#include <xtalk/proto_sync.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
/*---------------- Common types --------------------*/
|
||||
|
||||
/*
|
||||
* The eeprom_table is common to all eeprom types.
|
||||
*/
|
||||
#define LABEL_SIZE 8
|
||||
struct eeprom_table {
|
||||
uint8_t source; /* C0 - small eeprom, C2 - large eeprom */
|
||||
uint16_t vendor;
|
||||
uint16_t product;
|
||||
uint16_t release; /* BCD encoded release */
|
||||
uint8_t config_byte; /* Must be 0 */
|
||||
uint8_t label[LABEL_SIZE];
|
||||
} PACKED;
|
||||
|
||||
#define VERSION_LEN 6
|
||||
struct firmware_versions {
|
||||
char usb[VERSION_LEN];
|
||||
char fpga[VERSION_LEN];
|
||||
char eeprom[VERSION_LEN];
|
||||
} PACKED;
|
||||
|
||||
struct capabilities {
|
||||
uint8_t ports_fxs;
|
||||
uint8_t ports_fxo;
|
||||
uint8_t ports_bri;
|
||||
uint8_t ports_pri;
|
||||
uint8_t extra_features; /* BIT(0) - TwinStar */
|
||||
uint8_t ports_echo;
|
||||
uint8_t reserved[2];
|
||||
uint32_t timestamp;
|
||||
} PACKED;
|
||||
|
||||
#define CAP_EXTRA_TWINSTAR(c) ((c)->extra_features & 0x01)
|
||||
#define CAP_EXTRA_TWINSTAR_SET(c) do {(c)->extra_features |= 0x01;} while (0)
|
||||
#define CAP_EXTRA_TWINSTAR_CLR(c) do {(c)->extra_features &= ~0x01;} while (0)
|
||||
|
||||
#define KEYSIZE 16
|
||||
struct capkey {
|
||||
uint8_t k[KEYSIZE];
|
||||
} PACKED;
|
||||
|
||||
#define EXTRAINFO_SIZE 24
|
||||
struct extrainfo {
|
||||
char text[EXTRAINFO_SIZE];
|
||||
} PACKED;
|
||||
|
||||
struct mpp_header {
|
||||
uint16_t len;
|
||||
uint16_t seq;
|
||||
uint8_t op; /* MSB: 0 - to device, 1 - from device */
|
||||
} PACKED;
|
||||
|
||||
enum mpp_ser_op {
|
||||
SER_CARD_INFO_GET = 0x1,
|
||||
SER_STAT_GET = 0x3,
|
||||
/* Status bits */
|
||||
#define SER_STAT_WATCHDOG_READY(s) ((s) & 0x01)
|
||||
#define SER_STAT_XPD_ALIVE(s) ((s) & 0x02)
|
||||
};
|
||||
|
||||
/* EEPROM_QUERY: i2cs(ID1, ID0) */
|
||||
enum eeprom_type {
|
||||
EEPROM_TYPE_NONE = 0,
|
||||
EEPROM_TYPE_SMALL = 1,
|
||||
EEPROM_TYPE_LARGE = 2,
|
||||
EEPROM_TYPE_UNUSED = 3,
|
||||
};
|
||||
|
||||
enum dev_dest {
|
||||
DEST_NONE = 0x00,
|
||||
DEST_FPGA = 0x01,
|
||||
DEST_EEPROM = 0x02,
|
||||
};
|
||||
|
||||
|
||||
/*---------------- PROTOCOL ------------------------*/
|
||||
/* API */
|
||||
struct mpp_device;
|
||||
|
||||
struct mpp_device *mpp_new(struct xusb_iface *iface);
|
||||
void mpp_delete(struct mpp_device *dev);
|
||||
struct xusb_iface *xubs_iface_of_mpp(struct mpp_device *mpp);
|
||||
int mpp_status_query(struct mpp_device *mpp_dev);
|
||||
|
||||
enum eeprom_type mpp_eeprom_type(struct mpp_device *mpp_dev);
|
||||
|
||||
void show_eeprom(const struct eeprom_table *eprm, FILE *fp);
|
||||
void show_capabilities(const struct capabilities *capabilities, FILE *fp);
|
||||
void show_astribank_status(struct mpp_device *mpp_dev, FILE *fp);
|
||||
void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp);
|
||||
int twinstar_show(struct mpp_device *mpp, FILE *fp);
|
||||
int show_hardware(struct mpp_device *mpp_dev);
|
||||
|
||||
int mpp_renumerate(struct mpp_device *mpp_dev);
|
||||
int mpp_send_start(struct mpp_device *mpp_dev, int dest, const char *ihex_version);
|
||||
int mpp_send_end(struct mpp_device *mpp_dev);
|
||||
int mpp_send_seg(struct mpp_device *mpp_dev, const uint8_t *data, uint16_t offset, uint16_t len);
|
||||
int mpp_reset(struct mpp_device *mpp_dev, int full_reset);
|
||||
|
||||
int mpp_caps_get(struct mpp_device *mpp_dev,
|
||||
struct eeprom_table *eeprom_table,
|
||||
struct capabilities *capabilities,
|
||||
struct capkey *key);
|
||||
int mpp_caps_set(struct mpp_device *mpp_dev,
|
||||
const struct eeprom_table *eeprom_table,
|
||||
const struct capabilities *capabilities,
|
||||
const struct capkey *key);
|
||||
|
||||
/*
|
||||
* serial sub-protocol to FPGA
|
||||
*/
|
||||
int mpps_card_info(struct mpp_device *mpp, int unit, uint8_t *card_type, uint8_t *card_status);
|
||||
int mpps_stat(struct mpp_device *mpp, int unit, uint8_t *maincard_version, uint8_t *status);
|
||||
|
||||
/*
|
||||
* Twinstar
|
||||
*/
|
||||
int mpp_tws_watchdog(struct astribank_device *astribank);
|
||||
int mpp_tws_setwatchdog(struct astribank_device *astribank, int yes);
|
||||
int mpp_tws_powerstate(struct astribank_device *astribank);
|
||||
int mpp_tws_portnum(struct astribank_device *astribank);
|
||||
int mpp_tws_setportnum(struct astribank_device *astribank, uint8_t portnum);
|
||||
int mpp_tws_watchdog(struct mpp_device *mpp);
|
||||
int mpp_tws_setwatchdog(struct mpp_device *mpp, int yes);
|
||||
int mpp_tws_powerstate(struct mpp_device *mpp);
|
||||
int mpp_tws_portnum(struct mpp_device *mpp);
|
||||
int mpp_tws_setportnum(struct mpp_device *mpp, uint8_t portnum);
|
||||
|
||||
const char *dev_dest2str(int dest);
|
||||
|
||||
#endif /* MPP_FUNCS_H */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* MPPTALK_H */
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
#ifndef MPPTALK_DEFS_H
|
||||
#define MPPTALK_DEFS_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2008,2009,2010 Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xtalk_defs.h>
|
||||
/*
|
||||
* MPP - Managment Processor Protocol definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* OP Codes:
|
||||
* MSB of op signifies a reply from device
|
||||
*/
|
||||
#define MPP_RENUM 0x0B /* Trigger USB renumeration */
|
||||
#define MPP_EEPROM_SET 0x0D
|
||||
|
||||
/* AB capabilities */
|
||||
#define MPP_CAPS_GET 0x0E
|
||||
#define MPP_CAPS_GET_REPLY 0x8E
|
||||
#define MPP_CAPS_SET 0x0F
|
||||
|
||||
#define MPP_DEV_SEND_START 0x05
|
||||
#define MPP_DEV_SEND_SEG 0x07
|
||||
#define MPP_DEV_SEND_END 0x09
|
||||
|
||||
/* Astribank Status */
|
||||
#define MPP_STATUS_GET 0x11
|
||||
#define MPP_STATUS_GET_REPLY 0x91
|
||||
#define MPP_STATUS_GET_REPLY_V13 0x91 /* backward compat */
|
||||
|
||||
/* Get extra vendor information */
|
||||
#define MPP_EXTRAINFO_GET 0x13
|
||||
#define MPP_EXTRAINFO_GET_REPLY 0x93
|
||||
#define MPP_EXTRAINFO_SET 0x15 /* Set extra vendor information */
|
||||
|
||||
#define MPP_EEPROM_BLK_RD 0x27
|
||||
#define MPP_EEPROM_BLK_RD_REPLY 0xA7
|
||||
|
||||
#define MPP_SER_SEND 0x37
|
||||
#define MPP_SER_RECV 0xB7
|
||||
|
||||
#define MPP_RESET 0x45 /* Reset both FPGA and USB firmwares */
|
||||
#define MPP_HALF_RESET 0x47 /* Reset only FPGA firmware */
|
||||
|
||||
/* Twinstar */
|
||||
#define MPP_TWS_WD_MODE_SET 0x31 /* Set watchdog off/on guard */
|
||||
#define MPP_TWS_WD_MODE_GET 0x32 /* Current watchdog mode */
|
||||
#define MPP_TWS_WD_MODE_GET_REPLY 0xB2 /* Current watchdog mode */
|
||||
#define MPP_TWS_PORT_SET 0x34 /* USB-[0/1] */
|
||||
#define MPP_TWS_PORT_GET 0x35 /* USB-[0/1] */
|
||||
#define MPP_TWS_PORT_GET_REPLY 0xB5 /* USB-[0/1] */
|
||||
#define MPP_TWS_PWR_GET 0x36 /* Power: bits -> USB ports */
|
||||
#define MPP_TWS_PWR_GET_REPLY 0xB6 /* Power: bits -> USB ports */
|
||||
|
||||
/*
|
||||
* Statuses
|
||||
*/
|
||||
#define STAT_OK 0x00 /* acknowledges previous command */
|
||||
#define STAT_FAIL 0x01 /* Last command failed */
|
||||
#define STAT_RESET_FAIL 0x02 /* reset failed */
|
||||
#define STAT_NODEST 0x03 /* No destination is selected */
|
||||
#define STAT_MISMATCH 0x04 /* Data mismatch */
|
||||
#define STAT_NOACCESS 0x05 /* No access */
|
||||
#define STAT_BAD_CMD 0x06 /* Bad command */
|
||||
#define STAT_TOO_SHORT 0x07 /* Packet is too short */
|
||||
#define STAT_ERROFFS 0x08 /* Offset error */
|
||||
#define STAT_NOCODE 0x09 /* Source was not burned before */
|
||||
#define STAT_NO_LEEPROM 0x0A /* Large EEPROM was not found */
|
||||
#define STAT_NO_EEPROM 0x0B /* No EEPROM was found */
|
||||
#define STAT_WRITE_FAIL 0x0C /* Writing to device failed */
|
||||
#define STAT_FPGA_ERR 0x0D /* FPGA error */
|
||||
#define STAT_KEY_ERR 0x0E /* Bad Capabilities Key */
|
||||
#define STAT_NOCAPS_ERR 0x0F /* No matching capability */
|
||||
#define STAT_NOPWR_ERR 0x10 /* No power on USB connector */
|
||||
#define STAT_CAPS_FPGA_ERR 0x11 /* Setting of the capabilities while FPGA is loaded */
|
||||
|
||||
/* EEPROM_QUERY: i2cs(ID1, ID0) */
|
||||
enum eeprom_type {
|
||||
EEPROM_TYPE_NONE = 0,
|
||||
EEPROM_TYPE_SMALL = 1,
|
||||
EEPROM_TYPE_LARGE = 2,
|
||||
EEPROM_TYPE_UNUSED = 3,
|
||||
};
|
||||
|
||||
enum dev_dest {
|
||||
DEST_NONE = 0x00,
|
||||
DEST_FPGA = 0x01,
|
||||
DEST_EEPROM = 0x02,
|
||||
};
|
||||
|
||||
#define EXTRAINFO_SIZE 24
|
||||
|
||||
#endif /* MPPTALK_DEFS_H */
|
|
@ -1,38 +0,0 @@
|
|||
CFLAGS=-V3.4 -ffunction-sections -I/lib/modules/$(shell uname -r)/build/include -Iinclude -Ioctdeviceapi -Ioctdeviceapi/oct6100api -DGFP_ATOMIC=0 -Dkmalloc=calloc -Dkfree=free
|
||||
LDFLAGS=-V3.4 -Wl,-Map -Wl,test.map -Wl,--gc-sections
|
||||
|
||||
APIDIR=octdeviceapi/oct6100api/oct6100_api
|
||||
|
||||
OCTASIC_OBJS=$(APIDIR)/oct6100_adpcm_chan.o \
|
||||
$(APIDIR)/oct6100_channel.o \
|
||||
$(APIDIR)/oct6100_chip_open.o \
|
||||
$(APIDIR)/oct6100_chip_stats.o \
|
||||
$(APIDIR)/oct6100_conf_bridge.o \
|
||||
$(APIDIR)/oct6100_debug.o \
|
||||
$(APIDIR)/oct6100_events.o \
|
||||
$(APIDIR)/oct6100_interrupts.o \
|
||||
$(APIDIR)/oct6100_memory.o \
|
||||
$(APIDIR)/oct6100_miscellaneous.o \
|
||||
$(APIDIR)/oct6100_mixer.o \
|
||||
$(APIDIR)/oct6100_phasing_tsst.o \
|
||||
$(APIDIR)/oct6100_playout_buf.o \
|
||||
$(APIDIR)/oct6100_remote_debug.o \
|
||||
$(APIDIR)/oct6100_tlv.o \
|
||||
$(APIDIR)/oct6100_tone_detection.o \
|
||||
$(APIDIR)/oct6100_tsi_cnct.o \
|
||||
$(APIDIR)/oct6100_tsst.o \
|
||||
$(APIDIR)/oct6100_user.o \
|
||||
apilib/bt/octapi_bt0.o \
|
||||
apilib/largmath/octapi_largmath.o \
|
||||
apilib/llman/octapi_llman.o
|
||||
|
||||
|
||||
all: test
|
||||
|
||||
test.o: test.c
|
||||
|
||||
test: test.o $(OCTASIC_OBJS)
|
||||
|
||||
clean:
|
||||
rm -rf test test.o
|
||||
rm -rf $(OCTASIC_OBJS)
|
|
@ -0,0 +1,119 @@
|
|||
GLOBAL_CFLAGS = -Wall -Werror
|
||||
|
||||
OCTASIC_DEFINES = \
|
||||
-DPTR_TYPE=uint32_t \
|
||||
-DcOCT6100_INTERNAL_SUPER_ARRAY_SIZE=1024 \
|
||||
-DcOCT6100_MAX_ECHO_CHANNELS=672 \
|
||||
-DcOCT6100_MAX_MIXER_EVENTS=1344
|
||||
|
||||
noinst_LTLIBRARIES = liboctasic.la
|
||||
|
||||
# Taken from octasic-helper
|
||||
liboctasic_la_SOURCES = \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_events.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_memory.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.c \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.c \
|
||||
apilib/bt/octapi_bt0.c \
|
||||
apilib/largmath/octapi_largmath.c \
|
||||
apilib/llman/octapi_llman.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
apilib/bt/octapi_bt0_private.h \
|
||||
apilib/llman/octapi_llman_private.h \
|
||||
include/apilib/octapi_bt0.h \
|
||||
include/apilib/octapi_largmath.h \
|
||||
include/apilib/octapi_llman.h \
|
||||
include/digium_unused.h \
|
||||
include/oct6100api/oct6100_adpcm_chan_inst.h \
|
||||
include/oct6100api/oct6100_adpcm_chan_pub.h \
|
||||
include/oct6100api/oct6100_api.h \
|
||||
include/oct6100api/oct6100_api_inst.h \
|
||||
include/oct6100api/oct6100_apimi.h \
|
||||
include/oct6100api/oct6100_apiud.h \
|
||||
include/oct6100api/oct6100_channel_inst.h \
|
||||
include/oct6100api/oct6100_channel_pub.h \
|
||||
include/oct6100api/oct6100_chip_open_inst.h \
|
||||
include/oct6100api/oct6100_chip_open_pub.h \
|
||||
include/oct6100api/oct6100_chip_stats_inst.h \
|
||||
include/oct6100api/oct6100_chip_stats_pub.h \
|
||||
include/oct6100api/oct6100_conf_bridge_inst.h \
|
||||
include/oct6100api/oct6100_conf_bridge_pub.h \
|
||||
include/oct6100api/oct6100_debug_inst.h \
|
||||
include/oct6100api/oct6100_debug_pub.h \
|
||||
include/oct6100api/oct6100_defines.h \
|
||||
include/oct6100api/oct6100_errors.h \
|
||||
include/oct6100api/oct6100_events_inst.h \
|
||||
include/oct6100api/oct6100_events_pub.h \
|
||||
include/oct6100api/oct6100_interrupts_inst.h \
|
||||
include/oct6100api/oct6100_interrupts_pub.h \
|
||||
include/oct6100api/oct6100_mixer_inst.h \
|
||||
include/oct6100api/oct6100_mixer_pub.h \
|
||||
include/oct6100api/oct6100_phasing_tsst_inst.h \
|
||||
include/oct6100api/oct6100_phasing_tsst_pub.h \
|
||||
include/oct6100api/oct6100_playout_buf_inst.h \
|
||||
include/oct6100api/oct6100_playout_buf_pub.h \
|
||||
include/oct6100api/oct6100_remote_debug_inst.h \
|
||||
include/oct6100api/oct6100_remote_debug_pub.h \
|
||||
include/oct6100api/oct6100_tlv_inst.h \
|
||||
include/oct6100api/oct6100_tone_detection_inst.h \
|
||||
include/oct6100api/oct6100_tone_detection_pub.h \
|
||||
include/oct6100api/oct6100_tsi_cnct_inst.h \
|
||||
include/oct6100api/oct6100_tsi_cnct_pub.h \
|
||||
include/oct6100api/oct6100_tsst_inst.h \
|
||||
include/octdef.h \
|
||||
include/octmac.h \
|
||||
include/octosdependant.h \
|
||||
include/octrpc/oct6100_rpc_protocol.h \
|
||||
include/octrpc/rpc_protocol.h \
|
||||
include/octtype.h \
|
||||
include/octtypevx.h \
|
||||
include/octtypewin.h \
|
||||
#
|
||||
|
||||
liboctasic_la_CFLAGS = \
|
||||
$(GLOBAL_CFLAGS) \
|
||||
$(OCTASIC_DEFINES) \
|
||||
$(OCTASIC_CFLAGS)
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
get_discards \
|
||||
octasic-helper \
|
||||
octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_api/oct6100_user.c \
|
||||
octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.c \
|
||||
octdeviceapi/oct6100api/oct6100_channel_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_chip_open_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_chip_stats_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_conf_bridge_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_debug_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_events_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_interrupts_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_memory_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_miscellaneous_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_mixer_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_phasing_tsst_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_playout_buf_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_remote_debug_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_tlv_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_tone_detection_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_tsi_cnct_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_tsst_priv.h \
|
||||
octdeviceapi/oct6100api/oct6100_version.h \
|
||||
test.c \
|
||||
#
|
|
@ -109,6 +109,10 @@ my %pci_ids = (
|
|||
|
||||
# from wcb4xxp
|
||||
'd161:b410' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Digium Wildcard B410P' },
|
||||
'd161:8014' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Digium Wildcard B433' },
|
||||
'd161:8015' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Digium Wildcard B434' },
|
||||
'd161:8016' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Digium Wildcard B233' },
|
||||
'd161:8017' => { DRIVER => 'wcb4xxp', DESCRIPTION => 'Digium Wildcard B234' },
|
||||
|
||||
# from tor2
|
||||
'10b5:9030' => { DRIVER => 'tor2', DESCRIPTION => 'PLX 9030' },
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
perllibdir = @perllibdir@
|
||||
nobase_perllib_DATA = \
|
||||
Dahdi.pm \
|
||||
Dahdi/Hardware.pm \
|
||||
Dahdi/Xpp/Line.pm \
|
||||
Dahdi/Xpp/Xbus.pm \
|
||||
Dahdi/Xpp/Xpd.pm \
|
||||
Dahdi/Xpp/Mpp.pm \
|
||||
Dahdi/Span.pm \
|
||||
Dahdi/Utils.pm \
|
||||
Dahdi/Chans.pm \
|
||||
Dahdi/Xpp.pm \
|
||||
Dahdi/Config/Params.pm \
|
||||
Dahdi/Config/Gen/Xpporder.pm \
|
||||
Dahdi/Config/Gen/Spantypes.pm \
|
||||
Dahdi/Config/Gen/Modules.pm \
|
||||
Dahdi/Config/Gen/Users.pm \
|
||||
Dahdi/Config/Gen/Freepbxdb.pm \
|
||||
Dahdi/Config/Gen/Unicall.pm \
|
||||
Dahdi/Config/Gen/Chandahdi.pm \
|
||||
Dahdi/Config/Gen/Assignedspans.pm \
|
||||
Dahdi/Config/Gen/System.pm \
|
||||
Dahdi/Config/Gen.pm \
|
||||
Dahdi/Hardware/USB.pm \
|
||||
Dahdi/Hardware/PCI.pm
|
||||
|
||||
EXTRA_DIST = $(nobase_perllib_DATA)
|
|
@ -25,12 +25,12 @@
|
|||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
#include <xtalk/debug.h>
|
||||
#include <xtalk/xusb.h>
|
||||
#include "hexfile.h"
|
||||
#include "pic_loader.h"
|
||||
#include <debug.h>
|
||||
#include <xusb.h>
|
||||
|
||||
#define DBG_MASK 0x03
|
||||
#define DBG_MASK 0x20
|
||||
#define MAX_HEX_LINES 10000
|
||||
#define TIMEOUT 500
|
||||
|
||||
|
@ -57,7 +57,7 @@ struct xpp_packet_header {
|
|||
} d;
|
||||
} PACKED;
|
||||
|
||||
int send_picline(struct astribank_device *astribank, uint8_t card_type, enum pic_command pcmd, int offs, uint8_t *data, int data_len)
|
||||
int send_picline(struct astribank *ab, uint8_t card_type, enum pic_command pcmd, int offs, uint8_t *data, int data_len)
|
||||
{
|
||||
int recv_answer = 0;
|
||||
char buf[PACKET_SIZE];
|
||||
|
@ -65,7 +65,7 @@ int send_picline(struct astribank_device *astribank, uint8_t card_type, enum pic
|
|||
int pack_len;
|
||||
int ret;
|
||||
|
||||
assert(astribank != NULL);
|
||||
assert(ab != NULL);
|
||||
pack_len = data_len + sizeof(phead->header) + sizeof(phead->d.pic_packet.pic_header);
|
||||
phead->header.len = pack_len;
|
||||
phead->header.op = PIC_REQ_XOP;
|
||||
|
@ -90,14 +90,14 @@ int send_picline(struct astribank_device *astribank, uint8_t card_type, enum pic
|
|||
DBG("PICLINE: pack_len=%d pcmd=%d\n", pack_len, pcmd);
|
||||
dump_packet(LOG_DEBUG, DBG_MASK, "dump:picline[W]", (char *)phead, pack_len);
|
||||
|
||||
ret = xusb_send(astribank->xusb, buf, pack_len, TIMEOUT);
|
||||
ret = astribank_send(ab, 0, buf, pack_len, TIMEOUT);
|
||||
if(ret < 0) {
|
||||
ERR("xusb_send failed: %d\n", ret);
|
||||
ERR("astribank_send failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
DBG("xusb_send: Written %d bytes\n", ret);
|
||||
DBG("astribank_send: Written %d bytes\n", ret);
|
||||
if (recv_answer) {
|
||||
ret = xusb_recv(astribank->xusb, buf, sizeof(buf), TIMEOUT);
|
||||
ret = astribank_recv(ab, 0, buf, sizeof(buf), TIMEOUT);
|
||||
if(ret <= 0) {
|
||||
ERR("No USB packs to read\n");
|
||||
return ret;
|
||||
|
@ -172,7 +172,7 @@ static const char *pic_basename(const char *fname, uint8_t *card_type)
|
|||
/*
|
||||
* Returns: true on success, false on failure
|
||||
*/
|
||||
static int pic_burn(struct astribank_device *astribank, const struct hexdata *hexdata)
|
||||
static int pic_burn(struct astribank *ab, const struct hexdata *hexdata)
|
||||
{
|
||||
const char *v = hexdata->version_info;
|
||||
const char *basename;
|
||||
|
@ -182,18 +182,21 @@ static int pic_burn(struct astribank_device *astribank, const struct hexdata *he
|
|||
int ret;
|
||||
unsigned int i;
|
||||
const char *devstr;
|
||||
const struct xusb_device *xusb;
|
||||
|
||||
v = (v[0]) ? v : "Unknown";
|
||||
assert(astribank != NULL);
|
||||
assert(ab != NULL);
|
||||
assert(hexdata != NULL);
|
||||
devstr = xusb_devpath(astribank->xusb);
|
||||
if(!astribank->is_usb2) {
|
||||
xusb = xusb_dev_of_astribank(ab);
|
||||
devstr = xusb_devpath(xusb);
|
||||
i = xusb_packet_size(xusb);
|
||||
if(i != 512) {
|
||||
ERR("%s: Skip PIC burning (not USB2)\n", devstr);
|
||||
return 0;
|
||||
}
|
||||
INFO("%s [%s]: Loading PIC Firmware: %s (version %s)\n",
|
||||
devstr,
|
||||
xusb_serial(astribank->xusb),
|
||||
xusb_serial(xusb),
|
||||
hexdata->fname,
|
||||
hexdata->version_info);
|
||||
basename = pic_basename(hexdata->fname, &card_type);
|
||||
|
@ -209,10 +212,10 @@ static int pic_burn(struct astribank_device *astribank, const struct hexdata *he
|
|||
for(i = 2; i; i--) {
|
||||
char buf[PACKET_SIZE];
|
||||
|
||||
if(xusb_recv(astribank->xusb, buf, sizeof(buf), 1) <= 0)
|
||||
if (astribank_recv(ab, 0, buf, sizeof(buf), TIMEOUT) <= 0)
|
||||
break;
|
||||
}
|
||||
if((ret = send_picline(astribank, card_type, PIC_START_FLAG, 0, NULL, 0)) != 0) {
|
||||
if((ret = send_picline(ab, card_type, PIC_START_FLAG, 0, NULL, 0)) != 0) {
|
||||
perror("Failed sending start hexline");
|
||||
return 0;
|
||||
}
|
||||
|
@ -233,7 +236,7 @@ static int pic_burn(struct astribank_device *astribank, const struct hexdata *he
|
|||
}
|
||||
data = hexline->d.content.tt_data.data;
|
||||
check_sum ^= data[0] ^ data[1] ^ data[2];
|
||||
ret = send_picline(astribank, card_type, PIC_DATA_FLAG,
|
||||
ret = send_picline(ab, card_type, PIC_DATA_FLAG,
|
||||
hexline->d.content.header.offset, data, len);
|
||||
if(ret) {
|
||||
perror("Failed sending data hexline");
|
||||
|
@ -247,7 +250,7 @@ static int pic_burn(struct astribank_device *astribank, const struct hexdata *he
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
if((ret = send_picline(astribank, card_type, PIC_END_FLAG, 0, &check_sum, 1)) != 0) {
|
||||
if((ret = send_picline(ab, card_type, PIC_END_FLAG, 0, &check_sum, 1)) != 0) {
|
||||
perror("Failed sending end hexline");
|
||||
return 0;
|
||||
}
|
||||
|
@ -255,12 +258,12 @@ static int pic_burn(struct astribank_device *astribank, const struct hexdata *he
|
|||
return 1;
|
||||
}
|
||||
|
||||
int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[])
|
||||
int load_pic(struct astribank *ab, int numfiles, char *filelist[])
|
||||
{
|
||||
int i;
|
||||
const char *devstr;
|
||||
|
||||
devstr = xusb_devpath(astribank->xusb);
|
||||
devstr = xusb_devpath(xusb_dev_of_astribank(ab));
|
||||
DBG("%s: Loading %d PIC files...\n", devstr, numfiles);
|
||||
for(i = 0; i < numfiles; i++) {
|
||||
struct hexdata *picdata;
|
||||
|
@ -271,13 +274,13 @@ int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[])
|
|||
perror(curr);
|
||||
return -errno;
|
||||
}
|
||||
if(!pic_burn(astribank, picdata)) {
|
||||
if(!pic_burn(ab, picdata)) {
|
||||
ERR("%s: PIC %s burning failed\n", devstr, curr);
|
||||
return -ENODEV;
|
||||
}
|
||||
free_hexdata(picdata);
|
||||
}
|
||||
if((i = send_picline(astribank, 0, PIC_ENDS_FLAG, 0, NULL, 0)) != 0) {
|
||||
if((i = send_picline(ab, 0, PIC_ENDS_FLAG, 0, NULL, 0)) != 0) {
|
||||
ERR("%s: PIC end burning failed\n", devstr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "astribank_usb.h"
|
||||
#include "astribank.h"
|
||||
|
||||
/*
|
||||
* Astribank PIC loading
|
||||
|
@ -39,8 +39,8 @@ enum pic_command {
|
|||
#define PIC_PACK_LEN 0x0B
|
||||
#define PIC_LINE_LEN 0x03
|
||||
|
||||
int send_picline(struct astribank_device *astribank, uint8_t card_type,
|
||||
int send_picline(struct astribank *astribank, uint8_t card_type,
|
||||
enum pic_command pcmd, int offs, uint8_t *data, int data_len);
|
||||
int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[]);
|
||||
int load_pic(struct astribank *astribank, int numfiles, char *filelist[]);
|
||||
|
||||
#endif /* PIC_LOADER_H */
|
||||
|
|
|
@ -89,6 +89,10 @@ waitfor_ab_initialization() {
|
|||
done
|
||||
}
|
||||
|
||||
clean_lines() {
|
||||
sed -e 's/#.*//' -e 'y/\t/ /' -e 's/^ *//' -e 's/ *$//' -e '$s/$/\n/' "$1"
|
||||
}
|
||||
|
||||
# Any hardware?
|
||||
if ! dahdi_hardware="`which dahdi_hardware 2>/dev/null`"; then
|
||||
echo >&2 "$0: Missing dahdi_hardware"
|
||||
|
@ -150,13 +154,19 @@ cat /sys/bus/astribanks/devices/*/waitfor_xpds 2> /dev/null || :
|
|||
echo 1>&2 "Astribanks initializing spans"
|
||||
if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" = '' -a \
|
||||
"$ASTERISK_SUPPORTS_DAHDI_HOTPLUG" != 'yes' ]; then
|
||||
if [ -f /etc/dahdi/xpp_order ]; then
|
||||
# Now we can wait until the hotplug run would remove the semaphore
|
||||
echo -n 1>&2 "Other DAHDI initializations... "
|
||||
astribank_is_starting -v -w 1>&2
|
||||
else
|
||||
if [ ! -f /etc/dahdi/xpp_order ]; then
|
||||
echo 1>&2 "WARNING: No ASTERISK_SUPPORTS_DAHDI_HOTPLUG" \
|
||||
" and no /etc/dahdi/xpp_order"
|
||||
else
|
||||
count=`clean_lines /etc/dahdi/xpp_order | wc -l`
|
||||
if [ "$count" -le 0 ]; then
|
||||
echo 1>&2 "WARNING: No ASTERISK_SUPPORTS_DAHDI_HOTPLUG" \
|
||||
" and empty /etc/dahdi/xpp_order"
|
||||
else
|
||||
# Now we can wait until the hotplug run would remove the semaphore
|
||||
echo -n 1>&2 "Other DAHDI initializations... "
|
||||
astribank_is_starting -v -w 1>&2
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# All Astribanks initialized -- remove semaphore
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Load firmware into the Xorcom Astribank device:
|
||||
SUBSYSTEM=="usb", ACTION=="add", \
|
||||
ENV{PRODUCT}=="e4e4/11[3456][013]/*", ENV{DEVTYPE}!="usb_interface", \
|
||||
OPTIONS+="event_timeout=180" \
|
||||
RUN+="/usr/share/dahdi/xpp_fxloader udev $env{PRODUCT}"
|
||||
|
||||
# Hotplug hook for Astribank up/down
|
||||
|
|
|
@ -319,8 +319,9 @@ load_fw_device() {
|
|||
if [ "$pri_spec_wildcard" != '' ]; then
|
||||
debug "ECHO($dev_short): Found definitions for wildcard -- $pri_spec_wildcard"
|
||||
fi
|
||||
pri_spec=`echo "$pri_spec_wildcard $pri_spec" | tr -s ' \t\n' ','`
|
||||
if [ "$pri_spec" != '' ]; then
|
||||
pri_spec_params=""
|
||||
if [ "$pri_spec$pri_spec_wildcard" != '' ]; then
|
||||
pri_spec=`echo "$pri_spec_wildcard $pri_spec" | tr -s ' \t\n' ','`
|
||||
pri_spec_params="-S $pri_spec"
|
||||
debug "ECHO($dev_short): pri_spec_params='$pri_spec_params'"
|
||||
fi
|
||||
|
@ -348,7 +349,7 @@ load_fw_device() {
|
|||
echo "WARNING: ECHO burning was skipped (no capabilities)"
|
||||
fi
|
||||
fi
|
||||
pic_files=`echo "$FIRMWARE_DIR"/PIC_TYPE_[1-4].hex`
|
||||
pic_files=`echo "$FIRMWARE_DIR"/PIC_TYPE_[1-46].hex`
|
||||
debug "PIC burning into $dev: begin $pic_files"
|
||||
run_astribank_hexload -D "$dev" -p $pic_files
|
||||
debug "PIC burning into $dev: end $pic_files"
|
||||
|
@ -442,7 +443,7 @@ fpga_firmware_all_devices() {
|
|||
reset_fpga() {
|
||||
devices=`filter_devs 'e4e4/11[3456][124]/*'`
|
||||
totaldevs=`numdevs 'e4e4/11[3456][124]/*'`
|
||||
echo >&2 -- "Reseting devices [$totaldevs devices]"
|
||||
echo >&2 -- "Resetting devices [$totaldevs devices]"
|
||||
echo "$devices" | grep -v '^$' | while read id_str dev
|
||||
do
|
||||
(
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
# module match_flags idVendor idProduct bcdDevice_lo bcdDevice_hi bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass bInterfaceSubClass bInterfaceProtocol driver_info
|
||||
xpp_fxloader 0x0003 0x04b4 0x8613 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
|
||||
xpp_fxloader 0x0003 0xe4e4 0x1130 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
|
||||
xpp_fxloader 0x0003 0xe4e4 0x1131 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
|
||||
xpp_fxloader 0x0003 0xe4e4 0x1140 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
|
||||
xpp_fxloader 0x0003 0xe4e4 0x1141 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
|
||||
xpp_fxloader 0x0003 0xe4e4 0x1150 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
|
||||
xpp_fxloader 0x0003 0xe4e4 0x1151 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
|
||||
xpp_fxloader 0x0003 0xe4e4 0x1160 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
|
||||
xpp_fxloader 0x0003 0xe4e4 0x1161 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
|
|
@ -64,7 +64,7 @@ sub do_select(@) {
|
|||
foreach my $xpd (@_) {
|
||||
my $xbus = $xpd->xbus;
|
||||
my $busnum = $xbus->name;
|
||||
die "Uknown bus name" unless $busnum;
|
||||
die "Unknown bus name" unless $busnum;
|
||||
$busnum =~ s/XBUS-//;
|
||||
die "bad bus name" unless $busnum =~ /^\d+$/;
|
||||
#printf "Setting sync: %-10s (%s)\n", $xpd->fqn, $xpd->type;
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
VISIBILITY_DEFS = -DXTALK_DLL -DXTALK_DLL_EXPORTS
|
||||
COMMON_CFLAGS = \
|
||||
-Wall \
|
||||
-Wno-unknown-pragmas \
|
||||
-Werror \
|
||||
$(VISIBILITY_DEFS) \
|
||||
$(CFLAG_VISIBILITY)
|
||||
|
||||
AM_CFLAGS = $(COMMON_CFLAGS)
|
||||
|
||||
|
||||
if LIBUSBX
|
||||
USB_CFLAGS = $(LIBUSBX_CFLAGS)
|
||||
USB_LIBS = $(LIBUSBX_LIBS)
|
||||
USB_NAME = libusbx
|
||||
else
|
||||
if LIBUSB
|
||||
USB_CFLAGS = $(LIBUSB_CFLAGS)
|
||||
USB_LIBS = $(LIBUSB_LIBS)
|
||||
USB_NAME = libusb
|
||||
endif
|
||||
endif
|
||||
|
||||
noinst_PROGRAMS = xlist_test xusb_test xusb_test_bypath xtalk_test xtalk_raw_test xtalk_send
|
||||
noinst_LTLIBRARIES = libxtalk.la
|
||||
dist_noinst_HEADERS = \
|
||||
xtalk_base.h \
|
||||
xusb_common.h \
|
||||
include/xtalk/proto_raw.h \
|
||||
include/xtalk/api_defs.h \
|
||||
include/xtalk/xlist.h \
|
||||
include/xtalk/proto_sync.h \
|
||||
include/xtalk/xusb_iface.h \
|
||||
include/xtalk/proto.h \
|
||||
include/xtalk/debug.h \
|
||||
include/xtalk/xusb.h \
|
||||
include/xtalk/firmware_defs.h \
|
||||
include/xtalk/xtalk_iface.h \
|
||||
#
|
||||
|
||||
libxtalk_la_CFLAGS = \
|
||||
$(COMMON_CFLAGS) \
|
||||
-I$(srcdir)/include \
|
||||
-I$(srcdir) \
|
||||
$(USB_CFLAGS) \
|
||||
-DXTALK_OPTIONS_FILE=\"/etc/dahdi/xpp.conf\"
|
||||
|
||||
libxtalk_la_LDFLAGS = #
|
||||
libxtalk_la_LIBADD = $(USB_LIBS)
|
||||
libxtalk_la_SOURCES = \
|
||||
$(dist_noinst_HEADERS) \
|
||||
xtalk_sync.c \
|
||||
xtalk_raw.c \
|
||||
xtalk_base.c \
|
||||
xlist.c \
|
||||
debug.c \
|
||||
xtalk-xusb.c \
|
||||
xusb_common.c
|
||||
if LIBUSBX
|
||||
libxtalk_la_SOURCES += xusb_libusbx.c
|
||||
else
|
||||
if LIBUSB
|
||||
libxtalk_la_SOURCES += xusb_libusb.c
|
||||
endif
|
||||
endif
|
||||
libxtalk_la_DEPENDENCIES = $(libxtalk_la_SOURCES)
|
||||
|
||||
xtalk_send_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
|
||||
xtalk_send_LDADD = libxtalk.la $(USB_LIBS)
|
||||
|
||||
xtalk_test_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
|
||||
xtalk_test_LDADD = libxtalk.la $(USB_LIBS)
|
||||
|
||||
xtalk_raw_test_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
|
||||
xtalk_raw_test_LDADD = libxtalk.la $(USB_LIBS)
|
||||
|
||||
xusb_test_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
|
||||
xusb_test_LDADD = libxtalk.la $(USB_LIBS)
|
||||
|
||||
xusb_test_bypath_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
|
||||
xusb_test_bypath_LDADD = libxtalk.la $(USB_LIBS)
|
||||
|
||||
xlist_test_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
|
||||
xlist_test_LDADD = libxtalk.la $(USB_LIBS)
|
||||
|
||||
DISTCLEANFILES = xtalk.pc xtalk-uninstalled.pc
|
||||
|
||||
EXTRA_DIST = $(man_MANS)
|
|
@ -27,7 +27,8 @@
|
|||
#include <stdarg.h>
|
||||
#include <syslog.h>
|
||||
#include <execinfo.h>
|
||||
#include <debug.h>
|
||||
#include <xtalk/debug.h>
|
||||
#include <autoconfig.h>
|
||||
|
||||
int verbose = LOG_INFO;
|
||||
int debug_mask;
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef XTALK_API_DEFS_H
|
||||
#define XTALK_API_DEFS_H
|
||||
|
||||
/*
|
||||
* Visibility settings: taken from:
|
||||
* http://gcc.gnu.org/wiki/Visibility
|
||||
*/
|
||||
|
||||
/* Generic helper definitions for shared library support */
|
||||
#if __GNUC__ >= 4
|
||||
#define XTALK_HELPER_DLL_IMPORT __attribute__ ((visibility ("default")))
|
||||
#define XTALK_HELPER_DLL_EXPORT __attribute__ ((visibility ("default")))
|
||||
#define XTALK_HELPER_DLL_LOCAL __attribute__ ((visibility ("hidden")))
|
||||
#else
|
||||
#define XTALK_HELPER_DLL_IMPORT
|
||||
#define XTALK_HELPER_DLL_EXPORT
|
||||
#define XTALK_HELPER_DLL_LOCAL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Now we use the generic helper definitions above to define XTALK_API and XTALK_LOCAL.
|
||||
* XTALK_API is used for the public API symbols. It either DLL imports or DLL exports (or does nothing for static build)
|
||||
* XTALK_LOCAL is used for non-api symbols.
|
||||
*/
|
||||
|
||||
#ifdef XTALK_DLL /* defined if XTALK is compiled as a DLL */
|
||||
#ifdef XTALK_DLL_EXPORTS /* defined if we are building the XTALK DLL (instead of using it) */
|
||||
#define XTALK_API XTALK_HELPER_DLL_EXPORT
|
||||
#else
|
||||
#define XTALK_API XTALK_HELPER_DLL_IMPORT
|
||||
#endif /* XTALK_DLL_EXPORTS */
|
||||
#define XTALK_LOCAL XTALK_HELPER_DLL_LOCAL
|
||||
#else /* XTALK_DLL is not defined: this means XTALK is a static lib. */
|
||||
#define XTALK_API
|
||||
#define XTALK_LOCAL
|
||||
#endif /* XTALK_DLL */
|
||||
|
||||
#endif /* XTALK_API_DEFS_H */
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2008, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <syslog.h>
|
||||
#include <stdio.h>
|
||||
#include <xtalk/api_defs.h>
|
||||
|
||||
/*
|
||||
* Each module should define a unique DBG_MASK
|
||||
*/
|
||||
|
||||
XTALK_API extern int verbose;
|
||||
XTALK_API extern int debug_mask;
|
||||
|
||||
/*
|
||||
* Logging
|
||||
*/
|
||||
XTALK_API void log_function(int level, int mask, const char *msg, ...)
|
||||
__attribute__((format(printf, 3, 4)));
|
||||
|
||||
#define ERR(fmt, arg...) log_function(LOG_ERR, 0, "%s:%d: ERROR(%s): " fmt, \
|
||||
__FILE__, __LINE__, __func__, ## arg)
|
||||
#define WARN(fmt, arg...) log_function(LOG_WARNING, 0, "WARNING: " fmt, ## arg)
|
||||
#define INFO(fmt, arg...) log_function(LOG_INFO, 0, "INFO: " fmt, ## arg)
|
||||
#define DBG(fmt, arg...) log_function(LOG_DEBUG, DBG_MASK, \
|
||||
"%s:%d: DBG(%s): " fmt, __FILE__, __LINE__, __func__, ## arg)
|
||||
|
||||
XTALK_API void dump_packet(int loglevel, int mask, const char *msg,
|
||||
const char *buf, int len);
|
||||
XTALK_API void print_backtrace(FILE *fp);
|
||||
|
||||
#endif /* DEBUG_H */
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef XTALK_DEFS_H
|
||||
#define XTALK_DEFS_H
|
||||
#ifndef XTALK_FIRMWARE_DEFS_H
|
||||
#define XTALK_FIRMWARE_DEFS_H
|
||||
|
||||
#define MAX_OPS 256 /* single byte */
|
||||
#define MAX_STATUS 256 /* single byte */
|
||||
|
@ -8,18 +8,17 @@
|
|||
|
||||
#define PRIVATE_OP_FIRST 0x05
|
||||
#define PRIVATE_OP_LAST 0x7F
|
||||
#define IS_PRIVATE_OP(x) ( \
|
||||
(((x) & ~(XTALK_REPLY_MASK)) >= PRIVATE_OP_FIRST) && \
|
||||
(((x) & ~(XTALK_REPLY_MASK)) <= PRIVATE_OP_LAST) \
|
||||
)
|
||||
#define IS_PRIVATE_OP(x) ( \
|
||||
(((x) & ~(XTALK_REPLY_MASK)) >= PRIVATE_OP_FIRST) && \
|
||||
(((x) & ~(XTALK_REPLY_MASK)) <= PRIVATE_OP_LAST) \
|
||||
)
|
||||
|
||||
#define XTALK_ACK 0x80
|
||||
#define XTALK_PROTO_GET 0x01
|
||||
#define XTALK_PROTO_GET_REPLY (XTALK_PROTO_GET | XTALK_REPLY_MASK)
|
||||
#define XTALK_FWVERS_GET 0x11
|
||||
#define XTALK_FWVERS_GET_REPLY (XTALK_FWVERS_GET | XTALK_REPLY_MASK)
|
||||
/* Get EEPROM table contents Product/Vendor Id ... */
|
||||
#define XTALK_CAPS_GET 0x0E
|
||||
#define XTALK_CAPS_GET 0x0E /* Get EEPROM table contents Product/Vendor Id ... */
|
||||
#define XTALK_CAPS_GET_REPLY (XTALK_CAPS_GET | XTALK_REPLY_MASK)
|
||||
|
||||
/*------------- XTALK: statuses in ACK ---------------------------------------*/
|
||||
|
@ -38,4 +37,4 @@
|
|||
#define STAT_NOPWR_ERR 0x10 /* No power on USB connector */
|
||||
|
||||
|
||||
#endif /* XTALK_DEFS_H */
|
||||
#endif /* XTALK_FIRMWARE_DEFS_H */
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef XTALK_H
|
||||
#define XTALK_H
|
||||
#ifndef XTALK_PROTO_H
|
||||
#define XTALK_PROTO_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2009, Xorcom
|
||||
|
@ -35,8 +35,8 @@ extern "C"
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
/* Definitions common to the firmware (in include/ directory) */
|
||||
#include <xtalk_defs.h>
|
||||
#include <xtalk/api_defs.h>
|
||||
#include <xtalk/firmware_defs.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
|
@ -44,18 +44,25 @@ extern "C"
|
|||
#error "We do not know how your compiler packs structures"
|
||||
#endif
|
||||
|
||||
struct xtalk_device;
|
||||
struct xtalk_base;
|
||||
struct xtalk_command_desc;
|
||||
struct xtalk_command;
|
||||
|
||||
/*
|
||||
* Callbacks should return negative errno's
|
||||
* in case of errors.
|
||||
* They are called from process_command() and their
|
||||
* return values are propagated back.
|
||||
*/
|
||||
typedef int (*xtalk_cmd_callback_t)(
|
||||
struct xtalk_device *xtalk_dev,
|
||||
struct xtalk_command_desc *xtalk_cmd);
|
||||
const struct xtalk_base *xtalk_base,
|
||||
const struct xtalk_command_desc *cmd_desc,
|
||||
struct xtalk_command *cmd);
|
||||
|
||||
/* Describe a single xtalk command */
|
||||
struct xtalk_command_desc {
|
||||
uint8_t op;
|
||||
const char *name;
|
||||
xtalk_cmd_callback_t callback;
|
||||
uint16_t len; /* Minimal length */
|
||||
};
|
||||
|
||||
|
@ -102,12 +109,13 @@ struct xtalk_command {
|
|||
__VA_ARGS__ \
|
||||
} PACKED XTALK_STRUCT(p, o)
|
||||
#define MEMBER(p, o) struct XTALK_STRUCT(p, o) XTALK_STRUCT(p, o)
|
||||
#define XTALK_OP(p, o) (p ## _ ## o)
|
||||
|
||||
/* Wrappers for transport (xusb) functions */
|
||||
struct xtalk_ops {
|
||||
int (*send_func)(void *transport_priv, void *data, size_t len,
|
||||
int (*send_func)(void *transport_priv, const char *data, size_t len,
|
||||
int timeout);
|
||||
int (*recv_func)(void *transport_priv, void *data, size_t maxlen,
|
||||
int (*recv_func)(void *transport_priv, char *data, size_t maxlen,
|
||||
int timeout);
|
||||
int (*close_func)(void *transport_priv);
|
||||
};
|
||||
|
@ -117,38 +125,39 @@ struct xtalk_ops {
|
|||
* should be included in the struct representing
|
||||
* the dialect.
|
||||
*/
|
||||
struct xtalk_device;
|
||||
struct xtalk_base;
|
||||
struct xusb_iface;
|
||||
|
||||
/* high-level */
|
||||
struct xtalk_device *xtalk_new(const struct xtalk_ops *ops,
|
||||
size_t packet_size, void *transport_priv);
|
||||
void xtalk_delete(struct xtalk_device *dev);
|
||||
int xtalk_set_protocol(struct xtalk_device *xtalk_dev,
|
||||
const struct xtalk_protocol *xproto);
|
||||
int xtalk_proto_query(struct xtalk_device *dev);
|
||||
void xtalk_dump_command(struct xtalk_command *cmd);
|
||||
XTALK_API struct xtalk_base *xtalk_base_new_on_xusb(struct xusb_iface *xusb_iface);
|
||||
XTALK_API struct xtalk_base *xtalk_base_new(const struct xtalk_ops *ops,
|
||||
size_t packet_size, void *priv);
|
||||
XTALK_API void xtalk_base_delete(struct xtalk_base *xtalk_base);
|
||||
XTALK_API struct xusb_iface *xusb_iface_of_xtalk_base(const struct xtalk_base *xtalk_base);
|
||||
XTALK_API const char *xtalk_protocol_name(const struct xtalk_base *dev);
|
||||
XTALK_API int xtalk_cmd_callback(struct xtalk_base *xtalk_base, int op,
|
||||
xtalk_cmd_callback_t callback,
|
||||
xtalk_cmd_callback_t *old_callback);
|
||||
XTALK_API void xtalk_dump_command(struct xtalk_command *cmd);
|
||||
XTALK_API int xtalk_set_timeout(struct xtalk_base *dev, int new_timeout);
|
||||
|
||||
/* low-level */
|
||||
int process_command(
|
||||
struct xtalk_device *dev,
|
||||
struct xtalk_command *cmd,
|
||||
struct xtalk_command **reply_ref);
|
||||
struct xtalk_command *new_command(
|
||||
const struct xtalk_device *xtalk_dev,
|
||||
XTALK_API const char *ack_status_msg(const struct xtalk_protocol *xproto,
|
||||
uint8_t status);
|
||||
XTALK_API struct xtalk_command *new_command(
|
||||
const struct xtalk_base *xtalk_base,
|
||||
uint8_t op, uint16_t extra_data);
|
||||
void free_command(struct xtalk_command *cmd);
|
||||
XTALK_API void free_command(struct xtalk_command *cmd);
|
||||
|
||||
/*
|
||||
* Convenience macros to define entries in a protocol command table:
|
||||
* p - signify the dialect prefix (XTALK for base protocol)
|
||||
* o - signify command op (e.g: ACK)
|
||||
* cb - A callback function (type xtalk_cmd_callback_t)
|
||||
*/
|
||||
#define CMD_RECV(p, o, cb) \
|
||||
#define CMD_RECV(p, o) \
|
||||
[p ## _ ## o | XTALK_REPLY_MASK] = { \
|
||||
.op = (p ## _ ## o) | XTALK_REPLY_MASK, \
|
||||
.name = (#o "_reply"), \
|
||||
.callback = (cb), \
|
||||
.len = \
|
||||
sizeof(struct xtalk_header) + \
|
||||
sizeof(struct XTALK_STRUCT(p, o)), \
|
||||
|
@ -158,7 +167,6 @@ void free_command(struct xtalk_command *cmd);
|
|||
[p ## _ ## o] = { \
|
||||
.op = (p ## _ ## o), \
|
||||
.name = (#o), \
|
||||
.callback = NULL, \
|
||||
.len = \
|
||||
sizeof(struct xtalk_header) + \
|
||||
sizeof(struct XTALK_STRUCT(p, o)), \
|
||||
|
@ -175,4 +183,4 @@ void free_command(struct xtalk_command *cmd);
|
|||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* XTALK_H */
|
||||
#endif /* XTALK_PROTO_H */
|
|
@ -0,0 +1,76 @@
|
|||
#ifndef XTALK_PROTO_RAW_H
|
||||
#define XTALK_PROTO_RAW_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2009, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* XTALKSYNC - Base synchronous protocol for our USB devices
|
||||
* It is meant to provide a common base for layered
|
||||
* protocols (dialects)
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <xtalk/api_defs.h>
|
||||
#include <xtalk/proto.h>
|
||||
#include <xtalk/firmware_defs.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#error "We do not know how your compiler packs structures"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Base XTALK device. A pointer to this struct
|
||||
* should be included in the struct representing
|
||||
* the dialect.
|
||||
*/
|
||||
struct xtalk_raw;
|
||||
struct xusb;
|
||||
|
||||
XTALK_API struct xtalk_raw *xtalk_raw_new(struct xtalk_base *xtalk_base);
|
||||
XTALK_API void xtalk_raw_delete(struct xtalk_raw *xraw);
|
||||
XTALK_API int xtalk_raw_set_protocol(struct xtalk_raw *xtalk_base,
|
||||
const struct xtalk_protocol *xproto);
|
||||
XTALK_API int xtalk_raw_cmd_recv(struct xtalk_raw *xraw,
|
||||
struct xtalk_command **reply_ref);
|
||||
XTALK_API int xtalk_raw_cmd_send(struct xtalk_raw *xraw, const char *buf, int len,
|
||||
uint16_t *tx_seq);
|
||||
|
||||
/*
|
||||
* These are low-level interfaces that receive/send arbitrary buffers
|
||||
* Be carefull, as that allow to send illegal Xtalk packets
|
||||
*/
|
||||
XTALK_API int xtalk_raw_buffer_recv(struct xtalk_raw *xraw, char *buf, int len);
|
||||
XTALK_API int xtalk_raw_buffer_send(struct xtalk_raw *xraw, const char *buf, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* XTALK_PROTO_RAW_H */
|
|
@ -0,0 +1,75 @@
|
|||
#ifndef XTALK_PROTO_SYNC_H
|
||||
#define XTALK_PROTO_SYNC_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2009, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xtalk/api_defs.h>
|
||||
#include <xtalk/proto.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* XTALKSYNC - Base synchronous protocol for our USB devices
|
||||
* It is meant to provide a common base for layered
|
||||
* protocols (dialects)
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <xtalk/firmware_defs.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#error "We do not know how your compiler packs structures"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Base XTALK device. A pointer to this struct
|
||||
* should be included in the struct representing
|
||||
* the dialect.
|
||||
*/
|
||||
struct xtalk_sync;
|
||||
struct xusb;
|
||||
|
||||
/* high-level */
|
||||
XTALK_API struct xtalk_sync *xtalk_sync_new(struct xtalk_base *xtalk_base);
|
||||
XTALK_API void xtalk_sync_delete(struct xtalk_sync *xtalk_sync);
|
||||
XTALK_API int xtalk_sync_set_protocol(struct xtalk_sync *xtalk_base,
|
||||
const struct xtalk_protocol *xproto);
|
||||
XTALK_API int xtalk_proto_query(struct xtalk_sync *dev);
|
||||
|
||||
/* low-level */
|
||||
XTALK_API int process_command(
|
||||
struct xtalk_sync *dev,
|
||||
struct xtalk_command *cmd,
|
||||
struct xtalk_command **reply_ref,
|
||||
uint16_t *sequence_number);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* XTALK_PROTO_SYNC_H */
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef XLIST_H
|
||||
#define XLIST_H
|
||||
|
||||
#include <xtalk/api_defs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct xlist_node {
|
||||
void *data;
|
||||
struct xlist_node *next;
|
||||
struct xlist_node *prev;
|
||||
};
|
||||
|
||||
typedef void (*xlist_destructor_t)(void *data);
|
||||
|
||||
XTALK_API struct xlist_node *xlist_new(void *data);
|
||||
XTALK_API void xlist_destroy(struct xlist_node *list, xlist_destructor_t destructor);
|
||||
XTALK_API void xlist_append_list(struct xlist_node *list1, struct xlist_node *list2);
|
||||
XTALK_API void xlist_append_item(struct xlist_node *list, struct xlist_node *item);
|
||||
XTALK_API void xlist_remove_item(struct xlist_node *item);
|
||||
XTALK_API struct xlist_node *xlist_shift(struct xlist_node *list);
|
||||
XTALK_API int xlist_empty(const struct xlist_node *list);
|
||||
XTALK_API size_t xlist_length(const struct xlist_node *list);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* XLIST_H */
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Wrappers for swig/python integration
|
||||
*/
|
||||
|
||||
struct Command {
|
||||
struct xtalk_command *command;
|
||||
};
|
||||
|
||||
struct Xtalksync {
|
||||
struct xtalk_base *xtalk_base;
|
||||
struct xtalk_sync *xtalk_sync;
|
||||
struct XusbIface *py_xusb_iface;
|
||||
};
|
||||
|
||||
struct Xtalkraw {
|
||||
struct xtalk_base *xtalk_base;
|
||||
struct xtalk_raw *xtalk_raw;
|
||||
struct XusbIface *py_xusb_iface;
|
||||
};
|
|
@ -0,0 +1,115 @@
|
|||
#ifndef XUSB_H
|
||||
#define XUSB_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2008, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <xtalk/api_defs.h>
|
||||
#include <xtalk/xlist.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Xorcom usb handling
|
||||
*/
|
||||
|
||||
#define PACKET_SIZE 512
|
||||
|
||||
/*
|
||||
* Specify the wanted device
|
||||
*/
|
||||
struct xusb_spec {
|
||||
char *name; /* For debug/output purpose */
|
||||
/* What we will actually use */
|
||||
uint16_t vendor_id;
|
||||
uint16_t product_id;
|
||||
};
|
||||
|
||||
#define SPEC_HEAD(vendor_id_, product_id_, name_) \
|
||||
{ \
|
||||
.name = (name_), \
|
||||
.vendor_id = (vendor_id_), \
|
||||
.product_id = (product_id_), \
|
||||
}
|
||||
|
||||
XTALK_API void xusb_init_spec(struct xusb_spec *xusb_spec,
|
||||
char *name, uint16_t vendor_id, uint16_t product_id);
|
||||
|
||||
struct xusb_device;
|
||||
struct xusb_iface;
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
typedef int (*xusb_filter_t)(const struct xusb_device *xusb_device, void *data);
|
||||
XTALK_API struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs,
|
||||
int numspecs, xusb_filter_t filterfunc, void *data);
|
||||
XTALK_API struct xusb_device *xusb_find_bypath(const char *path);
|
||||
XTALK_API struct xusb_iface *xusb_open_one(const struct xusb_spec *specs, int numspecs,
|
||||
int interface_num,
|
||||
xusb_filter_t filterfunc, void *data);
|
||||
|
||||
/*
|
||||
* A convenience filter
|
||||
*/
|
||||
XTALK_API int xusb_filter_bypath(const struct xusb_device *xusb_device, void *data);
|
||||
|
||||
/* Device management */
|
||||
XTALK_API const struct xusb_spec *xusb_spec(const struct xusb_device *xusb_device);
|
||||
XTALK_API void xusb_destroy(struct xusb_device *xusb_device);
|
||||
XTALK_API size_t xusb_packet_size(const struct xusb_device *xusb_device);
|
||||
XTALK_API void xusb_showinfo(const struct xusb_device *xusb_device);
|
||||
XTALK_API const char *xusb_serial(const struct xusb_device *xusb_device);
|
||||
XTALK_API const char *xusb_manufacturer(const struct xusb_device *xusb_device);
|
||||
XTALK_API const char *xusb_product(const struct xusb_device *xusb_device);
|
||||
XTALK_API uint16_t xusb_bus_num(const struct xusb_device *xusb_device);
|
||||
XTALK_API uint16_t xusb_device_num(const struct xusb_device *xusb_device);
|
||||
XTALK_API uint16_t xusb_vendor_id(const struct xusb_device *xusb_device);
|
||||
XTALK_API uint16_t xusb_product_id(const struct xusb_device *xusb_device);
|
||||
XTALK_API const char *xusb_devpath(const struct xusb_device *xusb_device);
|
||||
XTALK_API const struct xusb_spec *xusb_device_spec(const struct xusb_device *xusb_device);
|
||||
XTALK_API struct xusb_iface *xusb_find_iface(const char *devpath,
|
||||
int iface_num,
|
||||
int ep_out,
|
||||
int ep_in,
|
||||
struct xusb_spec *dummy_spec);
|
||||
XTALK_API int xusb_claim(struct xusb_device *xusb_device, unsigned int interface_num,
|
||||
struct xusb_iface **iface);
|
||||
XTALK_API void xusb_release(struct xusb_iface *iface);
|
||||
XTALK_API int xusb_is_claimed(struct xusb_iface *iface);
|
||||
XTALK_API struct xusb_iface *xusb_interface_of(const struct xusb_device *dev, int num);
|
||||
XTALK_API struct xusb_device *xusb_deviceof(struct xusb_iface *iface);
|
||||
XTALK_API const char *xusb_interface_name(const struct xusb_iface *iface);
|
||||
XTALK_API int xusb_interface_num(const struct xusb_iface *iface);
|
||||
XTALK_API int xusb_send(struct xusb_iface *iface, const char *buf, int len, int timeout);
|
||||
XTALK_API int xusb_recv(struct xusb_iface *iface, char *buf, size_t len, int timeout);
|
||||
XTALK_API int xusb_flushread(struct xusb_iface *iface);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* XUSB_H */
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Wrappers for swig/python integration
|
||||
*/
|
||||
|
||||
#ifdef SWIG
|
||||
%feature("docstring", "Represents the specification of wanted USB device") Spec;
|
||||
#endif
|
||||
struct Spec {
|
||||
#ifdef SWIG
|
||||
%immutable spec;
|
||||
%immutable ref_count;
|
||||
#endif
|
||||
struct xusb_spec *spec;
|
||||
int ref_count;
|
||||
};
|
||||
|
||||
#ifdef SWIG
|
||||
%feature("docstring", "Represents a single USB device") XusbDev;
|
||||
#endif
|
||||
struct XusbDev {
|
||||
#ifdef SWIG
|
||||
%immutable spec;
|
||||
%immutable xusb_device;
|
||||
%immutable ref_count;
|
||||
#endif
|
||||
struct Spec *spec_wrapper;
|
||||
struct xusb_device *xusb_device;
|
||||
int ref_count;
|
||||
};
|
||||
|
||||
#ifdef SWIG
|
||||
%feature("docstring", "Represents a single USB interface") XusbIface;
|
||||
#endif
|
||||
struct XusbIface {
|
||||
#ifdef SWIG
|
||||
%immutable dev_wrapper;
|
||||
%immutable iface;
|
||||
#endif
|
||||
struct XusbDev *dev_wrapper; /* for ref-counting */
|
||||
struct xusb_iface *iface;
|
||||
};
|
||||
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <xlist.h>
|
||||
#include <xtalk/xlist.h>
|
||||
#include <autoconfig.h>
|
||||
|
||||
struct xlist_node *xlist_new(void *data)
|
||||
{
|
||||
|
@ -36,6 +37,17 @@ void xlist_destroy(struct xlist_node *list, xlist_destructor_t destructor)
|
|||
free(list);
|
||||
}
|
||||
|
||||
void xlist_append_list(struct xlist_node *list1, struct xlist_node *list2)
|
||||
{
|
||||
struct xlist_node *curr;
|
||||
|
||||
assert(list1);
|
||||
assert(list2);
|
||||
|
||||
while ((curr = xlist_shift(list2)) != NULL)
|
||||
xlist_append_item(list1, curr);
|
||||
}
|
||||
|
||||
void xlist_append_item(struct xlist_node *list, struct xlist_node *item)
|
||||
{
|
||||
assert(list);
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <xtalk/xlist.h>
|
||||
#include <autoconfig.h>
|
||||
|
||||
void dump_list(const struct xlist_node *list)
|
||||
{
|
||||
struct xlist_node *curr;
|
||||
const char *p;
|
||||
int len;
|
||||
|
||||
len = xlist_length(list);
|
||||
p = list->data;
|
||||
printf("dumping list: %s[%d]\n", p, len);
|
||||
for (curr = list->next; curr != list; curr = curr->next) {
|
||||
p = curr->data;
|
||||
printf("> %s\n", p);
|
||||
}
|
||||
}
|
||||
|
||||
void string_destructor(void *data)
|
||||
{
|
||||
const char *p = data;
|
||||
|
||||
printf("destroy: '%s'\n", p);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct xlist_node *list1;
|
||||
struct xlist_node *list2;
|
||||
struct xlist_node *list3;
|
||||
struct xlist_node *item1;
|
||||
struct xlist_node *item2;
|
||||
struct xlist_node *item3;
|
||||
|
||||
list1 = xlist_new("list1");
|
||||
list2 = xlist_new("list2");
|
||||
list3 = xlist_new("list3");
|
||||
item1 = xlist_new("item1");
|
||||
item2 = xlist_new("item2");
|
||||
item3 = xlist_new("item3");
|
||||
assert(xlist_empty(list1));
|
||||
assert(xlist_empty(list2));
|
||||
assert(xlist_empty(list3));
|
||||
assert(xlist_empty(item1));
|
||||
assert(xlist_empty(item2));
|
||||
assert(xlist_empty(item3));
|
||||
dump_list(list1);
|
||||
dump_list(list2);
|
||||
xlist_append_item(list1, item1);
|
||||
assert(!xlist_empty(list1));
|
||||
xlist_append_item(list1, item2);
|
||||
xlist_append_item(list1, item3);
|
||||
dump_list(list1);
|
||||
xlist_remove_item(item2);
|
||||
assert(!xlist_empty(list1));
|
||||
xlist_append_item(list2, item2);
|
||||
assert(!xlist_empty(list2));
|
||||
dump_list(list1);
|
||||
dump_list(list2);
|
||||
xlist_shift(list1);
|
||||
dump_list(list1);
|
||||
xlist_append_list(list1, list2);
|
||||
dump_list(list1);
|
||||
xlist_append_item(list3, item1);
|
||||
xlist_append_list(list1, list3);
|
||||
dump_list(list1);
|
||||
xlist_destroy(list1, string_destructor);
|
||||
xlist_destroy(list2, string_destructor);
|
||||
xlist_destroy(list3, string_destructor);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2012, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Convenience wrappers for xtalk_base over xusb
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <xtalk/debug.h>
|
||||
#include <xtalk/xusb.h>
|
||||
#include <autoconfig.h>
|
||||
#include "xtalk_base.h"
|
||||
|
||||
static inline int close_func(void *priv)
|
||||
{
|
||||
struct xusb_iface *iface = (struct xusb_iface *)priv;
|
||||
xusb_release(iface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int send_func(void *priv, const char *data, size_t len, int timeout)
|
||||
{
|
||||
return xusb_send((struct xusb_iface *)priv, data, len, timeout);
|
||||
}
|
||||
|
||||
static inline int recv_func(void *priv, char *data, size_t maxlen, int timeout)
|
||||
{
|
||||
return xusb_recv((struct xusb_iface *)priv, data, maxlen, timeout);
|
||||
}
|
||||
|
||||
|
||||
static struct xtalk_ops xtalk_ops = {
|
||||
.send_func = send_func,
|
||||
.recv_func = recv_func,
|
||||
.close_func = close_func,
|
||||
};
|
||||
|
||||
struct xtalk_base *xtalk_base_new_on_xusb(struct xusb_iface *xusb_iface)
|
||||
{
|
||||
struct xtalk_base *xtalk_base;
|
||||
int packet_size;
|
||||
|
||||
assert(xusb_iface);
|
||||
packet_size = xusb_packet_size(xusb_deviceof(xusb_iface));
|
||||
|
||||
xtalk_base = xtalk_base_new(&xtalk_ops, packet_size, xusb_iface);
|
||||
if (!xtalk_base) {
|
||||
ERR("Failed creating the xtalk device abstraction\n");
|
||||
return NULL;
|
||||
}
|
||||
return xtalk_base;
|
||||
}
|
|
@ -1,497 +0,0 @@
|
|||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2009, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <xtalk.h>
|
||||
#include <debug.h>
|
||||
|
||||
#define DBG_MASK 0x02
|
||||
|
||||
#define TIMEOUT 6000
|
||||
|
||||
/*
|
||||
* Base XTALK device. A pointer to this struct
|
||||
* should be included in the struct representing
|
||||
* the dialect.
|
||||
*/
|
||||
struct xtalk_device {
|
||||
void *transport_priv; /* e.g: struct xusb */
|
||||
struct xtalk_ops ops;
|
||||
struct xtalk_protocol xproto;
|
||||
uint8_t xtalk_proto_version;
|
||||
uint8_t status;
|
||||
size_t packet_size;
|
||||
uint16_t tx_sequenceno;
|
||||
};
|
||||
|
||||
CMD_DEF(XTALK, ACK,
|
||||
uint8_t stat;
|
||||
);
|
||||
|
||||
CMD_DEF(XTALK, PROTO_GET,
|
||||
uint8_t proto_version;
|
||||
uint8_t reserved;
|
||||
);
|
||||
|
||||
CMD_DEF(XTALK, PROTO_GET_REPLY,
|
||||
uint8_t proto_version;
|
||||
uint8_t reserved;
|
||||
);
|
||||
|
||||
union XTALK_PDATA(XTALK) {
|
||||
MEMBER(XTALK, ACK);
|
||||
MEMBER(XTALK, PROTO_GET);
|
||||
MEMBER(XTALK, PROTO_GET_REPLY);
|
||||
} PACKED members;
|
||||
|
||||
struct xtalk_protocol xtalk_base = {
|
||||
.name = "XTALK",
|
||||
.proto_version = 0,
|
||||
.commands = {
|
||||
CMD_RECV(XTALK, ACK, NULL),
|
||||
CMD_SEND(XTALK, PROTO_GET),
|
||||
CMD_RECV(XTALK, PROTO_GET_REPLY, NULL),
|
||||
},
|
||||
.ack_statuses = {
|
||||
ACK_STAT(OK, "Acknowledges previous command"),
|
||||
ACK_STAT(FAIL, "Last command failed"),
|
||||
ACK_STAT(RESET_FAIL, "reset failed"),
|
||||
ACK_STAT(NODEST, "No destination is selected"),
|
||||
ACK_STAT(MISMATCH, "Data mismatch"),
|
||||
ACK_STAT(NOACCESS, "No access"),
|
||||
ACK_STAT(BAD_CMD, "Bad command"),
|
||||
ACK_STAT(TOO_SHORT, "Packet is too short"),
|
||||
ACK_STAT(ERROFFS, "Offset error (not used)"),
|
||||
ACK_STAT(NO_LEEPROM, "Large EEPROM was not found"),
|
||||
ACK_STAT(NO_EEPROM, "No EEPROM was found"),
|
||||
ACK_STAT(WRITE_FAIL, "Writing to device failed"),
|
||||
ACK_STAT(NOPWR_ERR, "No power on USB connector"),
|
||||
}
|
||||
};
|
||||
|
||||
void free_command(struct xtalk_command *cmd)
|
||||
{
|
||||
if (!cmd)
|
||||
return;
|
||||
memset(cmd, 0, cmd->header.len);
|
||||
free(cmd);
|
||||
}
|
||||
|
||||
static const struct xtalk_command_desc *get_command_desc(
|
||||
const struct xtalk_protocol *xproto, uint8_t op)
|
||||
{
|
||||
const struct xtalk_command_desc *desc;
|
||||
|
||||
if (!xproto)
|
||||
return NULL;
|
||||
desc = &xproto->commands[op];
|
||||
if (!desc->name)
|
||||
return NULL;
|
||||
#if 0
|
||||
DBG("%s version=%d, op=0x%X (%s)\n",
|
||||
xproto->name, xproto->proto_version,
|
||||
op, desc->name);
|
||||
#endif
|
||||
return desc;
|
||||
}
|
||||
|
||||
static const char *ack_status_msg(const struct xtalk_protocol *xproto,
|
||||
uint8_t status)
|
||||
{
|
||||
const char *ack_status;
|
||||
|
||||
if (!xproto)
|
||||
return NULL;
|
||||
ack_status = xproto->ack_statuses[status];
|
||||
DBG("%s status=0x%X (%s)\n", xproto->name, status, ack_status);
|
||||
return ack_status;
|
||||
}
|
||||
|
||||
int xtalk_set_protocol(struct xtalk_device *xtalk_dev,
|
||||
const struct xtalk_protocol *xproto)
|
||||
{
|
||||
const char *protoname = (xproto) ? xproto->name : "GLOBAL";
|
||||
int i;
|
||||
|
||||
DBG("%s\n", protoname);
|
||||
memset(&xtalk_dev->xproto, 0, sizeof(xtalk_dev->xproto));
|
||||
for (i = 0; i < MAX_OPS; i++) {
|
||||
const struct xtalk_command_desc *desc;
|
||||
|
||||
desc = get_command_desc(xproto, i);
|
||||
if (desc) {
|
||||
if (!IS_PRIVATE_OP(i)) {
|
||||
ERR("Bad op=0x%X "
|
||||
"(should be in the range [0x%X-0x%X]\n",
|
||||
i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST);
|
||||
return -EINVAL;
|
||||
}
|
||||
xtalk_dev->xproto.commands[i] = *desc;
|
||||
DBG("private: op=0x%X (%s)\n", i, desc->name);
|
||||
} else {
|
||||
if (!IS_PRIVATE_OP(i)) {
|
||||
const char *name;
|
||||
|
||||
xtalk_dev->xproto.commands[i] =
|
||||
xtalk_base.commands[i];
|
||||
name = xtalk_dev->xproto.commands[i].name;
|
||||
if (name)
|
||||
DBG("global: op=0x%X (%s)\n", i, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_STATUS; i++) {
|
||||
const char *stat_msg;
|
||||
|
||||
stat_msg = (xproto) ? xproto->ack_statuses[i] : NULL;
|
||||
if (stat_msg) {
|
||||
if (!IS_PRIVATE_OP(i)) {
|
||||
ERR("Bad status=0x%X "
|
||||
"(should be in the range [0x%X-0x%X]\n",
|
||||
i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST);
|
||||
return -EINVAL;
|
||||
}
|
||||
xtalk_dev->xproto.ack_statuses[i] = stat_msg;
|
||||
DBG("private: status=0x%X (%s)\n", i, stat_msg);
|
||||
} else {
|
||||
if (!IS_PRIVATE_OP(i)) {
|
||||
const char *stat_msg;
|
||||
|
||||
xtalk_dev->xproto.ack_statuses[i] =
|
||||
xtalk_base.ack_statuses[i];
|
||||
stat_msg = xtalk_dev->xproto.ack_statuses[i];
|
||||
if (stat_msg)
|
||||
DBG("global: status=0x%X (%s)\n",
|
||||
i, stat_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
xtalk_dev->xproto.name = protoname;
|
||||
xtalk_dev->xproto.proto_version = (xproto) ? xproto->proto_version : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct xtalk_command *new_command(
|
||||
const struct xtalk_device *xtalk_dev,
|
||||
uint8_t op, uint16_t extra_data)
|
||||
{
|
||||
const struct xtalk_protocol *xproto;
|
||||
struct xtalk_command *cmd;
|
||||
const struct xtalk_command_desc *desc;
|
||||
uint16_t len;
|
||||
|
||||
xproto = &xtalk_dev->xproto;
|
||||
desc = get_command_desc(xproto, op);
|
||||
if (!desc) {
|
||||
ERR("Unknown op=0x%X.\n", op);
|
||||
return NULL;
|
||||
}
|
||||
DBG("OP=0x%X [%s] (extra_data %d)\n", op, desc->name, extra_data);
|
||||
len = desc->len + extra_data;
|
||||
cmd = malloc(len);
|
||||
if (!cmd) {
|
||||
ERR("Out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
if (extra_data) {
|
||||
uint8_t *ptr = (uint8_t *)cmd;
|
||||
|
||||
DBG("clear extra_data (%d bytes)\n", extra_data);
|
||||
memset(ptr + desc->len, 0, extra_data);
|
||||
}
|
||||
cmd->header.op = op;
|
||||
cmd->header.len = len;
|
||||
cmd->header.seq = 0; /* Overwritten in send_usb() */
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void xtalk_dump_command(struct xtalk_command *cmd)
|
||||
{
|
||||
uint16_t len;
|
||||
int i;
|
||||
|
||||
len = cmd->header.len;
|
||||
if (len < sizeof(struct xtalk_header)) {
|
||||
ERR("Command too short (%d)\n", len);
|
||||
return;
|
||||
}
|
||||
INFO("DUMP: OP=0x%X len=%d seq=%d\n",
|
||||
cmd->header.op, cmd->header.len, cmd->header.seq);
|
||||
for (i = 0; i < len - sizeof(struct xtalk_header); i++)
|
||||
INFO(" %2d. 0x%X\n", i, cmd->alt.raw_data[i]);
|
||||
}
|
||||
|
||||
static int send_command(struct xtalk_device *xtalk_dev,
|
||||
struct xtalk_command *cmd, int timeout)
|
||||
{
|
||||
int ret;
|
||||
int len;
|
||||
void *priv = xtalk_dev->transport_priv;
|
||||
|
||||
len = cmd->header.len;
|
||||
cmd->header.seq = xtalk_dev->tx_sequenceno;
|
||||
|
||||
ret = xtalk_dev->ops.send_func(priv, (char *)cmd, len, timeout);
|
||||
if (ret < 0)
|
||||
DBG("send_func failed ret=%d\n", ret);
|
||||
xtalk_dev->tx_sequenceno++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct xtalk_command *recv_command(struct xtalk_device *xtalk_dev,
|
||||
int timeout)
|
||||
{
|
||||
struct xtalk_command *reply;
|
||||
void *priv = xtalk_dev->transport_priv;
|
||||
size_t psize = xtalk_dev->packet_size;
|
||||
int ret;
|
||||
|
||||
reply = malloc(psize);
|
||||
if (!reply) {
|
||||
ERR("Out of memory\n");
|
||||
goto err;
|
||||
}
|
||||
reply->header.len = 0;
|
||||
ret = xtalk_dev->ops.recv_func(priv, (char *)reply, psize, timeout);
|
||||
if (ret < 0) {
|
||||
ERR("Receive from usb failed.\n");
|
||||
goto err;
|
||||
} else if (ret == 0) {
|
||||
goto err; /* No reply */
|
||||
}
|
||||
if (ret != reply->header.len) {
|
||||
ERR("Wrong length received: got %d bytes, "
|
||||
"but length field says %d bytes%s\n",
|
||||
ret, reply->header.len,
|
||||
(ret == 1) ? ". Old USB firmware?" : "");
|
||||
goto err;
|
||||
}
|
||||
/* dump_packet(LOG_DEBUG, DBG_MASK, __func__, (char *)reply, ret); */
|
||||
return reply;
|
||||
err:
|
||||
if (reply) {
|
||||
memset(reply, 0, psize);
|
||||
free_command(reply);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
__attribute__((warn_unused_result))
|
||||
int process_command(
|
||||
struct xtalk_device *xtalk_dev,
|
||||
struct xtalk_command *cmd,
|
||||
struct xtalk_command **reply_ref)
|
||||
{
|
||||
const struct xtalk_protocol *xproto;
|
||||
struct xtalk_command *reply = NULL;
|
||||
const struct xtalk_command_desc *reply_desc;
|
||||
const struct xtalk_command_desc *expected;
|
||||
const struct xtalk_command_desc *cmd_desc;
|
||||
uint8_t reply_op;
|
||||
const char *protoname;
|
||||
int ret;
|
||||
|
||||
xproto = &xtalk_dev->xproto;
|
||||
protoname = (xproto) ? xproto->name : "GLOBAL";
|
||||
/* So the caller knows if a reply was received */
|
||||
if (reply_ref)
|
||||
*reply_ref = NULL;
|
||||
reply_op = cmd->header.op | XTALK_REPLY_MASK;
|
||||
cmd_desc = get_command_desc(xproto, cmd->header.op);
|
||||
expected = get_command_desc(xproto, reply_op);
|
||||
ret = send_command(xtalk_dev, cmd, TIMEOUT);
|
||||
if (!reply_ref) {
|
||||
DBG("No reply requested\n");
|
||||
goto out;
|
||||
}
|
||||
if (ret < 0) {
|
||||
ERR("send_command failed: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
reply = recv_command(xtalk_dev, TIMEOUT);
|
||||
if (!reply) {
|
||||
ERR("recv_command failed\n");
|
||||
ret = -EPROTO;
|
||||
goto out;
|
||||
}
|
||||
*reply_ref = reply;
|
||||
if ((reply->header.op & 0x80) != 0x80) {
|
||||
ERR("Unexpected reply op=0x%02X, should have MSB set.\n",
|
||||
reply->header.op);
|
||||
ret = -EPROTO;
|
||||
goto out;
|
||||
}
|
||||
DBG("REPLY OP: 0x%X\n", reply->header.op);
|
||||
reply_desc = get_command_desc(xproto, reply->header.op);
|
||||
if (!reply_desc) {
|
||||
ERR("Unknown reply (proto=%s) op=0x%02X\n",
|
||||
protoname, reply->header.op);
|
||||
ret = -EPROTO;
|
||||
goto out;
|
||||
}
|
||||
DBG("REPLY NAME: %s\n", reply_desc->name);
|
||||
if (reply->header.op == XTALK_ACK) {
|
||||
int status = CMD_FIELD(reply, XTALK, ACK, stat);
|
||||
|
||||
if (expected) {
|
||||
ERR("Expected OP=0x%02X: Got ACK(%d): %s\n",
|
||||
reply_op,
|
||||
status,
|
||||
ack_status_msg(xproto, status));
|
||||
ret = -EPROTO;
|
||||
goto out;
|
||||
} else if (status != STAT_OK) {
|
||||
|
||||
ERR("Got ACK (for OP=0x%X [%s]): %d %s\n",
|
||||
cmd->header.op,
|
||||
cmd_desc->name,
|
||||
status, ack_status_msg(xproto, status));
|
||||
ret = -EPROTO;
|
||||
goto out;
|
||||
}
|
||||
/* Good expected ACK ... */
|
||||
} else if (reply->header.op != reply_op) {
|
||||
ERR("Expected OP=0x%02X: Got OP=0x%02X\n",
|
||||
reply_op, reply->header.op);
|
||||
ret = -EPROTO;
|
||||
goto out;
|
||||
}
|
||||
if (expected && expected->len > reply->header.len) {
|
||||
ERR("Expected len=%d: Got len=%d\n",
|
||||
expected->len, reply->header.len);
|
||||
ret = -EPROTO;
|
||||
goto out;
|
||||
}
|
||||
if (cmd->header.seq != reply->header.seq) {
|
||||
ERR("Expected seq=%d: Got seq=%d\n",
|
||||
cmd->header.seq, reply->header.seq);
|
||||
ret = -EPROTO;
|
||||
goto out;
|
||||
}
|
||||
ret = reply->header.len; /* All good, return the length */
|
||||
DBG("returning reply op 0x%X (%d bytes)\n", reply->header.op, ret);
|
||||
out:
|
||||
free_command(cmd);
|
||||
if (!reply_ref && reply)
|
||||
free_command(reply);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Protocol Commands
|
||||
*/
|
||||
|
||||
int xtalk_proto_query(struct xtalk_device *xtalk_dev)
|
||||
{
|
||||
struct xtalk_command *cmd;
|
||||
struct xtalk_command *reply;
|
||||
uint8_t proto_version;
|
||||
int ret;
|
||||
|
||||
DBG("\n");
|
||||
assert(xtalk_dev != NULL);
|
||||
proto_version = xtalk_dev->xproto.proto_version;
|
||||
cmd = new_command(xtalk_dev, XTALK_PROTO_GET, 0);
|
||||
if (!cmd) {
|
||||
ERR("new_command failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* Protocol Version */
|
||||
CMD_FIELD(cmd, XTALK, PROTO_GET, proto_version) = proto_version;
|
||||
ret = process_command(xtalk_dev, cmd, &reply);
|
||||
if (ret < 0) {
|
||||
ERR("process_command failed: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
xtalk_dev->xtalk_proto_version =
|
||||
CMD_FIELD(reply, XTALK, PROTO_GET_REPLY, proto_version);
|
||||
if (xtalk_dev->xtalk_proto_version != proto_version) {
|
||||
DBG("Got %s protocol version: 0x%02x (expected 0x%02x)\n",
|
||||
xtalk_dev->xproto.name,
|
||||
xtalk_dev->xtalk_proto_version,
|
||||
proto_version);
|
||||
ret = xtalk_dev->xtalk_proto_version;
|
||||
goto out;
|
||||
}
|
||||
DBG("Protocol version: %02x\n", xtalk_dev->xtalk_proto_version);
|
||||
ret = xtalk_dev->xtalk_proto_version;
|
||||
out:
|
||||
free_command(reply);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrappers
|
||||
*/
|
||||
|
||||
struct xtalk_device *xtalk_new(const struct xtalk_ops *ops,
|
||||
size_t packet_size, void *priv)
|
||||
{
|
||||
struct xtalk_device *xtalk_dev;
|
||||
int ret;
|
||||
|
||||
DBG("\n");
|
||||
assert(ops != NULL);
|
||||
xtalk_dev = malloc(sizeof(*xtalk_dev));
|
||||
if (!xtalk_dev) {
|
||||
ERR("Allocating XTALK device memory failed\n");
|
||||
return NULL;
|
||||
}
|
||||
memset(xtalk_dev, 0, sizeof(*xtalk_dev));
|
||||
memcpy((void *)&xtalk_dev->ops, (const void *)ops,
|
||||
sizeof(xtalk_dev->ops));
|
||||
xtalk_dev->transport_priv = priv;
|
||||
xtalk_dev->packet_size = packet_size;
|
||||
xtalk_dev->tx_sequenceno = 1;
|
||||
ret = xtalk_set_protocol(xtalk_dev, NULL);
|
||||
if (ret < 0) {
|
||||
ERR("GLOBAL Protocol registration failed: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
return xtalk_dev;
|
||||
|
||||
err:
|
||||
if (xtalk_dev)
|
||||
xtalk_delete(xtalk_dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xtalk_delete(struct xtalk_device *xtalk_dev)
|
||||
{
|
||||
void *priv;
|
||||
|
||||
if (!xtalk_dev)
|
||||
return;
|
||||
DBG("\n");
|
||||
priv = xtalk_dev->transport_priv;
|
||||
assert(priv);
|
||||
xtalk_dev->tx_sequenceno = 0;
|
||||
assert(&xtalk_dev->ops != NULL);
|
||||
assert(&xtalk_dev->ops.close_func != NULL);
|
||||
xtalk_dev->ops.close_func(priv);
|
||||
}
|
|
@ -0,0 +1,350 @@
|
|||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2009, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <xtalk/debug.h>
|
||||
#include <autoconfig.h>
|
||||
#include "xtalk_base.h"
|
||||
|
||||
#define DBG_MASK 0x02
|
||||
|
||||
void free_command(struct xtalk_command *cmd)
|
||||
{
|
||||
if (!cmd)
|
||||
return;
|
||||
memset(cmd, 0, cmd->header.len);
|
||||
free(cmd);
|
||||
}
|
||||
|
||||
const struct xtalk_command_desc *get_command_desc(
|
||||
const struct xtalk_protocol *xproto, uint8_t op)
|
||||
{
|
||||
const struct xtalk_command_desc *desc;
|
||||
|
||||
if (!xproto)
|
||||
return NULL;
|
||||
desc = &xproto->commands[op];
|
||||
if (!desc->name)
|
||||
return NULL;
|
||||
#if 0
|
||||
DBG("%s version=%d, op=0x%X (%s)\n",
|
||||
xproto->name, xproto->proto_version,
|
||||
op, desc->name);
|
||||
#endif
|
||||
return desc;
|
||||
}
|
||||
|
||||
const char *ack_status_msg(const struct xtalk_protocol *xproto,
|
||||
uint8_t status)
|
||||
{
|
||||
const char *ack_status;
|
||||
|
||||
if (!xproto)
|
||||
return NULL;
|
||||
ack_status = xproto->ack_statuses[status];
|
||||
DBG("%s status=0x%X (%s)\n", xproto->name, status, ack_status);
|
||||
return ack_status;
|
||||
}
|
||||
|
||||
const char *xtalk_protocol_name(const struct xtalk_base *xtalk_base)
|
||||
{
|
||||
const struct xtalk_protocol *xproto;
|
||||
|
||||
xproto = &xtalk_base->xproto;
|
||||
return (xproto) ? xproto->name : "";
|
||||
}
|
||||
|
||||
int xtalk_set_protocol(struct xtalk_base *xtalk_base,
|
||||
const struct xtalk_protocol *xproto_base,
|
||||
const struct xtalk_protocol *xproto)
|
||||
{
|
||||
const char *protoname = (xproto) ? xproto->name : "GLOBAL";
|
||||
int i;
|
||||
|
||||
DBG("%s\n", protoname);
|
||||
memset(&xtalk_base->xproto, 0, sizeof(xtalk_base->xproto));
|
||||
for (i = 0; i < MAX_OPS; i++) {
|
||||
const struct xtalk_command_desc *desc;
|
||||
|
||||
desc = get_command_desc(xproto, i);
|
||||
if (desc) {
|
||||
if (!IS_PRIVATE_OP(i)) {
|
||||
ERR("Bad op=0x%X "
|
||||
"(should be in the range [0x%X-0x%X]\n",
|
||||
i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST);
|
||||
return -EINVAL;
|
||||
}
|
||||
xtalk_base->xproto.commands[i] = *desc;
|
||||
DBG("private: op=0x%X (%s)\n", i, desc->name);
|
||||
} else {
|
||||
if (!IS_PRIVATE_OP(i)) {
|
||||
const char *name;
|
||||
|
||||
xtalk_base->xproto.commands[i] =
|
||||
xproto_base->commands[i];
|
||||
name = xtalk_base->xproto.commands[i].name;
|
||||
if (name)
|
||||
DBG("global: op=0x%X (%s)\n", i, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_STATUS; i++) {
|
||||
const char *stat_msg;
|
||||
|
||||
stat_msg = (xproto) ? xproto->ack_statuses[i] : NULL;
|
||||
if (stat_msg) {
|
||||
xtalk_base->xproto.ack_statuses[i] = stat_msg;
|
||||
DBG("private: status=0x%X (%s)\n", i, stat_msg);
|
||||
} else {
|
||||
const char *global_msg;
|
||||
|
||||
xtalk_base->xproto.ack_statuses[i] =
|
||||
xproto_base->ack_statuses[i];
|
||||
global_msg = xtalk_base->xproto.ack_statuses[i];
|
||||
if (global_msg)
|
||||
DBG("global: status=0x%X (%s)\n",
|
||||
i, global_msg);
|
||||
}
|
||||
}
|
||||
xtalk_base->xproto.name = protoname;
|
||||
xtalk_base->xproto.proto_version = (xproto) ? xproto->proto_version : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xtalk_cmd_callback(struct xtalk_base *xtalk_base, int op,
|
||||
xtalk_cmd_callback_t callback,
|
||||
xtalk_cmd_callback_t *old_callback)
|
||||
{
|
||||
const struct xtalk_protocol *xproto;
|
||||
const struct xtalk_command_desc *desc;
|
||||
|
||||
xproto = &xtalk_base->xproto;
|
||||
desc = get_command_desc(xproto, op);
|
||||
if (!desc)
|
||||
DBG("Unknown op=0x%X.\n", op);
|
||||
if (old_callback)
|
||||
*old_callback = xtalk_base->callbacks[op];
|
||||
if (callback) {
|
||||
xtalk_base->callbacks[op] = callback;
|
||||
DBG("OP=0x%X [%s] -- set callback to %p\n",
|
||||
op,
|
||||
(desc) ? desc->name : "",
|
||||
callback);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct xtalk_command *new_command(
|
||||
const struct xtalk_base *xtalk_base,
|
||||
uint8_t op, uint16_t extra_data)
|
||||
{
|
||||
const struct xtalk_protocol *xproto;
|
||||
struct xtalk_command *cmd;
|
||||
const struct xtalk_command_desc *desc;
|
||||
uint16_t len;
|
||||
|
||||
xproto = &xtalk_base->xproto;
|
||||
desc = get_command_desc(xproto, op);
|
||||
if (!desc) {
|
||||
ERR("Unknown op=0x%X.\n", op);
|
||||
return NULL;
|
||||
}
|
||||
DBG("OP=0x%X [%s] (extra_data %d)\n", op, desc->name, extra_data);
|
||||
len = desc->len + extra_data;
|
||||
cmd = malloc(len);
|
||||
if (!cmd) {
|
||||
ERR("Out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
if (extra_data) {
|
||||
uint8_t *ptr = (uint8_t *)cmd;
|
||||
|
||||
DBG("clear extra_data (%d bytes)\n", extra_data);
|
||||
memset(ptr + desc->len, 0, extra_data);
|
||||
}
|
||||
cmd->header.op = op;
|
||||
cmd->header.len = len;
|
||||
cmd->header.seq = 0; /* Overwritten in send_usb() */
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void xtalk_dump_command(struct xtalk_command *cmd)
|
||||
{
|
||||
uint16_t len;
|
||||
int i;
|
||||
|
||||
len = cmd->header.len;
|
||||
if (len < sizeof(struct xtalk_header)) {
|
||||
ERR("Command too short (%d)\n", len);
|
||||
return;
|
||||
}
|
||||
INFO("DUMP: OP=0x%X len=%d seq=%d\n",
|
||||
cmd->header.op, cmd->header.len, cmd->header.seq);
|
||||
for (i = 0; i < len - sizeof(struct xtalk_header); i++)
|
||||
INFO(" %2d. 0x%X\n", i, cmd->alt.raw_data[i]);
|
||||
}
|
||||
|
||||
int xtalk_set_timeout(struct xtalk_base *dev, int new_timeout)
|
||||
{
|
||||
int old_timeout = dev->default_timeout;
|
||||
dev->default_timeout = new_timeout;
|
||||
return old_timeout;
|
||||
}
|
||||
|
||||
int send_buffer(struct xtalk_base *xtalk_base, const char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
void *priv = xtalk_base->transport_priv;
|
||||
int timeout = xtalk_base->default_timeout;
|
||||
|
||||
ret = xtalk_base->ops.send_func(priv, buf, len, timeout);
|
||||
if (ret < 0)
|
||||
DBG("%s: failed ret=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int recv_buffer(struct xtalk_base *xtalk_base, char *buf, int len)
|
||||
{
|
||||
void *priv = xtalk_base->transport_priv;
|
||||
int timeout = xtalk_base->default_timeout;
|
||||
int ret;
|
||||
|
||||
ret = xtalk_base->ops.recv_func(priv, buf, len, timeout);
|
||||
if (ret < 0) {
|
||||
DBG("Receive from usb failed (ret=%d)\n", ret);
|
||||
goto out;
|
||||
} else if (ret == 0) {
|
||||
DBG("No reply\n");
|
||||
goto out; /* No reply */
|
||||
}
|
||||
DBG("Received %d bytes\n", ret);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int send_command(struct xtalk_base *xtalk_base,
|
||||
struct xtalk_command *cmd, uint16_t *tx_seq)
|
||||
{
|
||||
int ret;
|
||||
int len;
|
||||
|
||||
len = cmd->header.len;
|
||||
cmd->header.seq = xtalk_base->tx_sequenceno;
|
||||
ret = send_buffer(xtalk_base, (const char *)cmd, len);
|
||||
if (ret < 0)
|
||||
DBG("%s: failed ret=%d\n", __func__, ret);
|
||||
else if (tx_seq)
|
||||
*tx_seq = xtalk_base->tx_sequenceno++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int recv_command(struct xtalk_base *xtalk_base,
|
||||
struct xtalk_command **reply_ref)
|
||||
{
|
||||
struct xtalk_command *reply;
|
||||
size_t psize = xtalk_base->packet_size;
|
||||
int ret;
|
||||
|
||||
reply = malloc(psize);
|
||||
if (!reply) {
|
||||
ERR("Out of memory\n");
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
reply->header.len = 0;
|
||||
ret = recv_buffer(xtalk_base, (char *)reply, psize);
|
||||
if (ret < 0) {
|
||||
DBG("%s: calling recv_buffer() failed (ret=%d)\n", __func__, ret);
|
||||
goto err;
|
||||
} else if (ret == 0) {
|
||||
goto err; /* No reply */
|
||||
}
|
||||
if (ret != reply->header.len) {
|
||||
ERR("Wrong length received: got %d bytes, "
|
||||
"but length field says %d bytes%s\n",
|
||||
ret, reply->header.len,
|
||||
(ret == 1) ? ". Old USB firmware?" : "");
|
||||
goto err;
|
||||
}
|
||||
/* dump_packet(LOG_DEBUG, DBG_MASK, __func__, (char *)reply, ret); */
|
||||
*reply_ref = reply;
|
||||
return ret;
|
||||
err:
|
||||
if (reply) {
|
||||
memset(reply, 0, psize);
|
||||
free_command(reply);
|
||||
*reply_ref = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrappers
|
||||
*/
|
||||
|
||||
struct xtalk_base *xtalk_base_new(const struct xtalk_ops *ops,
|
||||
size_t packet_size, void *priv)
|
||||
{
|
||||
struct xtalk_base *xtalk_base;
|
||||
|
||||
DBG("\n");
|
||||
assert(ops != NULL);
|
||||
xtalk_base = calloc(1, sizeof(*xtalk_base));
|
||||
if (!xtalk_base) {
|
||||
ERR("Allocating XTALK device memory failed\n");
|
||||
return NULL;
|
||||
}
|
||||
memcpy((void *)&xtalk_base->ops, (const void *)ops,
|
||||
sizeof(xtalk_base->ops));
|
||||
xtalk_base->packet_size = packet_size;
|
||||
xtalk_base->transport_priv = priv;
|
||||
xtalk_base->tx_sequenceno = 1;
|
||||
xtalk_base->default_timeout = 2000; /* millies */
|
||||
return xtalk_base;
|
||||
}
|
||||
|
||||
void xtalk_base_delete(struct xtalk_base *xtalk_base)
|
||||
{
|
||||
void *priv;
|
||||
|
||||
if (!xtalk_base)
|
||||
return;
|
||||
DBG("\n");
|
||||
priv = xtalk_base->transport_priv;
|
||||
assert(priv);
|
||||
xtalk_base->tx_sequenceno = 0;
|
||||
assert(&xtalk_base->ops != NULL);
|
||||
assert(&xtalk_base->ops.close_func != NULL);
|
||||
xtalk_base->ops.close_func(priv);
|
||||
memset(xtalk_base, 0, sizeof(*xtalk_base));
|
||||
free(xtalk_base);
|
||||
}
|
||||
|
||||
struct xusb_iface *xusb_iface_of_xtalk_base(const struct xtalk_base *xtalk_base)
|
||||
{
|
||||
return xtalk_base->transport_priv;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef XTALK_BASE_H
|
||||
#define XTALK_BASE_H
|
||||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2009, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <xtalk/proto.h>
|
||||
#include <xtalk/firmware_defs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Base XTALK device. A pointer to this struct
|
||||
* should be included in the struct representing
|
||||
* the dialect.
|
||||
*/
|
||||
struct xtalk_base {
|
||||
void *transport_priv; /* e.g: struct xusb */
|
||||
struct xtalk_ops ops;
|
||||
struct xtalk_protocol xproto;
|
||||
xtalk_cmd_callback_t callbacks[MAX_OPS];
|
||||
uint8_t xtalk_proto_version;
|
||||
uint8_t status;
|
||||
size_t packet_size;
|
||||
uint16_t tx_sequenceno;
|
||||
int default_timeout; /* in millies */
|
||||
};
|
||||
|
||||
int xtalk_set_protocol(struct xtalk_base *xtalk_base,
|
||||
const struct xtalk_protocol *xproto_base,
|
||||
const struct xtalk_protocol *xproto);
|
||||
const struct xtalk_command_desc *get_command_desc(
|
||||
const struct xtalk_protocol *xproto, uint8_t op);
|
||||
int send_command(struct xtalk_base *xtalk_base,
|
||||
struct xtalk_command *cmd, uint16_t *tx_seq);
|
||||
int recv_command(struct xtalk_base *xtalk_base,
|
||||
struct xtalk_command **reply_ref);
|
||||
|
||||
/*
|
||||
* These are low-level interfaces that receive/send arbitrary buffers
|
||||
* Be carefull, as that allow to send illegal Xtalk packets
|
||||
*/
|
||||
int send_buffer(struct xtalk_base *xtalk_base, const char *buf, int len);
|
||||
int recv_buffer(struct xtalk_base *xtalk_base, char *buf, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* XTALK_BASE_H */
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2009, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <xtalk/debug.h>
|
||||
#include <xtalk/proto_raw.h>
|
||||
#include <autoconfig.h>
|
||||
#include "xtalk_base.h"
|
||||
|
||||
#define DBG_MASK 0x02
|
||||
|
||||
/*
|
||||
* Base XTALK device. A pointer to this struct
|
||||
* should be included in the struct representing
|
||||
* the dialect.
|
||||
*/
|
||||
struct xtalk_raw {
|
||||
struct xtalk_base *xtalk_base;
|
||||
};
|
||||
|
||||
CMD_DEF(XTALK, ACK,
|
||||
uint8_t stat;
|
||||
);
|
||||
|
||||
union XTALK_PDATA(XTALK) {
|
||||
MEMBER(XTALK, ACK);
|
||||
} PACKED members;
|
||||
|
||||
const struct xtalk_protocol xtalk_raw_proto = {
|
||||
.name = "XTALK-RAW",
|
||||
.proto_version = 0,
|
||||
.commands = {
|
||||
CMD_RECV(XTALK, ACK),
|
||||
},
|
||||
.ack_statuses = {
|
||||
ACK_STAT(OK, "Acknowledges previous command"),
|
||||
ACK_STAT(FAIL, "Last command failed"),
|
||||
ACK_STAT(RESET_FAIL, "reset failed"),
|
||||
ACK_STAT(NODEST, "No destination is selected"),
|
||||
ACK_STAT(MISMATCH, "Data mismatch"),
|
||||
ACK_STAT(NOACCESS, "No access"),
|
||||
ACK_STAT(BAD_CMD, "Bad command"),
|
||||
ACK_STAT(TOO_SHORT, "Packet is too short"),
|
||||
ACK_STAT(ERROFFS, "Offset error (not used)"),
|
||||
ACK_STAT(NO_LEEPROM, "Large EEPROM was not found"),
|
||||
ACK_STAT(NO_EEPROM, "No EEPROM was found"),
|
||||
ACK_STAT(WRITE_FAIL, "Writing to device failed"),
|
||||
ACK_STAT(NOPWR_ERR, "No power on USB connector"),
|
||||
}
|
||||
};
|
||||
|
||||
struct xtalk_raw *xtalk_raw_new(struct xtalk_base *xtalk_base)
|
||||
{
|
||||
struct xtalk_raw *xtalk_raw;
|
||||
int ret;
|
||||
|
||||
assert(xtalk_base);
|
||||
xtalk_raw = calloc(1, sizeof(*xtalk_raw));
|
||||
if (!xtalk_raw) {
|
||||
ERR("Allocating XTALK device memory failed\n");
|
||||
return NULL;
|
||||
}
|
||||
xtalk_raw->xtalk_base = xtalk_base;
|
||||
ret = xtalk_set_protocol(xtalk_raw->xtalk_base, &xtalk_raw_proto, NULL);
|
||||
if (ret < 0) {
|
||||
ERR("GLOBAL Protocol registration failed: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
DBG("%s: xtalk_raw=%p\n", __func__, xtalk_raw);
|
||||
return xtalk_raw;
|
||||
err:
|
||||
xtalk_raw_delete(xtalk_raw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xtalk_raw_delete(struct xtalk_raw *xtalk_raw)
|
||||
{
|
||||
if (xtalk_raw) {
|
||||
memset(xtalk_raw, 0, sizeof(*xtalk_raw));
|
||||
free(xtalk_raw);
|
||||
}
|
||||
}
|
||||
|
||||
int xtalk_raw_set_protocol(struct xtalk_raw *xtalk_raw,
|
||||
const struct xtalk_protocol *xproto)
|
||||
{
|
||||
return xtalk_set_protocol(xtalk_raw->xtalk_base, &xtalk_raw_proto, xproto);
|
||||
}
|
||||
|
||||
int xtalk_raw_cmd_send(struct xtalk_raw *xtalk_raw, const char *buf, int len,
|
||||
uint16_t *tx_seq)
|
||||
{
|
||||
struct xtalk_command *cmd;
|
||||
char *p;
|
||||
int ret;
|
||||
|
||||
p = malloc(len);
|
||||
if (!p) {
|
||||
ERR("allocation failed (%d bytes)\n", len);
|
||||
return -ENOMEM;
|
||||
}
|
||||
cmd = (struct xtalk_command *)p;
|
||||
memcpy(p, buf, len);
|
||||
cmd->header.len = len;
|
||||
|
||||
ret = send_command(xtalk_raw->xtalk_base, cmd, tx_seq);
|
||||
if (ret < 0) {
|
||||
DBG("%s: send_command(%d bytes) failed ret=%d\n",
|
||||
__func__, len, ret);
|
||||
goto out;
|
||||
}
|
||||
DBG("%s(%d bytes, tx_seq=%d)\n", __func__, len, *tx_seq);
|
||||
out:
|
||||
free(p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
__attribute__((warn_unused_result))
|
||||
int xtalk_raw_cmd_recv(struct xtalk_raw *xtalk_raw,
|
||||
struct xtalk_command **reply_ref)
|
||||
{
|
||||
struct xtalk_base *xtalk_base;
|
||||
const struct xtalk_protocol *xproto;
|
||||
struct xtalk_command *reply = NULL;
|
||||
const struct xtalk_command_desc *reply_desc;
|
||||
const char *protoname;
|
||||
int ret;
|
||||
xtalk_cmd_callback_t callback;
|
||||
|
||||
xtalk_base = xtalk_raw->xtalk_base;
|
||||
xproto = &xtalk_base->xproto;
|
||||
protoname = (xproto) ? xproto->name : "GLOBAL";
|
||||
/* So the caller knows if a reply was received */
|
||||
if (reply_ref)
|
||||
*reply_ref = NULL;
|
||||
ret = recv_command(xtalk_base, &reply);
|
||||
if (ret <= 0) {
|
||||
DBG("%s: failed (xproto = %s, ret = %d)\n",
|
||||
__func__, protoname, ret);
|
||||
goto err;
|
||||
}
|
||||
DBG("REPLY OP: 0x%X\n", reply->header.op);
|
||||
if (debug_mask & DBG_MASK)
|
||||
xtalk_dump_command(reply);
|
||||
/* reply_desc may be NULL (raw reply to application) */
|
||||
reply_desc = get_command_desc(xproto, reply->header.op);
|
||||
if (reply->header.op == XTALK_ACK) {
|
||||
int status = CMD_FIELD(reply, XTALK, ACK, stat);
|
||||
|
||||
if (status != STAT_OK) {
|
||||
ERR("Got NACK(seq=%d): %d %s\n",
|
||||
reply->header.seq,
|
||||
status,
|
||||
ack_status_msg(xproto, status));
|
||||
}
|
||||
/* Good expected ACK ... */
|
||||
}
|
||||
DBG("got reply seq=%d op=0x%X (%d bytes)\n",
|
||||
reply->header.seq,
|
||||
reply->header.op,
|
||||
ret);
|
||||
/* Find if there is associated callback */
|
||||
ret = xtalk_cmd_callback(xtalk_base, reply->header.op, NULL, &callback);
|
||||
if (ret < 0) {
|
||||
ERR("Failed getting callback for op=0x%X\n", reply->header.op);
|
||||
goto err;
|
||||
}
|
||||
if (callback) {
|
||||
/* Override return value with callback return value */
|
||||
ret = callback(xtalk_base, reply_desc, reply);
|
||||
DBG("%s: callback for 0x%X returned %d\n", __func__,
|
||||
reply->header.op, ret);
|
||||
}
|
||||
if (reply_ref)
|
||||
*reply_ref = reply;
|
||||
return 0;
|
||||
err:
|
||||
if (reply)
|
||||
free_command(reply);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xtalk_raw_buffer_send(struct xtalk_raw *xraw, const char *buf, int len)
|
||||
{
|
||||
dump_packet(LOG_DEBUG, DBG_MASK, __func__, buf, len);
|
||||
return send_buffer(xraw->xtalk_base, buf, len);
|
||||
}
|
||||
|
||||
int xtalk_raw_buffer_recv(struct xtalk_raw *xraw, char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = recv_buffer(xraw->xtalk_base, buf, len);
|
||||
if (ret >= 0)
|
||||
dump_packet(LOG_DEBUG, DBG_MASK, __func__, buf, ret);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <xtalk/debug.h>
|
||||
#include <xtalk/xusb.h>
|
||||
#include <xtalk/proto_raw.h>
|
||||
#include <autoconfig.h>
|
||||
|
||||
static char *progname;
|
||||
|
||||
#define DBG_MASK 0x10
|
||||
|
||||
static void usage()
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [options...] -D <device> [hexnum ....]\n",
|
||||
progname);
|
||||
fprintf(stderr, "\tOptions:\n");
|
||||
fprintf(stderr, "\t\t[-v] # Increase verbosity\n");
|
||||
fprintf(stderr,
|
||||
"\t\t[-d mask] # Debug mask (0xFF for everything)\n");
|
||||
fprintf(stderr, "\tDevice:\n");
|
||||
fprintf(stderr, "\t\t/proc/bus/usb/<bus>/<dev>\n");
|
||||
fprintf(stderr, "\t\t/dev/bus/usb/<bus>/<dev>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void xusb_destructor(void *data)
|
||||
{
|
||||
struct xusb_device *xusb_device = data;
|
||||
xusb_destroy(xusb_device);
|
||||
}
|
||||
|
||||
static const struct test_struct {
|
||||
struct xusb_spec spec;
|
||||
int interface_num;
|
||||
} known_devices[] = {
|
||||
{ SPEC_HEAD(0xe4e4, 0x1162, "astribank2-FPGA"), 0 },
|
||||
{{}, 0 },
|
||||
};
|
||||
|
||||
int proto_ack_cb(
|
||||
const struct xtalk_base *xtalk_base,
|
||||
const struct xtalk_command_desc *cmd_desc,
|
||||
struct xtalk_command *cmd)
|
||||
{
|
||||
const char *name = (cmd_desc->name) ? cmd_desc->name : "RAW";
|
||||
|
||||
printf("%s: op=0x%X (%s): len=%d\n", __func__,
|
||||
cmd_desc->op, name, cmd->header.len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Not const, because we override proto_version for testing
|
||||
*/
|
||||
static struct xtalk_protocol xtalk_raw_test_base = {
|
||||
.name = "XTALK_TEST",
|
||||
.proto_version = 0, /* Modified in test_device() */
|
||||
.commands = {
|
||||
},
|
||||
.ack_statuses = {
|
||||
}
|
||||
};
|
||||
|
||||
static int test_device(struct xusb_iface *xusb_iface, int timeout)
|
||||
{
|
||||
struct xtalk_base *xtalk_base = NULL;
|
||||
struct xtalk_raw *xtalk_raw = NULL;
|
||||
struct xtalk_command *reply;
|
||||
uint16_t tx_seq;
|
||||
int ret;
|
||||
|
||||
xtalk_base = xtalk_base_new_on_xusb(xusb_iface);
|
||||
if (!xtalk_base) {
|
||||
ERR("Failed creating the xtalk device abstraction\n");
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
xtalk_raw = xtalk_raw_new(xtalk_base);
|
||||
if (!xtalk_raw) {
|
||||
ERR("Failed creating the xtalk sync device abstraction\n");
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
ret = xtalk_set_timeout(xtalk_base, timeout);
|
||||
INFO("Original timeout=%d, now set to %d\n", ret, timeout);
|
||||
/* override constness for testing */
|
||||
ret = xtalk_raw_set_protocol(xtalk_raw, &xtalk_raw_test_base);
|
||||
if (ret < 0) {
|
||||
ERR("%s Protocol registration failed: %d\n",
|
||||
xtalk_raw_test_base.name, ret);
|
||||
ret = -EPROTO;
|
||||
goto err;
|
||||
}
|
||||
ret = xtalk_cmd_callback(xtalk_base, XTALK_OP(XTALK, ACK), proto_ack_cb, NULL);
|
||||
if (ret < 0) {
|
||||
ERR("%s Callback registration failed: %d\n",
|
||||
xtalk_raw_test_base.name, ret);
|
||||
ret = -EPROTO;
|
||||
goto err;
|
||||
}
|
||||
INFO("Device and Protocol are ready\n");
|
||||
ret = xtalk_raw_cmd_send(xtalk_raw, "abcdef", 6, &tx_seq);
|
||||
if (ret < 0) {
|
||||
ERR("Failed sending raw command: %d\n", ret);
|
||||
ret = -EPROTO;
|
||||
goto err;
|
||||
}
|
||||
do {
|
||||
ret = xtalk_raw_cmd_recv(xtalk_raw, &reply);
|
||||
if (ret < 0) {
|
||||
if (ret == -ETIMEDOUT) {
|
||||
printf("timeout\n");
|
||||
continue;
|
||||
}
|
||||
ERR("Read error (ret=%d)\n", ret);
|
||||
goto err;
|
||||
}
|
||||
assert(reply);
|
||||
printf("Got %d (len=%d)\n", reply->header.op, reply->header.len);
|
||||
} while (1);
|
||||
err:
|
||||
if (xtalk_raw)
|
||||
xtalk_raw_delete(xtalk_raw);
|
||||
if (xtalk_base)
|
||||
xtalk_base_delete(xtalk_base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int run_spec(int i, xusb_filter_t filter, char *devpath, int timeout)
|
||||
{
|
||||
const struct xusb_spec *s = &known_devices[i].spec;
|
||||
int interface_num = known_devices[i].interface_num;
|
||||
struct xlist_node *xlist;
|
||||
struct xlist_node *curr;
|
||||
struct xusb_device *xusb_device;
|
||||
int success = 1;
|
||||
|
||||
if (!s->name)
|
||||
return 0;
|
||||
xlist = xusb_find_byproduct(s, 1, filter, devpath);
|
||||
if (!xlist_length(xlist))
|
||||
return 1;
|
||||
INFO("total %zd devices of type %s\n", xlist_length(xlist), s->name);
|
||||
for (curr = xlist_shift(xlist); curr; curr = xlist_shift(xlist)) {
|
||||
struct xusb_iface *xusb_iface;
|
||||
int ret;
|
||||
|
||||
xusb_device = curr->data;
|
||||
xusb_showinfo(xusb_device);
|
||||
INFO("Testing interface %d\n", interface_num);
|
||||
ret = xusb_claim(xusb_device, interface_num, &xusb_iface);
|
||||
if (ret == 0) {
|
||||
ret = test_device(xusb_iface, timeout);
|
||||
if (ret < 0)
|
||||
success = 0;
|
||||
}
|
||||
xusb_destroy(xusb_device);
|
||||
}
|
||||
xlist_destroy(xlist, xusb_destructor);
|
||||
return success;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *devpath = NULL;
|
||||
const char options[] = "vd:D:EFpt:";
|
||||
xusb_filter_t filter = NULL;
|
||||
int timeout = 500; /* millies */
|
||||
int i;
|
||||
|
||||
progname = argv[0];
|
||||
while (1) {
|
||||
int c;
|
||||
|
||||
c = getopt(argc, argv, options);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'D':
|
||||
devpath = optarg;
|
||||
filter = xusb_filter_bypath;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 't':
|
||||
timeout = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'd':
|
||||
debug_mask = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
ERR("Unknown option '%c'\n", c);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
i = 0;
|
||||
while (run_spec(i, filter, devpath, timeout))
|
||||
i++;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" (C) Copyright 2013 Oron Peled <oron@actcom.co.il>,
|
||||
.\"
|
||||
.TH XTALK_SEND 8 "March 14, 2013"
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
xtalk_send \- send arbitrary packets to XTALK devices
|
||||
.SH SYNOPSIS
|
||||
.B xtalk_send
|
||||
.RI [ options ] " hexnum" ...
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
This manual page documents briefly the \fBxtalk_send\fP command.
|
||||
.PP
|
||||
\fBxtalk_send\fP is a program that send arbitrary packets to Xorcom devices
|
||||
that use the XTALK protocol.
|
||||
.SH OPTIONS
|
||||
A summary of options is included below:
|
||||
.TP
|
||||
.B \-I <iface_num>
|
||||
Specify USB interface number (default 1).
|
||||
.TP
|
||||
.B \-t <timeout>
|
||||
Timeout from send until an answer is received (default 500).
|
||||
.TP
|
||||
.B \-Q
|
||||
Query protocol version. This is only valid for synchronous XTALK protocols.
|
||||
Usually, these protocols are bound to USB interface 1.
|
||||
.TP
|
||||
.B \-h
|
||||
Show summary of options.
|
||||
.TP
|
||||
.B \-v
|
||||
Increase output verbosity.
|
||||
.TP
|
||||
.B \-d <mask>
|
||||
Debug mask. Use 0xFF for everything.
|
||||
.SH AUTHOR
|
||||
Oron Peled <oron@actcom.co.il>
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Written by Oron Peled <oron@actcom.co.il>
|
||||
* Copyright (C) 2008-2011, Xorcom
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <xtalk/debug.h>
|
||||
#include <xtalk/xusb.h>
|
||||
#include <xtalk/proto_sync.h>
|
||||
#include <autoconfig.h>
|
||||
|
||||
#define DBG_MASK 0x80
|
||||
|
||||
static char *progname;
|
||||
static int timeout = 500; /* msec */
|
||||
static int iface_num = 1;
|
||||
|
||||
static void usage()
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [options...] -D <busnum>/<devnum> [hexnum ....]\n",
|
||||
progname);
|
||||
fprintf(stderr, "\tOptions:\n");
|
||||
fprintf(stderr,
|
||||
"\t\t[-I<iface_num>] # Interface number (default %d)\n",
|
||||
iface_num);
|
||||
fprintf(stderr,
|
||||
"\t\t[-t<timeout>] # Timeout (default %d)\n",
|
||||
timeout);
|
||||
fprintf(stderr, "\t\t[-Q] # Query protocol version\n");
|
||||
fprintf(stderr, "\t\t[-v] # Increase verbosity\n");
|
||||
fprintf(stderr,
|
||||
"\t\t[-d mask] # Debug mask (0xFF for everything)\n");
|
||||
fprintf(stderr, "\t\t[-h] # This help\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/***** XTALK Interface *****************************************************/
|
||||
static const struct xtalk_protocol xtalk_protocol = {
|
||||
.name = "XTALK-DERIVED",
|
||||
.proto_version = 0,
|
||||
.commands = {
|
||||
},
|
||||
.ack_statuses = {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/***** XUSB Interface ******************************************************/
|
||||
|
||||
static int sendto_device(struct xusb_iface *iface, int nargs, char *args[])
|
||||
{
|
||||
char *reply = NULL;
|
||||
char *buf = NULL;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
assert(nargs >= 0);
|
||||
if (!nargs)
|
||||
goto out;
|
||||
buf = malloc(nargs);
|
||||
if (!buf) {
|
||||
ERR("Out of memory for %d command bytes\n", nargs);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < nargs; i++) {
|
||||
int val = strtoul(args[i], NULL, 16);
|
||||
printf("%d> 0x%02X\n", i, val);
|
||||
buf[i] = val;
|
||||
}
|
||||
ret = xusb_send(iface, buf, nargs, timeout);
|
||||
if (ret < 0) {
|
||||
ERR("xusb_send failed ret=%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
reply = malloc(PACKET_SIZE);
|
||||
if (!reply) {
|
||||
ERR("Out of memory\n");
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
ret = xusb_recv(iface, reply, PACKET_SIZE, timeout);
|
||||
if (ret < 0) {
|
||||
ERR("Receive from usb failed.\n");
|
||||
goto out;
|
||||
}
|
||||
dump_packet(LOG_INFO, 0, "REPLY", reply, ret);
|
||||
ret = 0;
|
||||
out:
|
||||
if (reply)
|
||||
free(reply);
|
||||
if (buf)
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int show_protocol(struct xtalk_sync *xtalk_sync, struct xusb_iface *iface)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = xtalk_sync_set_protocol(xtalk_sync, &xtalk_protocol);
|
||||
if (ret < 0) {
|
||||
ERR("%s Protocol registration failed: %s\n",
|
||||
xtalk_protocol.name, strerror(-ret));
|
||||
return ret;
|
||||
}
|
||||
ret = xtalk_proto_query(xtalk_sync);
|
||||
if (ret < 0) {
|
||||
ERR("Protocol query error: %s\n", strerror(-ret));
|
||||
return ret;
|
||||
}
|
||||
INFO("usb:%s: Protocol version 0x%X\n", xusb_devpath(xusb_deviceof(iface)), ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *devpath = NULL;
|
||||
struct xusb_device *xusb_device;
|
||||
struct xtalk_base *xtalk_base;
|
||||
struct xtalk_sync *xtalk_sync;
|
||||
struct xusb_iface *iface;
|
||||
const char options[] = "vd:D:t:I:i:o:Q";
|
||||
int query = 0;
|
||||
int ret;
|
||||
|
||||
progname = argv[0];
|
||||
while (1) {
|
||||
int c;
|
||||
|
||||
c = getopt(argc, argv, options);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'D':
|
||||
devpath = optarg;
|
||||
break;
|
||||
case 'I':
|
||||
iface_num = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 't':
|
||||
timeout = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'Q':
|
||||
query++;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'd':
|
||||
debug_mask = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
ERR("Unknown option '%c'\n", c);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if (!devpath) {
|
||||
ERR("Missing device path\n");
|
||||
usage();
|
||||
}
|
||||
xusb_device = xusb_find_bypath(devpath);
|
||||
if (!xusb_device) {
|
||||
ERR("No XUSB device found\n");
|
||||
return 1;
|
||||
}
|
||||
ret = xusb_claim(xusb_device, iface_num, &iface);
|
||||
if (ret < 0) {
|
||||
ERR("Claiming interface #%d failed (ret = %d)\n", iface_num, ret);
|
||||
return 1;
|
||||
}
|
||||
xusb_showinfo(xusb_deviceof(iface));
|
||||
xtalk_base = xtalk_base_new_on_xusb(iface);
|
||||
if (!xtalk_base) {
|
||||
ERR("Failed creating the xtalk device abstraction\n");
|
||||
return 1;
|
||||
}
|
||||
xtalk_sync = xtalk_sync_new(xtalk_base);
|
||||
if (!xtalk_sync) {
|
||||
ERR("Failed creating the xtalk device abstraction\n");
|
||||
return 1;
|
||||
}
|
||||
if (query) {
|
||||
ret = show_protocol(xtalk_sync, iface);
|
||||
if (ret < 0)
|
||||
return 1;
|
||||
}
|
||||
ret = sendto_device(iface, argc - optind, argv + optind);
|
||||
if (ret < 0)
|
||||
ERR("Command failed: %d\n", ret);
|
||||
xtalk_sync_delete(xtalk_sync);
|
||||
xtalk_base_delete(xtalk_base);
|
||||
xusb_destroy(xusb_deviceof(iface));
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue