diff --git a/dahdi.rules b/dahdi.rules new file mode 100644 index 0000000..ef08fd3 --- /dev/null +++ b/dahdi.rules @@ -0,0 +1,3 @@ +# DAHDI devices with ownership/permissions for running as non-root +SUBSYSTEM=="dahdi", OWNER="asterisk", GROUP="asterisk", MODE="0660" +SUBSYSTEM=="dahdi_devices", RUN="/usr/share/dahdi/handle_device" diff --git a/dahdi_map b/dahdi_map new file mode 100755 index 0000000..a95ebae --- /dev/null +++ b/dahdi_map @@ -0,0 +1,39 @@ +#! /bin/sh +# +# Show a map of dahdi devices with the following fields: +# - spanno (or '-' if not assigned yet) +# - (vendor assigned) name +# - local spanno +# - hardware_id (or empty if none) +# - location (prefixed by '@') + +devbase="/sys/bus/dahdi_devices/devices" + +[ -d "$devbase" ] || { + echo >&2 "$0: Missing '$devbase' (Old driver?)" + exit 1 +} + +fmt="%-4s %-17s %-3s %-12s %s\n" + +printf "$fmt" 'SPAN' 'NAME' '#' 'HARDWARE_ID' 'LOCATION' + +DEVICES=`echo $devbase/*` + +for device in $DEVICES +do + hw_id=`cat "$device/hardware_id"` + location=`cd "$device" && pwd -P | sed 's,/sys/devices/,,'` + for local_spanno in `cut -d: -f1 "$device/spantype"` + do + span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \ + sed -e 's,/local_spanno:.*,,' -e 's,.*/,,'` + if [ "$span" != '' ]; then + spanno=`echo $span | sed 's/^.*-//'` + name=`cat 2>/dev/null "$device/$span/name"` + else + spanno='-' + fi + printf "$fmt" "$spanno" "$name" "($local_spanno)" "[$hw_id]" "@$location" + done | sort -n +done diff --git a/doc/dahdi_map.8 b/doc/dahdi_map.8 new file mode 100644 index 0000000..80d5d8f --- /dev/null +++ b/doc/dahdi_map.8 @@ -0,0 +1,48 @@ +.TH dahdi_test 8 "2013-05-24" +.SH "NAME" +dahdi_map \(em List hardware IDs and locations of DAHDI spans +.SH "SYNOPSIS" +.B dahdi_map + +.SH DESCRIPTION +.B dahdi_map +prints a list of hardware IDs and locations of any DAHDI span on the system +(possibly not yet assigned). + +It takes no extra options or parameters. + +Example output: +.EX +SPAN NAME # HARDWARE_ID LOCATION +5 XBUS-00/XPD-00 (1) [usb:INT06380] @pci0000:00/0000:00:10.4/usb1/1-3/xbus-00/astribanks:xbus-00 +6 XBUS-00/XPD-01 (2) [usb:INT06380] @pci0000:00/0000:00:10.4/usb1/1-3/xbus-00/astribanks:xbus-00 +7 XBUS-00/XPD-02 (3) [usb:INT06380] @pci0000:00/0000:00:10.4/usb1/1-3/xbus-00/astribanks:xbus-00 +8 XBUS-00/XPD-03 (4) [usb:INT06380] @pci0000:00/0000:00:10.4/usb1/1-3/xbus-00/astribanks:xbus-00 +9 XBUS-00/XPD-04 (5) [usb:INT06380] @pci0000:00/0000:00:10.4/usb1/1-3/xbus-00/astribanks:xbus-00 +10 XBUS-00/XPD-05 (6) [usb:INT06380] @pci0000:00/0000:00:10.4/usb1/1-3/xbus-00/astribanks:xbus-00 +11 XBUS-00/XPD-06 (7) [usb:INT06380] @pci0000:00/0000:00:10.4/usb1/1-3/xbus-00/astribanks:xbus-00 +12 XBUS-00/XPD-07 (8) [usb:INT06380] @pci0000:00/0000:00:10.4/usb1/1-3/xbus-00/astribanks:xbus-00 +13 XBUS-00/XPD-10 (9) [usb:INT06380] @pci0000:00/0000:00:10.4/usb1/1-3/xbus-00/astribanks:xbus-00 +14 XBUS-00/XPD-20 (10) [usb:INT06380] @pci0000:00/0000:00:10.4/usb1/1-3/xbus-00/astribanks:xbus-00 +15 XBUS-00/XPD-30 (11) [usb:INT06380] @pci0000:00/0000:00:10.4/usb1/1-3/xbus-00/astribanks:xbus-00 +16 XBUS-01/XPD-00 (1) [] @pci0000:00/0000:00:10.4/usb1/1-4/xbus-01/astribanks:xbus-01 +1 XBUS-02/XPD-00 (1) [usb:XILINX_4] @pci0000:00/0000:00:10.4/usb1/1-1/xbus-02/astribanks:xbus-02 +2 XBUS-02/XPD-10 (2) [usb:XILINX_4] @pci0000:00/0000:00:10.4/usb1/1-1/xbus-02/astribanks:xbus-02 +3 XBUS-02/XPD-20 (3) [usb:XILINX_4] @pci0000:00/0000:00:10.4/usb1/1-1/xbus-02/astribanks:xbus-02 +4 XBUS-02/XPD-30 (4) [usb:XILINX_4] @pci0000:00/0000:00:10.4/usb1/1-1/xbus-02/astribanks:xbus-02 +.EE + +.SH FILES +.B /sys/bus/dahdi_devices/devices +.RS +Information taken from that area in SysFS. +.RE + +.SH SEE ALSO +dahdi_cfg(8) + +.SH AUTHOR +This manual page was written by Tzafrir Cohen +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 2 any +later version published by the Free Software Foundation. diff --git a/handle_device b/handle_device new file mode 100755 index 0000000..180a163 --- /dev/null +++ b/handle_device @@ -0,0 +1,41 @@ +#! /bin/sh +# +# /usr/share/dahdi/handle_device +# +# Called by UDEV when a span goes online/offline to assign spans + +me=`basename $0` +dir=`dirname $0` +LOGGER="logger -i -t '$me'" +NAME=`basename "$DEVPATH" | tr -c 'A-Za-z0-9-' '_'` + +# Always redirect stderr somewhere, otherwise the shell script will die +# when it tries to do I/O related stuff on closed file descriptor. +# Our default is to throw it down the bit-bucket. +exec 2> /dev/null +# If you wish to trace this script: +#exec 2> "/tmp/${me}.$NAME" 1>&2 +#exec 2> /dev/console + +# Our directory in the beginning, so we can use local lab setup +PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" + +set -e + +echo >&2 "$0($ACTION): DEBUG($# args): '$*'" + +case "$ACTION" in +add) + echo "$ACTION: $DEVPATH" | $LOGGER + # FIXME: need a way to add custom environment here: + #export DAHDICONFDIR="/tmp/xortel/dahdi" + span_types set "/sys/$DEVPATH" 2>&1 | $LOGGER + span_assignments add "/sys/$DEVPATH" 2>&1 | $LOGGER + ;; +remove) + echo "$ACTION: $DEVPATH" | $LOGGER + ;; +*) + echo "UNHANDLED: $ACTION: $DEVPATH" | $LOGGER + ;; +esac diff --git a/pinned-spans.conf b/pinned-spans.conf new file mode 100644 index 0000000..a9145bb --- /dev/null +++ b/pinned-spans.conf @@ -0,0 +1,56 @@ +# +# /etc/dahdi/pinned-spans.conf: +# +# This file assigns span and channel numbers to dahdi devices +# +# Built as a table keyed by : +# .... +# +# Where: +# * The field may be either: +# hardware_id +# @location +# * Shell-style globbing is allowed for the field +# * There may one or more of +# * Each is composed as: +# :: +# +# Examples: + +# Astribank with two spans: +# FXS * 8 channels + 4 digital inputs 2 digital outputs +# FXO * 8 channels +#usb:QA-1 1:1:1 +#usb:QA-1 2:2:15 + +# Same Astribank in one-liner +#usb:QA-1 1:1:1 2:2:15 + +# Astribank with 4*PRI spans and 3*FXS*8 spans +# Note that channels are NOT globally contigous +# each span get its own 50 numbers. Also, skip +# Channel number 250... +#usb:INT03165 1:1:1 # E1 +#usb:INT03165 2:2:51 # E1 +#usb:INT03165 3:3:151 # E1 +#usb:INT03165 4:4:201 # E1 +#usb:INT03165 5:5:301 # FXS * 8 channels +#usb:INT03165 6:6:351 # FXS * 8 channels +#usb:INT03165 7:7:401 # FXS * 8 channels + +# Alternatively -- all in one-line +#usb:INT03165 1:1:1 2:2:51 3:3:151 4:4:201 5:5:301 6:6:351 7:7:401 + +# Astribank with 4*BRI without hardware_id :-( +# We use the location on the bus (ie: where it is physically +# located). Note the '@' prefix that indicate the location key. +#@pci0000:00/0000:00:03.3/usb1/1-6/xbus-01/astribanks:xbus-01 1:1:50 +#@pci0000:00/0000:00:03.3/usb1/1-6/xbus-01/astribanks:xbus-01 2:2:100 +#@pci0000:00/0000:00:03.3/usb1/1-6/xbus-01/astribanks:xbus-01 3:3:150 +#@pci0000:00/0000:00:03.3/usb1/1-6/xbus-01/astribanks:xbus-01 4:4:200 + +# Same configuration with globbing: +#@*/usb1/1-6/* 1:1:50 +#@*/usb1/1-6/* 2:2:100 +#@*/usb1/1-6/* 3:3:150 +#@*/usb1/1-6/* 4:4:200 diff --git a/span_assignments b/span_assignments new file mode 100755 index 0000000..0f4e006 --- /dev/null +++ b/span_assignments @@ -0,0 +1,193 @@ +#! /bin/sh +# +# /usr/share/dahdi/span_assignments: +# +# this script can be used both from udev and +# from the command line to assign/unassign and list +# current assignments. +# +# The first argument is an action: +# "add" to assign (spans which are not already assigned) +# "remove" to unassign (spans which are not already unassigned) +# "list" to show all spans (with/without assignments) +# +# Without further arguments, it operates on all existing spans +# With one or more sysfs dahdi_devices it is limited to those. +# +# Examples: +# span_assignments list +# span_assignments add # all +# span_assignments add /sys/bus/dahdi_devices/devices/astribanks:xbus-00 +# span_assignments remove # all +# + +devbase='/sys/bus/dahdi_devices/devices' +DAHDICONFDIR="${DAHDICONFDIR:-/etc/dahdi}" +pinned_spans_conf="$DAHDICONFDIR/pinned-spans.conf" + +usage() { + echo >&2 "Usage: $0 {add|remove|list} [devpath ...]" + exit 1 +} + +if [ "$#" -eq 0 ]; then + usage +fi +action="$1" +shift + +if [ ! -d "$devbase" ]; then + echo >&2 "$0: Missing '$devbase' (DAHDI driver unloaded?)" + exit 1 +fi + +# Use given devices or otherwise, all existing devices +if [ "$#" -gt 0 ]; then + DEVICES="$@" +else + DEVICES=`echo $devbase/*` +fi + +show_devices() { + + for device in $DEVICES + do + hw_id=`cat "$device/hardware_id"` + location=`cd "$device" && pwd -P | sed 's,/sys/devices/,,'` + for local_spanno in `cut -d: -f1 "$device/spantype"` + do + span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \ + sed -e 's,/local_spanno:.*,,' -e 's,.*/,,'` + if [ "$span" != '' ]; then + spanno=`echo $span | sed 's/^.*-//'` + name=`cat 2>/dev/null "$device/$span/name"` + basechan=`cat 2>/dev/null "$device/$span/basechan"` + else + spanno='-' + basechan='-' + fi + printf "%-4s %-12s %s\n" "$local_spanno:$spanno:$basechan" "[$hw_id]" "@$location" + done | sort -n + done +} + +dump_config() { + + for device in $DEVICES + do + hw_id=`cat "$device/hardware_id"` + location=`cd "$device" && pwd -P | sed 's,/sys/devices/,,'` + if [ "$hw_id" != '' ]; then + id="$hw_id" + else + id="@$location" + fi + for local_spanno in `cut -d: -f1 "$device/spantype"` + do + span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \ + sed -e 's,/local_spanno:.*,,' -e 's,.*/,,'` + if [ "$span" != '' ]; then + spanno=`echo $span | sed 's/^.*-//'` + name=`cat 2>/dev/null "$device/$span/name"` + basechan=`cat 2>/dev/null "$device/$span/basechan"` + else + spanno='-' + fi + printf "%-30s %s\n" "$id" "$local_spanno:$spanno:$basechan" + done | sort -n + done +} + +unassign_all_spans() { + for device in $DEVICES + do + find "$device" -follow -maxdepth 1 -name 'span-*' -type d | \ + sort | while read spandir; do + local_spanno=`cat "$spandir/local_spanno"` + echo "unassign $device $local_spanno" + if ! echo "$local_spanno" > "$device/unassign_span"; then + echo >&2 "$0: failed unassigning '$local_spanno' in '$device'" + fi + done + done +} + +# Allow comments and empty lines in config file +filter_conf() { + sed -e 's/#.*//' -e '/^[ \t]*$/d' "$pinned_spans_conf" +} + +# Beware of special characters in attributes +attr_clean() { + cat "$1" | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_' +} + +assign_device_spans() { + device="$1" + for s in $spanspecs + do + local_spanno=`echo "$s" | cut -d: -f1` + spanno=`echo "$s" | cut -d: -f2` + span="$device/span-$spanno" + 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" + fi + echo "$device [$local_spanno] already assigned to $spanno. Skipping..." + continue + fi + echo "assign $device: $s" + if ! echo "$s" > "$device/assign_span"; then + echo >&2 "$0: failed assigning '$s' to '$device'" + fi + done +} + +match_device() { + device="$1" + location='@'`cd "$device" && pwd -P | sed 's,/sys/devices/,,'` + hardware_id=`attr_clean "$device/hardware_id"` + filter_conf | while read id spanspecs + do + # We use case to enable shell-style globbing in configuration + case "$location" in + $id) + #echo "match location($id ~ $location): $spanspecs" + assign_device_spans "$device" + ;; + esac + # We use case to enable shell-style globbing in configuration + case "$hardware_id" in + $id) + #echo "match hardware_id([$id] ~ $hardware_id): $spanspecs" + assign_device_spans "$device" + ;; + esac + done +} + +assign_devices() { + for device in $DEVICES + do + match_device "$device" + done +} + +case "$action" in +list) + show_devices + ;; +dump) + dump_config + ;; +add) + assign_devices + ;; +remove) + unassign_all_spans + ;; +*) + usage + ;; +esac diff --git a/span_types b/span_types new file mode 100755 index 0000000..cf7c70d --- /dev/null +++ b/span_types @@ -0,0 +1,160 @@ +#! /bin/sh +# +# /usr/share/dahdi/span_types: +# +# this script can be used both from udev and +# from the command line for spantype management. +# +# It use a configuration file /etc/dahdi/spantype.conf +# (the format is documented inside this file) +# +# The first argument is an action: +# "list" to show existing E1/T1/J1 types +# "dump" the same, but in a format (almost) suitable for +# the configuration file +# FIXME: we currently don't have the base channo in sysfs. +# "set" actually write the setting to the driver +# +# Examples: +# span_types list +# span_types dump +# span_types set # all +# span_types set /sys/bus/dahdi_devices/devices/astribanks:xbus-00 +# + + +devbase='/sys/bus/dahdi_devices/devices' +DAHDICONFDIR="${DAHDICONFDIR:-/etc/dahdi}" +spantype_conf="$DAHDICONFDIR/spantype.conf" + +usage() { + echo >&2 "Usage: $0 {list|dump|set} [devpath ...]" + exit 1 +} + +if [ "$#" -eq 0 ]; then + usage +fi +action="$1" +shift + +# Use given devices or otherwise, all existing devices +if [ "$#" -gt 0 ]; then + DEVICES="$@" +else + DEVICES=`echo $devbase/*` +fi + +show_spantypes() { + for device in $DEVICES + do + hw_id=`cat "$device/hardware_id"` + location='@'`cd "$device" && pwd -P | sed 's,/sys/devices/,,'` + cat "$device/spantype" | while read st; do + printf "%-10s %-20s %s\n" "$st" "[$hw_id]" "$location" + done | sort -n + done +} + +dump_config() { + fmt="%-65s %s\n" + echo "# Map of dahdi_devices to span types for E1/T1/J1" + printf "$fmt" '# @location/hardware_id' 'span_type' + for device in $DEVICES + do + hw_id=`cat "$device/hardware_id"` + location='@'`cd "$device" && pwd -P | sed 's,/sys/devices/,,'` + if [ -n "$hw_id" ]; then + id="$hw_id" + else + id="$location" + fi + cat "$device/spantype" | while read st; do + case "$st" in + *:[ETJ]1) + printf "$fmt" "$id" "$st" + ;; + esac + done | sort -n + done +} + +# Allow comments and empty lines in config file +filter_conf() { + sed -e 's/#.*//' -e '/^[ \t]*$/d' "$spantype_conf" +} + +conf_spans() { + hw_id="$1" + location="$2" + filter_conf | ( + # Collect device spans + # in a subshell, so $SPANS is not lost + SPANS='' + while read id spans; do + # GLOBBING + case "$location" in + $id) + #echo >&2 "match($id): $spans" + SPANS="$SPANS $spans" + ;; + esac + case "$hw_id" in + $id) + #echo >&2 "match([$id]): $spans" + SPANS="$SPANS $spans" + ;; + esac + done + echo "$SPANS" + ) +} + +# Beware of special characters in attributes +attr_clean() { + cat "$1" | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_' +} + +device_set_spantype() { + device="$1" + attr_file="$device/spantype" + hw_id=`attr_clean "$device/hardware_id"` + location='@'`cd "$device" && pwd -P | sed 's,/sys/devices/,,'` + spanspecs=`conf_spans "$hw_id" "$location"` + echo >&2 "MATCHED($device): $spanspecs" + cut -d: -f1 "$attr_file" | while read spanno; do + for sp in $spanspecs + do + s=`echo "$sp" | cut -d: -f1` + v=`echo "$sp" | cut -d: -f2` + case "$spanno" in + $s) + #echo >&2 "conf($attr_file): $spanno:$v" + echo "$spanno:$v" > "$attr_file" + ;; + esac + done + done +} + +set_spantypes() { + for device in $DEVICES + do + device_set_spantype "$device" + done +} + +case "$action" in +list) + show_spantypes + ;; +dump) + dump_config + ;; +set) + set_spantypes + ;; +*) + usage + ;; +esac diff --git a/spantype.conf b/spantype.conf new file mode 100644 index 0000000..e639fe5 --- /dev/null +++ b/spantype.conf @@ -0,0 +1,27 @@ +# +# /etc/dahdi/spantype.conf: Set E1/T1/J1 per-device +# +# Built as a table of two columns: +# : +# +# Where: +# * The field may be either: +# hardware_id +# @location +# * The is the relative span number +# in the device (starting from 1) +# In this filed globbing rules apply. E.g: +# - * are all the spans in this device +# - [12] are the first two spans in this device +# * The may be E1, T1 or J1 +# +# Examples: +# Set the first two spans of a specific Astribank to T1 +#usb:000156 [12]:T1 + +# Set all spans of another Astribank to T1 +#usb:INT03165 *:E1 + +# Set the first two spans of an Astribank to T1. The +# Astribanks is specified by its location instead of hardware_id +#@pci0000:00/0000:00:03.3/usb1/1-5/xbus-01/astribanks:xbus-01 [12]:T1