#
# Makefile for Zaptel driver modules and utilities
#
# Copyright (C) 2001-2007 Digium, Inc.
#
#

CFLAGS+=-DSTANDALONE_ZAPATA -DBUILDING_TONEZONE

ifeq ($(MAKELEVEL),0)
PWD:=$(shell pwd)
endif

ifndef MACHINE
  MACHINE	:=$(shell uname -m)
endif
# FIXME: this variable sets ARCH in the kernel Makefile.
ARCH		:=$(shell echo $(MACHINE) | sed -e s/i.86/i386/)

# If you want to build for a kernel other than the current kernel, set KVERS
ifndef KVERS
KVERS:=$(shell uname -r)
endif
ifndef KSRC
  ifneq (,$(wildcard /lib/modules/$(KVERS)/build))
    KSRC:=/lib/modules/$(KVERS)/build
  else
    KSRC_SEARCH_PATH:=/usr/src/linux-2.4 /usr/src/linux
    KSRC:=$(shell for dir in $(KSRC_SEARCH_PATH); do if [ -d $$dir ]; then echo $$dir; break; fi; done)
  endif
endif
KINCLUDES:=$(KSRC)/include

ifeq (2.6,$(shell echo $(KVERS) | cut -d. -f1-2))
  BUILDVER:=linux26
else
  BUILDVER:=linux24
endif

# Set HOTPLUG_FIRMWARE=no to override automatic building with hotplug support
# if it is enabled in the kernel.
ifeq ($(BUILDVER),linux26)
  ifneq (,$(wildcard $(DESTDIR)/etc/udev/rules.d))
    DYNFS=yes
    UDEVRULES=yes
  endif
  HOTPLUG_FIRMWARE:=$(shell if grep CONFIG_FW_LOADER $(KINCLUDES)/linux/autoconf.h | grep -q undef; then echo "no"; else echo "yes"; fi)
else
  # Hotplug firmware loading is not supported on any other version then 2.6
  HOTPLUG_FIRMWARE:=no
endif

ifeq ($(HOTPLUG_FIRMWARE),yes)
  CFLAGS+=-DHOTPLUG_FIRMWARE
endif

MODULES:=zaptel tor2 torisa wcusb wcfxo wctdm \
	 ztdynamic ztd-eth wct1xxp wcte11xp pciradio \
         ztd-loc wcte12xp # ztdummy
#MODULES+=wcfxsusb
ifeq ($(BUILDVER),linux26)
MODULES+=ztdummy zttranscode
endif

# for building extra modules in this directory without editing the
# Makefiles:
# running:  make MODULES_EXTRA="mod1 mod2" SUBDIRS_EXTRA="subdir1/ subdir2/"
# "subdir/" only works with kernel 2.6.
MODULES+=$(MODULES_EXTRA)

MODULE_ALIASES=wcfxs wctdm8xxp wct2xxp

MODULESO:=$(MODULES:%=%.o)
MODULESKO:=$(MODULES:%=%.ko)

ifeq ($(BUILDVER),linux26)
MODULESO+=$(SUBDIRS_EXTRA:%=%/)
endif

# add this later, so it doesn't become part of MODULESO/MODULESKO
MODULES+=wct4xxp wctc4xxp wctdm24xxp

ifeq ($(ARCH),i386)
ifneq ($(wildcard $(PWD)/hpec/hpec_x86_32.o_shipped),)
HPEC_PRESENT=yes
endif
endif

ifeq ($(ARCH),x86_64)
ifneq ($(wildcard $(PWD)/hpec/hpec_x86_64.o_shipped),)
HPEC_PRESENT=yes
endif
endif

MOD_DESTDIR:=zaptel

#NOTE NOTE NOTE
#
# all variables set before the include of Makefile.kernel26 are needed by the 2.6 kernel module build process

ifneq ($(KBUILD_EXTMOD),)

include $(src)/Makefile.kernel26

else

HOSTCC=gcc

INSTALL_PREFIX	:= /usr

