dahdi_span_types: allow defaults + overrides
[dahdi/tools.git] / dahdi_span_types
1 #! /bin/sh
2 #
3 # /usr/sbin/dahdi_span_types
4 #
5 # This script can be used both from udev and
6 # from the command line to manage PRI spans
7 # type (E1/T1/J1).
8 #
9 # Span types can be set only *BEFORE* span are assigned.
10 #
11 # It uses a configuration file: $DAHDICONFDIR/span-types.conf
12 # (default DAHDICONFDIR=/etc/dahdi)
13 # (the format is documented inside that file)
14 #
15 # The first argument is an action:
16 #   "set"        - actually write the setting to the driver
17 #   "list"       - human-readable list of E1/T1/J1 types
18 #   "dumpconfig" - dump current assignments in a /etc/dahdi/span-types.conf
19 #                  compatible format
20 #
21 # Without further arguments, it operates on all existing spans
22 # With one or more sysfs dahdi_devices it is limited to those.
23 #
24 # We may use alternative "keys" for device matching:
25 # * Available keys:
26 #   - "hwid"       - Hardware id attribute from sysfs
27 #   - "@location"  - Location attribute from sysfs (embeded inside '<>')
28 #   - "/devpath"   - The sysfs absolute devpath
29 #
30 # * Wildcard are allowed in the configuration file:
31 #   - In the device specifiers (keys)
32 #   - In the span numbers
33 #   - Example for "match-all":    *   *:T1
34 #
35 # * During "set":
36 #   - If there are multiple matches, for a span, all are applied
37 #   - They are always applied in their order in the configuration file
38 #   - This means the last match wins
39 #   - Example:
40 #         *                   *:T1        # All span on all devices are T1
41 #         usb:X1234567        [34]:E1      # Except spans 3,4 on specific device
42 #
43 # * During "dumpconfig", for each device we take the first available key:
44 #   - The preference is: "hwid" or else "@location" or else "/devpath"
45 #   - This can be overriden via the SPAN_ASSIGNMENTS_KEY environment variable
46 #     or the '{-k|--key} key' command line option.
47 #
48 # Command line options:
49 #  - The '-h|--help' show a usage message.
50 #  - The '-v|--verbose' show debugging messages (on stderr)
51 #  - The '-n|--dry-run' During "set", only show what would be done
52 #  - The '-k <key>|--key <key>' overrides the SPAN_ASSIGNMENTS_KEY environment
53 #    variable.
54 #
55 # Examples:
56 #    dahdi_span_types list
57 #    dahdi_span_types set            # all devices
58 #    dahdi_span_types set /sys/bus/dahdi_devices/devices/astribanks:xbus-00
59 #    dahdi_span_types -k location dumpconfig
60 #
61
62
63 devbase='/sys/bus/dahdi_devices/devices'
64 DAHDICONFDIR="${DAHDICONFDIR:-/etc/dahdi}"
65 DAHDISPANTYPESCONF="${DAHDISPANTYPESCONF:-"${DAHDICONFDIR}/span-types.conf"}"
66 SPAN_ASSIGNMENTS_KEY=${SPAN_ASSIGNMENTS_KEY:-hwid}
67
68 usage() {
69         echo >&2 "Usage: $0 [options] action [devpath ...]"
70         echo >&2 "       action:"
71         echo >&2 "         set        - set spans to E1/T1 according to /etc/dahdi/span-types.conf"
72         echo >&2 "         list       - human-readable list of all spans"
73         echo >&2 "         dumpconfig - dump current state in /etc/dahdi/span-types.conf format"
74         echo >&2 ""
75         echo >&2 "       options:"
76         echo >&2 "         -h|--help      - Show this help"
77         echo >&2 "         -v|--verbose'  - Show debugging messages (on stderr)"
78         echo >&2 "         -n|--dry-run'  - During 'set', only show what would be done"
79         echo >&2 "         -k|--key <k>   - Override prefered key during dumpconfig action"
80         exit 1
81 }
82
83 # Parse command line options
84 TEMP=`getopt -o hnvk: --long help,dry-run,verbose,key: -n "$0" -- "$@"`
85 if [ $? != 0 ]; then
86         echo >&2 "Bad options"
87         usage
88 fi
89
90 # Note the quotes around `$TEMP': they are essential!
91 eval set -- "$TEMP"
92
93 while true ; do
94         case "$1" in
95         -h|--help)
96                 usage
97                 ;;
98         -n|--dry-run)
99                 shift
100                 dry_run=true
101                 ;;
102         -v|--verbose)
103                 shift
104                 verbose=true
105                 ;;
106         -k|--key)
107                 SPAN_ASSIGNMENTS_KEY="$2"
108                 shift
109                 shift
110                 ;;
111         --)
112                 shift
113                 break
114                 ;;
115         *)
116                 echo "Internal error!"
117                 exit 1
118                 ;;
119         esac
120 done
121
122 if [ "$#" -eq 0 ]; then
123         echo >&2 "Missing action argument"
124         usage
125 fi
126 action="$1"
127 shift
128
129 # Validate SPAN_ASSIGNMENTS_KEY
130 case "$SPAN_ASSIGNMENTS_KEY" in
131 hwid|location|devpath)
132         ;;
133 *)
134         echo >&2 "Bad SPAN_ASSIGNMENTS_KEY='$SPAN_ASSIGNMENTS_KEY' (should be: hwid|location|devpath)"
135         usage
136         ;;
137 esac
138
139 if [ ! -d "$devbase" ]; then
140         echo >&2 "$0: Missing '$devbase' (DAHDI driver unloaded?)"
141         exit 1
142 fi
143
144 # Use given devices or otherwise, all existing devices
145 if [ "$#" -gt 0 ]; then
146         DEVICES="$@"
147 else
148         DEVICES=`ls -d $devbase/* 2>/dev/null`
149 fi
150
151 # Beware of special characters in attributes
152 attr_clean() {
153         cat "$1" | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_'
154 }
155
156 show_spantypes() {
157         echo "# PRI span types (E1/T1/J1)"
158         for device in $DEVICES
159         do
160                 devpath=`cd "$device" && pwd -P`
161                 location='@'`attr_clean "$device/location"`
162                 hardware_id=`attr_clean "$device/hardware_id"`
163                 cat "$device/spantype" | while read st; do
164                         case "$st" in
165                         *:[ETJ]1)
166                                 printf "%-10s %-20s %-30s %s\n" \
167                                         "$st" "[$hardware_id]" "$location" \
168                                         "$devpath"
169                                 ;;
170                         esac
171                 done
172         done
173 }
174
175 dump_config() {
176         echo '#'
177         echo "# Autogenerated by $0 on `date`"
178         echo "# Map PRI DAHDI devices to span types for E1/T1/J1"
179         echo ''
180         fmt="%-65s %s\n"
181         printf "$fmt" '# @location/hardware_id' 'span_type'
182         for device in $DEVICES
183         do
184                 devpath=`cd "$device" && pwd -P`
185                 location=`attr_clean "$device/location"`
186                 hardware_id=`attr_clean "$device/hardware_id"`
187                 if [ "$SPAN_ASSIGNMENTS_KEY" = 'hwid' -a "$hardware_id" != '' ]; then
188                         id="$hardware_id"
189                 elif [ "$SPAN_ASSIGNMENTS_KEY" = 'location' -a "$location" != '' ]; then
190                         id="@$location"
191                 else
192                         id="$devpath"
193                 fi
194                 echo "# Device: [$hardware_id] @$location $devpath"
195                 cat "$device/spantype" | while read st; do
196                         case "$st" in
197                         *:[ETJ]1)
198                                 printf "$fmt" "$id" "$st"
199                                 ;;
200                         *)
201                                 #echo "#    Skipped local span `echo $st | sed 's/:/ -- /'`"
202                                 ;;
203                         esac
204                 done | sort -n
205                 #echo ''
206         done
207 }
208
209 # Allow comments and empty lines in config file
210 filter_conf() {
211         sed -e 's/#.*//' -e '/^[ \t]*$/d' "$DAHDISPANTYPESCONF"
212 }
213
214 handle_span() {
215         device="$1"
216         spantype="$2"
217         attr_file="$device/spantype"
218         devpath=`cd "$device" && pwd -P`
219         devname=`echo "$device" | sed "s,$devbase/,,"`
220         location='@'`attr_clean "$device/location"`
221         hardware_id=`attr_clean "$device/hardware_id"`
222         spanno=`echo "$spantype" | cut -d: -f1`
223         #echo >&2 "DEBUG: $device $spanno ($spantype)"
224         filter_conf | while read id span_spec; do
225                         sn=`echo "$span_spec" | cut -d: -f1`
226                         val=`echo "$span_spec" | cut -d: -f2`
227                         case "$spanno" in
228                         $sn)
229                                 ;;
230                         *)
231                                 #echo >&2 "no-match($device $spanno): $sn"
232                                 continue
233                                 ;;
234                         esac
235                         found=no
236                         # GLOBBING
237                         case "$location" in
238                         $id)
239                                 #echo >&2 "match($id): $span_spec"
240                                 found=yes
241                                 ;;
242                         esac
243                         case "$hardware_id" in
244                         $id)
245                                 #echo >&2 "match([$id]): $span_spec"
246                                 found=yes
247                                 ;;
248                         esac
249                         case "$devpath" in
250                         $id)
251                                 #echo >&2 "match([$id]): $span_spec"
252                                 found=yes
253                                 ;;
254                         esac
255                         if [ "$found" = 'yes' ]; then
256                                 if [ "$dry_run" = 'true' -o "$verbose" = 'true' ]; then
257                                         echo >&2 "Set $devname span $spanno = $val"
258                                 fi
259                                 if [ "$dry_run" != 'true' ]; then
260                                         echo "$spanno:$val" > "$attr_file"
261                                 fi
262                         fi
263                 done
264 }
265
266 set_all_devices() {
267         if [ ! -f "$DAHDISPANTYPESCONF" ]; then
268                 echo >&2 "$0: Missing configuration '$DAHDISPANTYPESCONF'"
269                 exit 1
270         fi
271         for device in $DEVICES
272         do
273                 devname=`echo "$device" | sed "s,$devbase/,,"`
274                 cat "$device/spantype" | while read spantype; do
275                         case "$spantype" in
276                         *:[ETJ]1)
277                                 handle_span "$device" "$spantype"
278                                 ;;
279                         *)
280                                 if [ "$dry_run" = 'true' -o "$verbose" = 'true' ]; then
281                                         echo >&2 "Skipping non-E1/T1/J1 span ($devname -- $spantype)"
282                                 fi
283                                 ;;
284                         esac
285                 done
286         done
287 }
288
289 case "$action" in
290 list)
291         show_spantypes
292         ;;
293 dumpconfig)
294         dump_config
295         ;;
296 set)
297         set_all_devices
298         ;;
299 *)
300         usage
301         ;;
302 esac