From 899994f3cf9d5a76fe2b1155c81e1c954f9555d4 Mon Sep 17 00:00:00 2001 From: tzafrir Date: Wed, 31 Jan 2007 20:47:36 +0000 Subject: r2066@boomtime: tzafrir | 2007-01-31 22:19:05 +0200 r2064: tzafrir | 2007-01-31 21:48:39 +0200 zaptel-helper deserves wider exposure. Note: it is not getting installed. However it will probably help preven the braking of Astribank drivers loading for those who do care. git-svn-id: http://svn.digium.com/svn/zaptel/trunk@2070 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/zaptel-helper | 377 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 377 insertions(+) create mode 100755 xpp/zaptel-helper (limited to 'xpp') diff --git a/xpp/zaptel-helper b/xpp/zaptel-helper new file mode 100755 index 0000000..5b17d22 --- /dev/null +++ b/xpp/zaptel-helper @@ -0,0 +1,377 @@ +#!/bin/sh + +# zaptel-helper: helper script/functions for Zaptel . + +# Should be possible to run with -e set. This is also recommended. + +# Constants: +# maximal time (in seconds) to wait for /dev/zap/dtl to appear after +# loading zaptel +DEVZAP_TIMEOUT=${DEVZAP_TIMEOUT:-20} + +# Zaptel modules we'll try when detecting zaptel hardware: +ALL_MODULES="${ALL_MODULES:-zaphfc qozap ztgsm wctdm wctdm24xxp wcfxo wcfxs pciradio tor2 torisa wct1xxp wct4xxp wcte11xp wanpipe wcusb xpp_usb}" + +# Where do we write the list of modules we detected (if at all): +MODLIST_FILE_DEBIAN=${MODLIST_FILE_DEBIAN:-/etc/modules} +MODLIST_FILE_REDHAT=${MODLIST_FILE_REDHAT:-/etc/sysconfig/zaptel} + +# The location of of the fxotune binary +FXOTUNE="${FXOTUNE:-/usr/sbin/fxotune}" +FXOTUNE_CONF="${FXOTUNE_CONF:-/etc/fxotune.conf}" + +ZTCFG="${ZTCFG:-/sbin/ztcfg}" + +# TODO: this may not be appropriate for a general-purpose script. +# However you should not use a direct 'echo' to write output to the user +#, to make it simple to override. +say() { + echo "$@" +} + +error() { + echo >&2 "$@" +} + +die() { + error "$@" + exit 1 +} + + +############################################################################# +##### +##### Init helper functions +##### + + +# Wait for udev to generate /dev/zap/ctl, if needed: +wait_for_zapctl() { + # if device file already exists, or if zaptel has failed to load: + # no point waiting. + if [ -c /dev/zap/ctl ] || ! grep -q zaptel /proc/modules ; then + return + fi + + say "Waiting for /dev/zap/ctl to be generated" + devzap_found=0 + for i in `seq $DEVZAP_TIMEOUT`; do + sleep 1 + if [ -c /dev/zap/ctl ]; then + devzap_found=1 + break + fi + done + if [ "$devzap_found" != 1 ]; then + say "Still no /dev/zap/ctl after $devzap_timeout seconds." + error "No /dev/zap/ctl: cannot run ztcfg. Aborting." + fi +} + +# load the fxotune parameters +# FIXME: /etc/fxotune.conf is a bad location for that file . +# /etc/zaptel/fxotune.conf? +fxotune_load() { + if [ -x "$FXOTUNE" ] && [ -r "FXOTUNE_CONF" ]; then + $FROTUNE -s + fi +} + +# If there is no zaptel timing source, load +# ztdummy. Other modules should have been loaded by +# now. +guarantee_timing_source() { + if ! head -c 0 /dev/zap/pseudo 2>/dev/null + then modprobe ztdummy || true # will fail if there is no module package + fi +} + +kill_zaptel_users() { + fuser -k /dev/zap/* +} + +# recursively unload a module and its dependencies, if possible. +# where's modprobe -r when you need it? +# inputs: module to unload. +# returns: the result from +unload_module() { + module="$1" + line=`lsmod 2>/dev/null | grep "^$1 "` + if [ "$line" = '' ]; then return; fi # module was not loaded + + set -- $line + # $1: the original module, $2: size, $3: refcount, $4: deps list + mods=`echo $4 | tr , ' '` + for mod in $mods; do + # run in a subshell, so it won't step over our vars: + (unload_module $mod) + # TODO: the following is probably the error handling we want: + # if [ $? != 0 ]; then return 1; fi + done + rmmod $module +} + +# sleep a while until the xpp modules fully register +wait_for_xpp() { + if [ -d /proc/xpp ] + then + # wait for the XPDs to register: + # TODO: improve error reporting and produce a messagee here + cat /proc/xpp/XBUS-*/waitfor_xpds 2>/dev/null >/dev/null || true + fi +} + +zap_reg_xpp() { + if [ ! -d /proc/xpp ]; then return; fi + + # Get a list of connected Astribank devices, sorted by the name of + # the USB connector. That order is rather arbitrary, but will not + # change without changes to the cabling. + xbusses=`sort -k 2 /proc/xpp/xbuses | awk -F: '/STATUS=connected/ {print $1}'` + + # get a list of XPDs that were not yet registered as zaptel spans. + # this will be the case if you set the parameter zap_autoreg=0 to + # the module xpp + # Append /dev/null to provide a valid file name in case of an empty pattern. + xbusses_pattern=`echo $xbusses| sed -e 's|XBUS-[0-9]*|/proc/xpp/&/XPD-*/zt_registration|g'`' /dev/null' + xpds_to_register=`grep -l 0 $xbusses_pattern 2>/dev/null` || true + for file in $xpds_to_register; do + echo 1 >$file + done +} + +# Set the sync source of the Astribank to the right value +fix_asterisbank_sync() { + # do nothing if module not present + if [ ! -d /proc/xpp ]; then return; fi + + #if ! grep -q '^HOST' /proc/xpp/sync 2>/dev/null; then return; fi + + case "$XPP_SYNC" in + n*|N*) return;; + host|HOST) sync_value="HOST";; + [0-9]*)sync_value="$XPP_SYNC";; + *) + # find the number of the first bus, and sync from it: + fxo_pat=`awk -F: '/STATUS=connected/{print $1}' /proc/xpp/xbuses | sed -e 's|.*|/proc/xpp/&/*/fxo_info|'` + # find the first FXO unit, and set it as the sync master + bus=`ls -1 $fxo_pat 2> /dev/null | head -n1 | cut -d- -f2 | cut -d/ -f1` + + # do nothing if there is no bus: + case "$bus" in [0-9]*):;; *) return;; esac + sync_value="$bus 0" + ;; + esac + # the built-in echo of bash fails to print a proper error on failure + if ! /bin/echo "$sync_value" >/proc/xpp/sync + then + error "Updating XPP sync source failed (used XPP_SYNC='$XPP_SYNC')" + fi +} + +run_adj_clock() { + if [ "$XPP_RUN_ADJ_CLOCK" = '' ]; then return; fi + + # daemonize adj_clock: + (adj_clock /dev/null 2>&1 &)& +} + +init_astribank() { + wait_for_xpp + zap_reg_xpp + fix_asterisbank_sync + run_adj_clock +} + +xpp_do_blink() { + val="$1" + shift + for xbus in $* + do + for xpd in /proc/xpp/XBUS-"$xbus"/XPD-* + do + echo "$val" > "$xpd/blink" + done + done +} + +xpp_blink() { + xbuses=`grep STATUS=connected /proc/xpp/xbuses | sed -e 's/^XBUS-//' -e 's/:.*$//'` + num=`echo $1 | tr -c -d 0-9` + case "$num" in + [0-9]*) + shift + xpp_do_blink 1 $xbuses + sleep 2 + xpp_do_blink 0 $xbuses + ;; + *) + shift + echo 1>&2 Enumerating $xbuses + xpp_do_blink 0 $xbuses + for i in $xbuses + do + echo "BLINKING: $i" + xpp_do_blink 1 "$i" + sleep 2 + xpp_do_blink 0 "$i" + done + ;; + esac +} + +# The current Debian start function. +# The function is not responsible for loading the zaptel modules: +# they will be loaded beforehand. +debian_start() { + wait_for_xpp + zap_reg_xpp + fix_asterisbank_sync + wait_for_zapctl + + if [ -r /etc/fxotune.conf ] && [ -x $FXOTUNE ]; then + $FXOTUNE -s + fi + + # configure existing modules: + $ZTCFG +} + + +# run_fxotune: destroy all FXO channels and run fxotune. +# This allows running fxotune without completly shutting down Asterisk. +# +# A simplistic assumption: every zaptel channel in the context from-pstn +# is a FXO ones. +# or rather: all tunable FXO channels are in the context from-pstn are +# not defined by zaptel. +run_fxotune() { + xpp_fxo_chans=`cat /proc/zaptel/* | awk '/XPP_FXO/{print $1}'` + for chan in $xpp_fxo_chans; do + asterisk -rx "zap destroy channel $chan" + done + $FXOTUNE + asterisk -rx "zap restart" +} + + +# recursively unload a module and its dependencies, if possible. +# where's modprobe -r when you need it? +# inputs: module to unload. +unload_module() { + set +e + module="$1" + line=`lsmod 2>/dev/null | grep "^$module "` + if [ "$line" = '' ]; then return; fi # module was not loaded + + set -- $line + # $1: the original module, $2: size, $3: refcount, $4: deps list + mods=`echo $4 | tr , ' '` + # xpd_fxs actually sort of depends on xpp: + case "$module" in xpd_*) mods="xpp_usb $mods";; esac + for mod in $mods; do + # run in a subshell, so it won't step over our vars: + (unload_module $mod) + done + rmmod $module || true + set -e +} + +unload() { + unload_module zaptel +} + +# sleep a while until the xpp modules fully register +wait_for_xpp() { + if [ -d /proc/xpp ] && \ + [ "`cat /sys/module/xpp/parameters/zap_autoreg`" = 'Y' ] + then + # wait for the XPDs to register: + # TODO: improve error reporting and produce a messagee here + cat /proc/xpp/XBUS-*/waitfor_xpds 2>/dev/null >/dev/null || true + fi +} + +############################################################################# +##### +##### Hardware detection functions +##### + +load_modules() { + say "Test Loading modules:" + for i in $ALL_MODULES + do + lines_before=`count_proc_zap_lines` + args="${i}_args" + eval "args=\$$args" + # a module is worth listing if it: + # a. loaded successfully, and + # b. added channels lines under /proc/zaptel/* + if /sbin/modprobe $i $args 2> /dev/null + then + check=0 + case "$i" in + xpp_usb) check=`grep 'STATUS=connected' 2>/dev/null /proc/xpp/xbuses | wc -l` ;; + # FIXME: zttranscode will always load, and will never + # add a span. Maybe try to read from /dev/zap/transcode . + zttranscode) : ;; + *) if [ $lines_before -lt `count_proc_zap_lines` ]; then check=1; fi ;; + esac + if [ "$check" != 0 ] + then + probed_modules="$probed_modules $i" + say " ok $i $args" + else + say " - $i $args" + rmmod $i + fi + else + say " - $i $args" + fi + done +} + +update_module_list_debian() { + say "Updating Debian modules list $MODLIST_FILE_DEBIAN." + del_args=`for i in $ALL_MODULES ztdummy + do + echo "$i" | sed s:.\*:-e\ '/^&/d': + done` + add_args=`for i in $* + do + echo "$i" | sed s:.\*:-e\ '\$a&': + done` + + sed -i.bak $del_args "$MODLIST_FILE_DEBIAN" + for i in $* + do + echo "$i" + done >> "$MODLIST_FILE_DEBIAN" +} + +update_module_list_redhat() { + say "Updating modules list in zaptel init config $MODLIST_FILE_REDHAT." + sed -i.bak -e '/^MODULES=/d' "$MODLIST_FILE_REDHAT" + echo "MODULES=\"$*\"" >> "$MODLIST_FILE_REDHAT" +} + +update_module_list() { + if [ -f "$MODLIST_FILE_DEBIAN" ]; then + update_module_list_debian "$@" + elif [ -f "$MODLIST_FILE_REDHAT" ]; then + update_module_list_redhat "$@" + else + die "Can't find a modules list to update. Tried: $MODLIST_FILE_DEBIAN, $MODLIST_FILE_REDHAT. Aborting" + fi +} + + + + + + +# unless we wanted to use this as a set of functions, run +# the given function with its parameters: +if [ "$ZAPHELPER_ONLY_INCLUDE" = '' ]; then + "$@" +fi -- cgit v1.2.3