auto_assign_spans may be true even if not '1'
[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         echo >&2 "         --line-mode <m> - Set default line mode to <m> (E1/T1/J1)"
81         exit 1
82 }
83
84 # Parse command line options
85 TEMP=`getopt -o hnvk: --long help,dry-run,verbose,key:,line-mode: -n "$0" -- "$@"`
86 if [ $? != 0 ]; then
87         echo >&2 "Bad options"
88         usage
89 fi
90
91 # Note the quotes around `$TEMP': they are essential!
92 eval set -- "$TEMP"
93
94 while true ; do
95         case "$1" in
96         -h|--help)
97                 usage
98                 ;;
99         -n|--dry-run)
100                 shift
101                 dry_run=true
102                 ;;
103         -v|--verbose)
104                 shift
105                 verbose=true
106                 ;;
107         -k|--key)
108                 SPAN_ASSIGNMENTS_KEY="$2"
109                 shift
110                 shift
111                 ;;
112         --line-mode)
113                 DEFAULT_LINE_MODE="$2"
114                 shift
115                 shift
116                 ;;
117         --)
118                 shift
119                 break
120                 ;;
121         *)
122                 echo "Internal error!"
123                 exit 1
124                 ;;
125         esac
126 done
127
128 if [ "$#" -eq 0 ]; then
129         echo >&2 "Missing action argument"
130         usage
131 fi
132 action="$1"
133 shift
134
135 # Validate SPAN_ASSIGNMENTS_KEY
136 case "$SPAN_ASSIGNMENTS_KEY" in
137 hwid|location|devpath)
138         ;;
139 *)
140         echo >&2 "Bad --key='$SPAN_ASSIGNMENTS_KEY' (should be: hwid|location|devpath)"
141         usage
142         ;;
143 esac
144
145 # Validate DEFAULT_LINE_MODE
146 case "$DEFAULT_LINE_MODE" in
147 E1|T1|J1|'')
148         ;;
149 *)
150         echo >&2 "Bad --line-mode='$DEFAULT_LINE_MODE' (should be: E1|T1|J1)"
151         usage
152         ;;
153 esac
154
155 if [ ! -d "$devbase" ]; then
156         echo >&2 "$0: Missing '$devbase' (DAHDI driver unloaded?)"
157         exit 1
158 fi
159
160 # Use given devices or otherwise, all existing devices
161 if [ "$#" -gt 0 ]; then
162         DEVICES="$@"
163 else
164         DEVICES=`ls -d $devbase/* 2>/dev/null`
165 fi
166
167 # Beware of special characters in attributes
168 attr_clean() {
169         cat "$1" 2>/dev/null | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_'
170 }
171
172 show_spantypes() {
173         echo "# PRI span types (E1/T1/J1)"
174         for device in $DEVICES
175         do
176                 devpath=`cd "$device" && pwd -P`
177                 location='@'`attr_clean "$device/location"`
178                 hardware_id=`attr_clean "$device/hardware_id"`
179                 cat "$device/spantype" | while read st; do
180                         case "$st" in
181                         *:[ETJ]1)
182                                 printf "%-10s %-20s %-30s %s\n" \
183                                         "$st" "[$hardware_id]" "$location" \
184                                         "$devpath"
185                                 ;;
186                         esac
187                 done
188         done
189 }
190
191 dump_config() {
192         echo '#'
193         echo "# Autogenerated by $0 on `date`"
194         echo "# Map PRI DAHDI devices to span types for E1/T1/J1"
195         if [ "$DEFAULT_LINE_MODE" != '' ]; then
196                 echo "# Was run with '--line-mode=$DEFAULT_LINE_MODE' -- so will:"
197                 echo "#     * Generate default wildcard entry"
198                 echo "#     * Generate commented-out device list (for overrides)"
199         fi
200         echo ''
201         fmt="%-65s %s\n"
202         printf "$fmt" '# @location/hardware_id' 'span_type'
203
204         if [ "$DEFAULT_LINE_MODE" != '' ]; then
205                 echo ""
206                 echo "# Wildcard line-mode $DEFAULT_LINE_MODE".
207                 printf "$fmt" "*" "*:$DEFAULT_LINE_MODE"
208                 echo ""
209                 echo "# A list of commented out configurations for spans."
210                 echo "# Each item may be un-commented to provide an override."
211                 echo ""
212         fi
213         for device in $DEVICES
214         do
215                 devpath=`cd "$device" && pwd -P`
216                 location=`attr_clean "$device/location"`
217                 hardware_id=`attr_clean "$device/hardware_id"`
218                 if [ "$SPAN_ASSIGNMENTS_KEY" = 'hwid' -a "$hardware_id" != '' ]; then
219                         id="$hardware_id"
220                 elif [ "$SPAN_ASSIGNMENTS_KEY" = 'location' -a "$location" != '' ]; then
221                         id="@$location"
222                 else
223                         id="$devpath"
224                 fi
225                 echo "# Device: [$hardware_id] @$location $devpath"
226                 cat "$device/spantype" | while read st; do
227                         case "$st" in
228                         *:[ETJ]1)
229                                 if [ "$DEFAULT_LINE_MODE" != '' ]; then
230                                         printf "#$fmt" "$id" "$st"
231                                 else
232                                         printf "$fmt" "$id" "$st"
233                                 fi
234                                 ;;
235                         *)
236                                 #echo "#    Skipped local span `echo $st | sed 's/:/ -- /'`"
237                                 ;;
238                         esac
239                 done | sort -n
240                 #echo ''
241         done
242 }
243
244 # Allow comments and empty lines in config file
245 filter_conf() {
246         sed -e 's/#.*//' -e '/^[ \t]*$/d' "$DAHDISPANTYPESCONF"
247 }
248
249 handle_span() {
250         device="$1"
251         spantype="$2"
252         attr_file="$device/spantype"
253         devpath=`cd "$device" && pwd -P`
254         devname=`echo "$device" | sed "s,$devbase/,,"`
255         location='@'`attr_clean "$device/location"`
256         hardware_id=`attr_clean "$device/hardware_id"`
257         spanno=`echo "$spantype" | cut -d: -f1`
258         #echo >&2 "DEBUG: $device $spanno ($spantype)"
259         filter_conf | while read id span_spec; do
260                         sn=`echo "$span_spec" | cut -d: -f1`
261                         val=`echo "$span_spec" | cut -d: -f2`
262                         case "$spanno" in
263                         $sn)
264                                 ;;
265                         *)
266                                 #echo >&2 "no-match($device $spanno): $sn"
267                                 continue
268                                 ;;
269                         esac
270                         found=no
271                         # GLOBBING
272                         case "$location" in
273                         $id)
274                                 #echo >&2 "match($id): $span_spec"
275                                 found=yes
276                                 ;;
277                         esac
278                         case "$hardware_id" in
279                         $id)
280                                 #echo >&2 "match([$id]): $span_spec"
281                                 found=yes
282                                 ;;
283                         esac
284                         case "$devpath" in
285                         $id)
286                                 #echo >&2 "match([$id]): $span_spec"
287                                 found=yes
288                                 ;;
289                         esac
290                         if [ "$found" = 'yes' ]; then
291                                 if [ "$dry_run" = 'true' -o "$verbose" = 'true' ]; then
292                                         echo >&2 "Set $devname span $spanno = $val"
293                                 fi
294                                 if [ "$dry_run" != 'true' ]; then
295                                         echo "$spanno:$val" > "$attr_file"
296                                 fi
297                         fi
298                 done
299 }
300
301 set_all_devices() {
302         if [ ! -f "$DAHDISPANTYPESCONF" ]; then
303                 echo >&2 "$0: Missing configuration '$DAHDISPANTYPESCONF'"
304                 exit 1
305         fi
306         for device in $DEVICES
307         do
308                 devname=`echo "$device" | sed "s,$devbase/,,"`
309                 cat "$device/spantype" | while read spantype; do
310                         case "$spantype" in
311                         *:[ETJ]1)
312                                 handle_span "$device" "$spantype"
313                                 ;;
314                         *)
315                                 if [ "$dry_run" = 'true' -o "$verbose" = 'true' ]; then
316                                         echo >&2 "Skipping non-E1/T1/J1 span ($devname -- $spantype)"
317                                 fi
318                                 ;;
319                         esac
320                 done
321         done
322 }
323
324 case "$action" in
325 list)
326         show_spantypes
327         ;;
328 dumpconfig)
329         dump_config
330         ;;
331 set)
332         set_all_devices
333         ;;
334 *)
335         usage
336         ;;
337 esac