CFLAGS+=-I. -O4 -g -fPIC -Wall
ifneq (,$(findstring ppc,$(MACHINE)))
  CFLAGS	+= -fsigned-char
  KFLAGS	+= -msoft-float -fsigned-char
endif
ifneq (,$(findstring x86_64,$(MACHINE)))
  CFLAGS	+= -m64
  KFLAGS	+= -mcmodel=kernel
endif
KFLAGS:=-I$(KINCLUDES) -O6
KFLAGS+=-DMODULE -D__KERNEL__ -DEXPORT_SYMTAB -I$(KSRC)/drivers/net \
	-Wall -I. -Wstrict-prototypes -fomit-frame-pointer -I$(KSRC)/drivers/net/wan -I$(KINCLUDES)/net
ifneq (,$(wildcard $(KINCLUDES)/linux/modversions.h))
  KFLAGS+=-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h
endif

#
# Features are now configured in zconfig.h
#

KFLAGS+=-DSTANDALONE_ZAPATA
KMAKE:= $(MAKE) -C $(KSRC) SUBDIRS=$(PWD)
KMAKE_INST:= $(KMAKE) INSTALL_MOD_PATH=$(DESTDIR) INSTALL_MOD_DIR=misc modules_install

CONFIG_FILE:=/etc/zaptel.conf
CFLAGS+=-DZAPTEL_CONFIG=\"$(CONFIG_FILE)\"

ifeq ($(BUILDVER),linux24)
#We only support DEVFS in linux 2.4 kernels, since its considered obsolete post 2.4
DYNFS:=$(shell ps ax | grep -v grep | grep -q devfsd && echo "yes")
endif

# Utilities we build with a standard build procedure:
UTILS		= tor2ee zttool zttest ztmonitor ztspeed sethdlc-new ztcfg \
		  ztcfg-dude usbfxstest fxstest fxotune ztdiag torisatool

# Makefile mentions them. Source is not included (anynore?)
UTILS		+= fxsdump ztprovision

# some tests:
UTILS		+= patgen pattest patlooptest hdlcstress hdlctest hdlcgen \
		   hdlcverify timertest

UTILSO		= $(UTILS:%=%.o)

# sample makefile "trace print"
#tracedummy=$(shell echo ====== GOT HERE ===== >&2; echo >&2)

CHKCONFIG	:= $(wildcard /sbin/chkconfig)
UPDATE_RCD	:= $(wildcard /usr/sbin/update-rc.d)
ifeq (,$(DESTDIR))
  ifneq (,$(CHKCONFIG))
    ADD_INITD	:= $(CHKCONFIG) --add zaptel
  else
    ifndef (,$(UPDATE_RCD))
      ADD_INITD	:= $(UPDATE_RCD) zaptel defaults 15 30
    endif
  endif
endif

INITRD_DIR	:= $(firstword $(wildcard /etc/rc.d/init.d /etc/init.d))
ifneq (,$(INITRD_DIR))
  INIT_TARGET	:= $(DESTDIR)$(INITRD_DIR)/zaptel
  COPY_INITD	:= install -D zaptel.init $(INIT_TARGET)
endif
RCCONF_DIR	:= $(firstword $(wildcard /etc/sysconfig /etc/default))

NETSCR_DIR	:= $(firstword $(wildcard /etc/sysconfig/network-scripts ))
ifneq (,$(NET_SCR_DIR))
  NETSCR_TARGET	:= $(DESTDIR)$(NETSCR_DIR)/ifup-hdlc
  COPY_NETSCR	:= install -D ifup-hdlc $(NETSCR_TARGET)
endif

SELINUX_ENABLED	:= $(shell  [ -x /usr/sbin/sestatus ] && (/usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"))

ifneq ($(wildcard .version),)
  ZAPTELVERSION:=$(shell cat .version)
else
ifneq ($(wildcard .svn),)
  ZAPTELVERSION=SVN-$(shell build_tools/make_svn_branch_name)
endif
endif

TZOBJS:=zonedata.lo tonezone.lo
LIBTONEZONE_SO:=libtonezone.so
LIBTONEZONE_SO_MAJOR_VER:=1
LIBTONEZONE_SO_MINOR_VER:=0

LIBDIR			:= $(INSTALL_PREFIX)/lib
INCLUDE_DIR		:= $(INSTALL_PREFIX)/include
# Note: Zaptel's use of /sbin is slightly non-standard:
SBINDIR			:= /sbin
# No better default. If INSTALL_PREFIX != /usr, I'm not sure 
# where the man page sit. So they need to be manually overriden anyway.
MANDIR			= /usr/share/man/man8
MODS_DIR		:= /lib/modules/$(KVERS)/misc
BINS=ztcfg torisatool ztmonitor ztspeed zttest fxotune
ifneq (,$(wildcard $(INCLUDE_DIR)/newt.h))
BINS+=zttool
endif
MAN_PAGES		= $(wildcard $(BINS:%=doc/%.8))

ASCIIDOC		:= asciidoc

all: programs modules

programs: utils libs

utils: $(BINS)

libs: $(LIBTONEZONE_SO)

ifeq ($(BUILDVER),linux24)
modules: prereq $(MODULESO) wct4xxp/wct4xxp.o wctdm24xxp/wctdm24xxp.o
else
modules: prereq
ifeq (,$(wildcard $(KSRC)/.config))
	@echo "You do not appear to have the sources for the $(KVERS) kernel installed (under $(KSRC))."; exit 1
endif
	$(MAKE) -C $(KSRC) SUBDIRS=$(PWD) HOTPLUG_FIRMWARE=$(HOTPLUG_FIRMWARE) modules
endif

ifeq ($(HPEC_PRESENT),yes)
ifeq ($(ARCH),i386)
ZAPTEL_HPEC:=hpec/hpec_x86_32.o_shipped
endif

ifeq ($(ARCH),x86_64)
ZAPTEL_HPEC:=hpec/hpec_x86_64.o_shipped
endif

KFLAGS+=-DECHO_CAN_HPEC -I$(PWD)/hpec
zaptel-base.o: hpec/hpec_zaptel.h hpec/hpec_user.h
endif

version.h: FORCE
	@ZAPTELVERSION="${ZAPTELVERSION}" build_tools/make_version_h > $@.tmp
	@if cmp -s $@.tmp $@ ; then echo; else \
		mv $@.tmp $@ ; \
	fi
	@rm -f $@.tmp

wct4xxp/wct4xxp.o:
	$(MAKE) -C wct4xxp KFLAGS="$(KFLAGS) -I.." CFLAGS="$(CFLAGS) -I.."

wctdm24xxp/wctdm24xxp.o:
	$(MAKE) -C wctdm24xxp KFLAGS="$(KFLAGS) -I.." CFLAGS="$(CFLAGS) -I.."

devel: tor2ee 

tests: patgen pattest patlooptest hdlcstress hdlctest hdlcgen hdlcverify timertest
	$(MAKE) -C wctc4xxp tests CFLAGS="$(CFLAGS) -I.."

$(MODULESO): zaptel.h

tor2.o: tor2-hw.h tor2fw.h

zaptel-base.o: digits.h arith.h sec.h sec-2.h mec.h mec2.h mec3.h mg2ec.h kb1ec.h zconfig.h version.h tones.h

torisa.o: torisa.h

wcusb.o: wcusb.h

wcfxsusb.o: wcfxsusb.h

wctdm.o: wctdm.h

pciradio.o: radfw.h

ztdummy.o: ztdummy.h

zaptel.o: zaptel-base.o $(ZAPTEL_HPEC)
	$(LD) -r -o $@ $< $(ZAPTEL_HPEC)

$(filter-out zaptel.o,$(MODULESO)) zaptel-base.o: %.o: %.c
	$(CC) $(KFLAGS) -o $@ -c $<

zonedata.lo tonezone.lo: %.lo: %.c
	$(CC) -c $(CFLAGS) -o $@ $^

tones.h: gendigits
	./gendigits > $@

tor2fw.h: makefw tormenta2.rbt
	./makefw tormenta2.rbt tor2fw > tor2fw.h

radfw.h: makefw pciradio.rbt
	./makefw pciradio.rbt radfw > radfw.h

gendigits makefw: %: %.c
	$(HOSTCC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

$(UTILS): %: %.o
	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

$(UTILSO): %.o: %.c
	$(CC) $(CFLAGS) -c $<

gendigits: LDFLAGS+=-lm

prereq: tones.h tor2fw.h radfw.h version.h

zttool.o: zttool.c zaptel.h
zttool: LDFLAGS+=-lnewt

tor2ee.o: tor2-hw.h
tor2ee: LDFLAGS+=-lpci

ztprovision.o: ztprovision.c zaptel.h

ztmonitor.o: ztmonitor.c zaptel.h

# make sure it is not optimized:
ztspeed.o: CFLAGS=
ztspeed: CFLAGS=

sethdlc-new.o: CFLAGS+=-I$(KINCLUDES)

libtonezone.a: $(TZOBJS)
	ar rcs libtonezone.a $^

$(LIBTONEZONE_SO): $(TZOBJS)
	$(CC) $(CFLAGS) -shared -Wl,-soname,$(LIBTONEZONE_SO).$(LIBTONEZONE_SO_MAJOR_VER).$(LIBTONEZONE_SO_MINOR_VER) -o $@ $^ $(LDFLAGS) -lm

ztcfg.c: ztcfg.h

ztcfg-shared: ztcfg.o $(LIBTONEZONE_SO)
	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lm

ztcfg: ztcfg.o libtonezone.a
ztcfg: LDFLAGS+=-lm

ztcfg-dude: LDFLAGS+=-lm -lstdc++
ztcfg-dude: ztcfg-dude.o mknotch.o complex.o $(LIBTONEZONE_SO)

# FIXME: we assume CC can build the C++ modules:
complex.o mknotch.o: %.o: %.cc
	$(CC) $(CFLAGS) -o $@ -c $<

usbfxstest: LDFLAGS+=-lzap

fxstest: fxstest.o $(LIBTONEZONE_SO)
fxstest: LDFLAGS+=-lm

fxotune: LDFLAGS+=-lm

fxsdump: LDFLAGS+=-lm

stackcheck: checkstack all
	./checkstack *.ko */*.ko

README.html: README
	$(ASCIIDOC) -n -a toc $<

xpp/README.Astribank.html: xpp/README.Astribank
	cd $(@D); $(ASCIIDOC) -o $(@F) -n -a toc $(<F)

devices:
ifndef DYNFS
	mkdir -p $(DESTDIR)/dev/zap
	rm -f $(DESTDIR)/dev/zap/ctl
	rm -f $(DESTDIR)/dev/zap/channel
	rm -f $(DESTDIR)/dev/zap/pseudo
	rm -f $(DESTDIR)/dev/zap/timer
	rm -f $(DESTDIR)/dev/zap/transcode
	rm -f $(DESTDIR)/dev/zap/253
	rm -f $(DESTDIR)/dev/zap/252
	rm -f $(DESTDIR)/dev/zap/251
	rm -f $(DESTDIR)/dev/zap/250
	mknod $(DESTDIR)/dev/zap/ctl c 196 0
	mknod $(DESTDIR)/dev/zap/transcode c 196 250
	mknod $(DESTDIR)/dev/zap/timer c 196 253
	mknod $(DESTDIR)/dev/zap/channel c 196 254
	mknod $(DESTDIR)/dev/zap/pseudo c 196 255
	N=1; \
	while [ $$N -lt 250 ]; do \
		rm -f $(DESTDIR)/dev/zap/$$N; \
		mknod $(DESTDIR)/dev/zap/$$N c 196 $$N; \
		N=$$[$$N+1]; \
	done
else # DYNFS
  ifdef UDEVRULES
	install -d $(DESTDIR)/etc/udev/rules.d
	build_tools/genudevrules > $(DESTDIR)/etc/udev/rules.d/zaptel.rules
  else # !UDEVRULES
	@echo "**** Dynamic filesystem detected -- not creating device nodes"
  endif
endif

b410p:
	@wget -V >/dev/null || (echo "You need wget in order to install the drivers" ; false)
	[ -f misdn-b410p.tar.gz ] || wget http://downloads.digium.com/pub/zaptel/b410p/misdn-b410p.tar.gz
	tar -zxf misdn-b410p.tar.gz
	$(MAKE) -C misdn install
	[ -f mISDNuser.tar.gz ] || wget http://downloads.digium.com/pub/zaptel/b410p/mISDNuser.tar.gz
	tar -zxf mISDNuser.tar.gz
	$(MAKE) -C mISDNuser install

install: all devices install-modules install-programs firmware
	@echo "###################################################"
	@echo "###"
	@echo "### Zaptel 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-include

install-utils: utils
	install -d $(DESTDIR)$(SBINDIR)
	install -m 755 $(BINS) $(DESTDIR)$(SBINDIR)
ifneq (,$(wildcard sethdlc-new))
	install -D -m 755 sethdlc-new $(DESTDIR)$(SBINDIR)/sethdlc
else
  ifneq (,$(wildcard sethdlc))
	install -D -m 755 sethdlc $(DESTDIR)$(SBINDIR)/sethdlc
  endif
endif
	install -d                  $(DESTDIR)$(MANDIR)
	install -m 644 $(MAN_PAGES) $(DESTDIR)$(MANDIR)
ifeq (,$(wildcard $(DESTDIR)$(CONFIG_FILE)))
	install -D -m 644 zaptel.conf.sample $(DESTDIR)$(CONFIG_FILE)
endif

# Pushing those two to a separate target that is not used by default:
install-modconf:
	build_tools/genmodconf $(BUILDVER) "$(DESTDIR)" "$(filter-out zaptel ztdummy zttranscode wctc4xxp ztdynamic xpp_usb,$(MODULES)) $(MODULE_ALIASES)"
ifeq (,$(DESTDIR))
	@if [ -d /etc/modutils ]; then \
		/sbin/update-modules ; \
	fi
endif


# Specific to a kernel version:
install-modules: modules
ifeq ($(BUILDVER),linux26)
	for x in $(MODULESKO); do \
		rm -f $(DESTDIR)/lib/modules/$(KVERS)/extra/$$x ; \
	done
	$(KMAKE_INST)
else
	install -d $(DESTDIR)$(MODS_DIR)
	install -m 644 $(MODULESO) wct4xxp/wct4xxp.o $(DESTDIR)$(MODS_DIR)
	install -m 644 $(MODULESO) wctdm24xxp/wctdm24xxp.o $(DESTDIR)$(MODS_DIR)
endif
ifeq (,$(wildcard wcfxsusb.o))
	rm -f $(DESTDIR)$(MODS_DIR)/wcfxsusb.o
endif
	rm -f $(DESTDIR)$(MODS_DIR)/wcfxs.o
	[ `id -u` = 0 ] && /sbin/depmod -a $(KVERS) || :

install-libs: libs
	install -D -m 755 $(LIBTONEZONE_SO) $(DESTDIR)$(LIBDIR)/$(LIBTONEZONE_SO).$(LIBTONEZONE_SO_MAJOR_VER).$(LIBTONEZONE_SO_MINOR_VER)
	[ `id -u` = 0 ] && /sbin/ldconfig || :
	rm -f $(DESTDIR)$(LIBDIR)/$(LIBTONEZONE_SO)
	ln -sf $(LIBTONEZONE_SO).$(LIBTONEZONE_SO_MAJOR_VER).$(LIBTONEZONE_SO_MINOR_VER) \
		$(DESTDIR)$(LIBDIR)/$(LIBTONEZONE_SO).$(LIBTONEZONE_SO_MAJOR_VER)
	ln -sf $(LIBTONEZONE_SO).$(LIBTONEZONE_SO_MAJOR_VER).$(LIBTONEZONE_SO_MINOR_VER) \
		$(DESTDIR)$(LIBDIR)/$(LIBTONEZONE_SO)
	install -d $(DESTDIR)$(INCLUDE_DIR)
	install -m 644 tonezone.h $(DESTDIR)$(INCLUDE_DIR)
ifneq (,$(SELINUX_ENABLED))
	/sbin/restorecon -v $(DESTDIR)$(LIBDIR)/$(LIBTONEZONE_SO)
endif

install-include: zaptel.h torisa.h
	install -d $(DESTDIR)$(INCLUDE_DIR)/linux
	install -m 644 zaptel.h torisa.h $(DESTDIR)$(INCLUDE_DIR)/linux/

install-udev: devices

# FIRMWARE_DIR also implies HOTPLUG_FIRMWARE, unless set manually.
firmware:
ifeq ($(HOTPLUG_FIRMWARE),yes)
	if [ -d $(DESTDIR)/usr/lib/hotplug/firmware ]; then \
		install -m 644 wct4xxp/*.ima wctc4xxp/*.bin $(DESTDIR)/usr/lib/hotplug/firmware; \
		install -m 644 wctdm24xxp/*.bin $(DESTDIR)/usr/lib/hotplug/firmware; \
	fi
	if [ -d $(DESTDIR)/lib/firmware ]; then \
		install -m 644 wct4xxp/*.ima wctc4xxp/*.bin $(DESTDIR)/lib/firmware; \
		install -m 644 wctdm24xxp/*.bin $(DESTDIR)/lib/firmware; \
	fi
	@echo "Installed firmware"
else
	@echo "Not installing firmware because we are not using hotplug firmware"
endif

config:
ifneq (,$(COPY_INITD))
	$(COPY_INITD)
endif
ifneq (,$(RCCONF_DIR))
  ifeq (,$(wildcard $(DESTDIR)$(RCCONF_DIR)/zaptel))
	install -D -m 644 zaptel.sysconfig $(DESTDIR)$(RCCONF_DIR)/zaptel
  endif
endif
ifneq (,$(COPY_NETSCR))
	$(COPY_NETSCR)
endif
ifneq (,$(ADD_INITD))
	$(ADD_INITD)
endif
	@echo "Zaptel has been configured."
	@echo ""
	@echo "If you have any zaptel hardware it is now recommended to "
	@echo "edit /etc/default/zaptel or /etc/sysconfig/zaptel and set there an "
	@echo "optimal value for the variable MODULES ."
	@echo ""
	@echo "I think that the zaptel hardware you have on your system is:"
	@xpp/utils/zaptel_hardware || true


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

clean:
	rm -f torisatool makefw tor2fw.h radfw.h
	rm -f $(BINS)
	rm -f patgen pattest patlooptest hdlcstress hdlctest hdlcgen hdlcverify timertest
	rm -f *.o ztcfg tzdriver sethdlc sethdlc-new
	rm -f $(TZOBJS) $(LIBTONEZONE_SO) *.lo
	$(MAKE) -C $(KSRC) SUBDIRS=$(PWD) clean
	$(MAKE) -C wct4xxp clean
	$(MAKE) -C wctc4xxp clean
	$(MAKE) -C wctdm24xxp clean
	rm -rf .tmp_versions
	rm -f gendigits tones.h
	rm -f libtonezone*
	rm -f tor2ee
	rm -f fxotune
	rm -f core
	rm -f ztcfg-shared fxstest
	rm -rf misdn*
	rm -rf mISDNuser*
	rm -rf README.html xpp/README.Astribank.html

.EXPORT_ALL_VARIABLES:

FORCE:

endif

