summaryrefslogtreecommitdiff
path: root/xpp
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-11-06 21:18:42 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-11-06 21:18:42 +0000
commit4953605453a7f7f1da8c70c4c12a4b557cfc2c24 (patch)
tree0d1bd64cb09f75bf0c7aca3b17820738965a0f77 /xpp
parent1148b31f800c4a280c9a26592a18d4478afc1a82 (diff)
r1557@boole: tzafrir | 2006-11-06 20:12:16 +0200
Merging xpp driver release 1.2 (rev. 2569), originally team/tzafrir/xpp_1.2 * Should build well. Almost final. * genzaptelconf: Also work when zap_autoreg=0 * README.Astribank updated for rev. 1.2. * xpp/utils/Makefile: Use $< with cc -c * Get xpp/utils configuration from autoconf (without changesin top dir) git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1563 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp')
-rw-r--r--xpp/Makefile16
-rw-r--r--xpp/README.Astribank326
-rwxr-xr-xxpp/calibrate_slics167
-rw-r--r--xpp/card_fxo.c548
-rw-r--r--xpp/card_fxo.h11
-rw-r--r--xpp/card_fxs.c593
-rw-r--r--xpp/card_fxs.h16
-rw-r--r--xpp/card_global.c149
-rw-r--r--xpp/card_global.h10
-rw-r--r--xpp/firmwares/FPGA_1151.hex576
-rw-r--r--xpp/firmwares/FPGA_FXS.hex (renamed from xpp/utils/FPGA_FXS.hex)0
-rw-r--r--xpp/firmwares/LICENSE.firmware (renamed from xpp/LICENSE.firmware)0
-rw-r--r--xpp/firmwares/README19
-rw-r--r--xpp/firmwares/USB_1130.hex (renamed from xpp/utils/USB_1130.hex)0
-rw-r--r--xpp/firmwares/USB_1150.hex308
-rwxr-xr-xxpp/init_card_3_23165
-rwxr-xr-xxpp/init_card_4_23143
-rw-r--r--xpp/init_data_3_19.cmd170
-rw-r--r--xpp/init_data_3_20.cmd173
-rw-r--r--xpp/init_data_4_19.cmd69
-rw-r--r--xpp/init_data_4_20.cmd64
-rwxr-xr-xxpp/initialize_registers77
-rw-r--r--xpp/slic.c176
-rw-r--r--xpp/slic.h81
-rw-r--r--xpp/utils/Makefile50
-rw-r--r--xpp/utils/USB_8613.hex301
-rw-r--r--xpp/utils/adj_clock.8144
-rw-r--r--xpp/utils/adj_clock.c228
-rwxr-xr-xxpp/utils/genzaptelconf268
-rw-r--r--xpp/utils/genzaptelconf.8184
-rw-r--r--xpp/utils/xpp_fxloader16
-rw-r--r--xpp/utils/xpp_fxloader.usermap4
-rw-r--r--xpp/xbus-core.c106
-rw-r--r--xpp/xbus-core.h6
-rw-r--r--xpp/xdefs.h15
-rw-r--r--xpp/xpd.h7
-rw-r--r--xpp/xpp_usb.c33
-rw-r--r--xpp/xpp_zap.c136
-rw-r--r--xpp/xpp_zap.h2
-rw-r--r--xpp/xproto.c46
-rw-r--r--xpp/xproto.h83
41 files changed, 3168 insertions, 2318 deletions
diff --git a/xpp/Makefile b/xpp/Makefile
index 3ecfdd9..bef84cf 100644
--- a/xpp/Makefile
+++ b/xpp/Makefile
@@ -1,9 +1,15 @@
-EXTRA_CFLAGS = -I$(SUBDIRS) -DDEBUG -DPOLL_DIGITAL_INPUTS -DWITH_ECHO_SUPPRESSION # -DSOFT_RING
+EXTRA_CFLAGS = -g3 -I$(SUBDIRS) -DDEBUG -DPOLL_DIGITAL_INPUTS -DWITH_ECHO_SUPPRESSION # -DSOFT_RING
-obj-m = xpp.o xpp_usb.o xpd_fxs.o xpd_fxo.o
-xpp-y += xbus-core.o xpp_zap.o xproto.o card_global.o
-xpd_fxs-y += card_fxs.o slic.o
-xpd_fxo-y += card_fxo.o slic.o
+obj-m += xpp.o xpd_fxs.o xpd_fxo.o
+
+# Build only supported modules
+ifneq (,$(filter y m,$(CONFIG_USB)))
+obj-m += xpp_usb.o
+endif
+
+xpp-y += xbus-core.o xpp_zap.o xproto.o card_global.o
+xpd_fxs-y += card_fxs.o
+xpd_fxo-y += card_fxo.o
ctags:
ctags *.[ch]
diff --git a/xpp/README.Astribank b/xpp/README.Astribank
index f6f995c..e45bde9 100644
--- a/xpp/README.Astribank
+++ b/xpp/README.Astribank
@@ -9,30 +9,20 @@ installing Zaptel with some additions.
Building drivers:
""""""""""""""""
-From the toplevel zaptel directory run a command similar to (I used line
-continuation to prevent line wrapping):
-
- $ make \
- KSRC=/usr/src/kernel-headers-2.6.12-1-386 \
- KVERS=2.6.12-1-386 \
- XPPMOD=xpp/ \
- EC_TYPE=CAN_KB1
-
- - The KSRC= points to a configured kernel source tree.
- - The KVERS= should match the relevant tree version.
- - The XPPMOD= instructs the Zaptel Makefile to descend into the xpp/
- subdirectory. The slash (/) in the end is mandatory.
- - The EC_TYPE= select the echo canceler.
-
-Building firmware utilities:
-"""""""""""""""""""""""""""
-Then you should compile the firmware loading utilities. Simply go
-to the zaptel/xpp/utils and run make.
-
-Those who don't use prepackaged drivers should make sure they also
-install the (externally available) fxload utility.
-
-Installation:
+Unlike earlier versions, the Astribank driver (xpp) will now build
+automatically. To build the drivers follow the usual Zaptel
+documentation. E.g: run:
+
+ make
+
+in the top-level directory.
+
+Next you will need to build the user-space tools needed for loading the
+firmware and initialization files for the Astribank:
+
+ make -C xpp/utils
+
+INSTALLATION:
""""""""""""
apart from the standard 'make install' in the zaptel directory,
@@ -45,7 +35,7 @@ Alternatively, do the following manually:
All firmware files should be copied to a new directory:
/usr/share/zaptel/
-The xpp_fxloader and xpp_fxloader.usbmap should be copied to:
+The xpp_fxloader and xpp_fxloader.usermap should be copied to:
/etc/hotplug/usb/
In addition, the file xpp/xpp_modprobe contains optional modprobe settings.
@@ -55,48 +45,242 @@ It may be copied verbatim into /etc/modprobe.conf or (better) copied to
Note that loading through udev is not yet provided. Run
- /etc/hotplug/usb/xpp_fxloader xppdetect
+ /etc/hotplug/usb/xpp_fxloader load
to load firmware.
+The FXS calibration script requires the perl module Time::HiRes. This
+modules is already packaged for most distributions including Debian, Fedora,
+RedHat and CentOS. To test for the existance of this module run:
+ perl -MTime::HiRes -e ''
-Loading Firmware Details:
-""""""""""""""""""""""""
-The Astribank needs a firmware loaded into it. Without the firmware,
-the device will appear in lsusb with vendor ID 04b4 and product ID 8613
-The firmware is provided in the Intel hex format. It can be loaded using
-the program fxload, which is typically part of the package 'fxload' or
-'hotplug-utils' .
+This should run cleanly (without output) if the module exists and issue
+a long error message otherwise. At least in RedHat, CentOS and Fedora-2
+until Fedora-5 it is in a package named perl-Time-HiRes. In Debian and
+Fedora-6 it is bundled with perl.
-To load the firmware automatically using the standard hotplug script,
-place xpp/utils/xpp_fxloader and xpp/utils/xpp_fxloader.usermap in
-/etc/hotplug/usb and place xpp/utils/*.hex in /usr/share/zaptel .
-Alternatively, xpp_fxloader when given the parameter 'xppdetect' will load
-the firmwares from /usr/share/zaptel/ . You can use it to load the
-firmware manually.
+DEVICE STARTUP:
+""""""""""""""
-You should then get in lsusb the vendor ID e4e4 and device ID 2121
-(those IDs are temporary and likely to change in upcoming versions).
-Once there is such a device, the xpp_usb driver should load
-automatically on hot-plugging. In fact, you may find it simpler to
-disconnect and reconnect the device than running 'modprobe xpp_usb'.
+Terminology:
+"""""""""""
+Some technical terms that are used throughout the document and in the
+driver / zaptel . Only used in the technical parts.
+span:
+Zaptel breaks the channels it knows bout to logical units called
+"spans". A port in a E1/T1/ISDN card is usually a span. So is a complete
+analog card. You can see the list of spans as the list of files under
+/proc/zaptel or the list in zttool.
-The driver has been separated into several modules: xpp.ko, xpd_fxs.ko and
-xpp_usb.ko . Generally you only need to modprobe xpp_usb, and it should also
-be loaded by hotplug when you connect the Astribank. However in order for it
-to load xpd_fks.ko correctly
+XBUS:
+A funny way to call an Astribank device.
-Refer to the instructions for Zaptel. After our small patches were applies,
-you get xpp.ko which is basically yet another zaptel driver, like wcfxo
-and wctdm.
+XPD:
+This is basically a logical unit of the Astribank. It will be registered to
+Zaptel as a single span. This will basically be 8 analog channels.
+
+
+Loading Firmware:
+""""""""""""""""
+Normally this is done using the script xpp_fxloader.If it works fine,
+you don't need to bother reading this section.
+Once the firmware is loaded the USB ID of the Astribank changes to e4e4
+1132, and the driver can pick it up. You'll also see the top led lit.
+
+First and foremost: the simplest and most useful tool to debug problems
+here is lsusb. The output of lsusb should show exactly if the device is
+connected and if its firmware is loaded.
+
+The firmware files are named *.hex. The are in the Intel hex format
+(read: plain text, but not readable) that is copied at install time from
+xpp/utils to /usr/share/zaptel .
+
+The Astribank needs a firmware loaded into it. Without the firmware,
+the device will appear in lsusb with vendor ID e4e4 and product ID 1130.
+The firmware is loaded in two stages. In the first stage we load the
+"USB" firmware using the program fxload. After the first stage the USB
+ID is e4e4 1131. In the second stage we load the "FPGA" firmware.
+
+The first is done using the the program fxload. To load it manually, use
+the command:
+
+ fxload -t fx2 -D /proc/bus/usb/MMM/NNN -I /usr/share/zaptel/USB_1130.hex
+
+fxload is standard program that is typically part of the package 'fxload'
+or 'hotplug-utils' . /proc/bus/usb is the mount point of the USB
+file-system (usbfs). MMM is the first number (bus number) and NNN is the
+second number (device number) you see for the device in lsusb, with full
+3 digits. If the load is successful, the device disconnects and
+reconnects with USB product ID 1131 (and a new device number).
+
+The second-stage loader is done using the program fpga_load, which is
+built in the directory xpp/utils and installed to /usr/sbin/fpga_load .
+Its syntax is based on fxload. To load with it manually, use:
+
+ fpga_load -D /proc/bus/usb/MMM/NNN -I /usr/share/zaptel/FPGA_FXS.hex
+
+Note that as the device has reconnected, it now has a new device
+number. So you need to re-check the value of NNN with lsusb. Typically
+this will be the old value + 1.
+
+
+Firmware Loading with UDEV:
+""""""""""""""""""""""""""
+Firmware loading with udev should work but is not installed
+automatically, yet. See the comments in the beginning of the script
+/etc/hotplug/usb/xpp_fxloader .
+
+Loading The Modules:
+"""""""""""""""""""
+Here is what should happen:
+In short: you should plug it or have it plugged at boot time, and all
+the modules should load. You will see xpp_usb , xpd_fxs and possibly
+xpd_fxo in the modules list (the output of lsmod).
+
+After the module xpp is loaded, you'll also be able to see the directory
+/proc/xpp . For any Astribank discovered there you will see a directory
+/prc/xpp/XBUS-n (where n is a number: typically 0). Once a unit have
+been discovered you'll see subdirectories: /proc/xpp/XBUS-n/XPD-m (where
+m may be another number: 0, 1 ,etc).
+
+Now to the ugly details:
+
+The driver of the Astribank is composed of several modules: xpp is the
+basic one, that contains the functionality to connect to Zaptel and other
+common functions. xpd_fxs is the module for controlling FXS spans.
+xpd_fxo is the module for controlling FXO spans. xpd_usb is the module
+that holds the functionality needed to connect to the USB bus.
+
+All modules depend on xpp, and modprobing them will install xpp as well.
+However the xpd_* modules are only installed on-demand: no need to
+install xpd_fxo if you only have FXS Astribank.
+
+You either plug in the Astribank , or start the hotplug/udev system
+while an Astribank is connected, after the firmware is loaded. The
+Vendor-ID/Product-ID of the device is e4e4/1132 . The handler for that
+combination is listed as the kernel module xpp_usb . Thus the system
+runs 'modprobe xpp_usb' if that module is not already loaded.
+
+The module xpp_usb depends on the modules zaptel and xpp . Both of which
+are loaded before xpp_usb is loaded. As usual, parameters and rules form
+/etc/modprobe.conf and/or /etc/modprobe.d/* will apply to the module, as
+modprobe is used.
+
+The modules to handle the specific span types (xpd_fxs, xpd_fxo) may or
+may not have been loaded yet at this stage (when the command 'modprobe
+xpp_usb' returns).
+
+At this point the xpp driver asks the box what logical units it has.
+According to the answers it gets, it will figure what xpd_* modules it will
+need, and modprobe for them. At some earlier version of the driver this has
+required some special modprobe.conf setup, but this is no longer
+the case.
+
+
+Device Initializations Scripts:
+""""""""""""""""""""""""""""""
+The chips in the device need to be initialized. This involves sending a
+bunch of values to certain registers in those chips. We decided that
+hardwiring those values in the driver itself would not be a good idea.
+
+before registering a XPD as a span in Zaptel, we run an initialization
+script: /usr/share/zaptel/initialize_registers . If this fails (e.g:
+because the script is not there, or is not executable), you will get an
+error message in the logs [FIXME: quote error message] that the
+invocation has failed. The XPD will then be removed (you won't see that
+a directory for that XPD under the relevant /proc/xpp/XBUS-* directory)
+and not be registered with Zaptel.
+
+Registering With Zaptel:
+"""""""""""""""""""""""
+Now we finally got to the "lights party" part: the lights in a unit
+(XPD) get lit before it registers with Zaptel and are turned off after
+that.
+
+You may choose not to register the XPDs to Zaptel automatically, to
+allow finer control of the process. This is done using the module
+parameter zap_autoreg. Set in the modprobe configuration file (e.g:
+/etc/modprobe.conf ) the line:
+
+ options xpp zap_autoreg=0
+
+to disable automatic registration at startup. You will then need to
+register the spans manually.
+
+
+SAMPLE CONFIGURATIONS:
+""""""""""""""""""""""
+
+/etc/zaptel.conf:
+
+ Astribank 8:
+
+ fxoks=1-14
+
+ Astribank 16: 8FXS/8FXO
+
+ fxoks=1-14
+ fksks=15-22
+
+/etc/asterisk/zapata.conf
+
+ Astribank 8:
+
+ [channels]
+ signalling=fxo_ks
+ ; The real analog ports:
+ context=from-internal
+ ; echocancel=yes
+ ; echocancelwhenbriged=yes
+ ; echotraining=9
+ channel => 1-8
+
+ ; output ports:
+ context=astribank-outputs
+ channel => 9-10
+ ; input ports:
+ immediate=yes
+ context=astribank-inputs
+ channel => 11-14
+ immediate=no
+
+ Astribank 16: 8FXS/8FXO
+
+ [channels]
+ signalling=fxo_ks
+ ; The real analog ports:
+ context=from-internal
+ ; echocancel=yes
+ ; echocancelwhenbriged=yes
+ ; echotraining=9
+ channel => 1-8
+
+ ; output ports:
+ context=astribank-outputs
+ channel => 9-10
+ ; input ports:
+ immediate=yes
+ context=astribank-inputs
+ channel => 11-14
+ immediate=no
+
+ ; FXO ports
+ signalling=fxs_ks
+ context=from-pstn
+ callerid=asreceived
+ channel => 15-22
+
+See also the output of genzaptelconf for examples of mailbox and
+callerid, and for channel numbers that will match your specific settings.
+For that reason I only give the above two sample configurations.
When loaded, you should get one span, of 8 extensions, 2 output ports and
4 input ports:
root@rapid:~# cat /proc/zaptel/2
- Span 1: XBUS-0/XPD-0 "Xorcom XPD #0/0: FXS" NOTOPEN
+ Span 1: XBUS-0/XPD-0 "Xorcom XPD #0/0: FXS"
1 XPP_FXS/0-0 FXOKS (In use)
2 XPP_FXS/0-1 FXOKS (In use)
@@ -113,36 +297,6 @@ When loaded, you should get one span, of 8 extensions, 2 output ports and
13 XPP_IN/0-12 FXOKS (In use)
14 XPP_IN/0-13 FXOKS (In use)
-For such a simple case you could use:
-
-/etc/zaptel.conf:
-
-fxoks=1-14
-loadzone=us
-tonezone=us
-
-/etc/asterisk/zapata.conf:
-
-[channels]
-group=1
-signalling=fxo_ks
-immediate=no
-
-context=from-internal
-channels => 1-8
-
-; actually they will never generate calls, so the context
-; here is irrelevant
-;context=outputs
-channels => 9-10
-
-; input ports should get an answer:
-immediate=yes
-context=inputs
-channels => 11-14
-
-;;;;;; end of zapata.conf
-
/proc Interface
"""""""""""""""
@@ -183,10 +337,10 @@ Unsetting this could be useful if you have several Astribanks and you
want to set their registration order manually using zt_registration in
the /proc interface.
-initialize_registers (xpd_fxs)
-The script that is run to initilize registers of the device. The default is
-/usr/share/zaptel/initialize_registers .
-Setting this value could be useful if that location is inconvient for you.
+initdir: (xpp)
+This is the directory containing the initialization scripts.
+The default is /usr/share/zaptel .
+Setting this value could be useful if that location is inconvenient for you.
print_dbg: (all modules)
It will make the driver print tons of debugging messages. Can be sometime
diff --git a/xpp/calibrate_slics b/xpp/calibrate_slics
index f5b45f3..72ca202 100755
--- a/xpp/calibrate_slics
+++ b/xpp/calibrate_slics
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
#
-# $Id:$
+# $Id$
#
use strict;
@@ -22,7 +22,6 @@ sub logger($) {
sub write_to_slic_file($) {
my $write_str = shift;
- #print STDERR "[Writing string]\n".$write_str."[End String]\n";
open(SLICS,">$SlicsFile") or
die("Failed writing to slics file $SlicsFile");
@@ -38,19 +37,19 @@ sub read_reg($$$) {
my $direct = shift;
write_to_slic_file(
- sprintf("%02x 00 00 00 R%s %02X",
- 1<<$read_slic, $direct, $read_reg));
+ sprintf("%d R%s %02X", $read_slic, $direct, $read_reg));
sleep(0.001);
open(SLICS,$SlicsFile) or
die("Failed reading from slics file $SlicsFile");
+ #awk '/^SLIC_REPLY:/{print $5}' $SLICS | cut -dx -f2
my @reply = ();
while(<SLICS>){
- #if (/^[^#]/) {
+ #if (/^ /) {
# print STDERR "answer line: $_";
#}
- if (/^SLIC_REPLY:\s+[DI]\s+reg_num=0x[[:xdigit:]]+,\s+dataH=0x([[:xdigit:]]+)\s+dataL=0x([[:xdigit:]]+)/){
+ if (/^ \d*\s+[RW][DIS]\s+[[:xdigit:]]+\s+([[:xdigit:]]+)\s+([[:xdigit:]]+)/){
@reply = (hex($1), hex($2));
- #print STDERR "got [@reply]\n";
+ #print STDERR "got [$reply]\n";
last;
}
}
@@ -58,7 +57,7 @@ sub read_reg($$$) {
if ($direct eq 'I') {
return @reply;
} else {
- return $reply[1];
+ return $reply[0];
}
}
@@ -70,28 +69,11 @@ sub write_reg{#($$$$$) {
my $reg_val_low = shift;
my $reg_val_hi = shift;
- my $str = sprintf "%02x 00 00 00 W%s %02X %02X",
- 1<<$read_slic, $direct, $read_reg, $reg_val_low;
+ my $str = sprintf "%d W%s %02X %02X",
+ $read_slic, $direct, $read_reg, $reg_val_low;
if ($direct eq 'I') {
$str .= sprintf " %02X", $reg_val_hi;
}
- #printf STDERR "Writing: $str\n";
- write_to_slic_file($str);
-}
-
-# TODO: rearange arguments
-sub write_reg_all_slics{#($$$$) {
- my $read_reg = shift;
- my $direct = shift;
- my $reg_val_low = shift;
- my $reg_val_hi = shift;
-
- my $str = sprintf "FF FF 00 00 W%s %02X %02X",
- $direct, $read_reg, $reg_val_low;
- if ($direct eq 'I') {
- $str .= sprintf " %02X", $reg_val_hi;
- }
- printf STDERR "Writing: $str\n";
write_to_slic_file($str);
}
@@ -107,81 +89,81 @@ sub log_calib_params() {
sub init_indirect_registers() {
return write_to_slic_file("#
-FF FF 00 00 WI 00 C2 55
-FF FF 00 00 WI 01 E6 51
-FF FF 00 00 WI 02 85 4B
-FF FF 00 00 WI 03 37 49
+31 WI 00 C2 55
+31 WI 01 E6 51
+31 WI 02 85 4B
+31 WI 03 37 49
-FF FF 00 00 WI 04 33 33
-FF FF 00 00 WI 05 02 02
-FF FF 00 00 WI 06 02 02
-FF FF 00 00 WI 07 98 01
+31 WI 04 33 33
+31 WI 05 02 02
+31 WI 06 02 02
+31 WI 07 98 01
-FF FF 00 00 WI 08 98 01
-FF FF 00 00 WI 09 11 06
-FF FF 00 00 WI 0A 02 02
-FF FF 00 00 WI 0B E5 00
+31 WI 08 98 01
+31 WI 09 11 06
+31 WI 0A 02 02
+31 WI 0B E5 00
-FF FF 00 00 WI 0C 1C 0A
-FF FF 00 00 WI 0D 30 7B
-FF FF 00 00 WI 0E 63 00
-FF FF 00 00 WI 0F 00 00
+31 WI 0C 1C 0A
+31 WI 0D 30 7B
+31 WI 0E 63 00
+31 WI 0F 00 00
-FF FF 00 00 WI 10 70 78
-FF FF 00 00 WI 11 7D 00
-FF FF 00 00 WI 12 00 00
-FF FF 00 00 WI 13 00 00
+31 WI 10 70 78
+31 WI 11 7D 00
+31 WI 12 00 00
+31 WI 13 00 00
-FF FF 00 00 WI 14 F0 7E
-FF FF 00 00 WI 15 60 01
-FF FF 00 00 WI 16 00 00
-FF FF 00 00 WI 17 00 20
+31 WI 14 F0 7E
+31 WI 15 60 01
+31 WI 16 00 00
+31 WI 17 00 20
-FF FF 00 00 WI 18 00 20
-FF FF 00 00 WI 19 00 00
-FF FF 00 00 WI 1A 00 20
-FF FF 00 00 WI 1B 00 40
+31 WI 18 00 20
+31 WI 19 00 00
+31 WI 1A 00 20
+31 WI 1B 00 40
-FF FF 00 00 WI 1C 00 10
-FF FF 00 00 WI 1D 00 36
-FF FF 00 00 WI 1E 00 10
-FF FF 00 00 WI 1F 00 02
+31 WI 1C 00 10
+31 WI 1D 00 36
+31 WI 1E 00 10
+31 WI 1F 00 02
-FF FF 00 00 WI 20 C0 07
-FF FF 00 00 WI 21 00 26
-FF FF 00 00 WI 22 F4 0F
-FF FF 00 00 WI 23 00 80
+31 WI 20 C0 07
+31 WI 21 00 26
+31 WI 22 F4 0F
+31 WI 23 00 80
-#FF FF 00 00 WI 24 20 03
-#FF FF 00 00 WI 25 8C 08
-#FF FF 00 00 WI 26 00 01
-#FF FF 00 00 WI 27 10 00
+#31 WI 24 20 03
+#31 WI 25 8C 08
+#31 WI 26 00 01
+#31 WI 27 10 00
-FF FF 00 00 WI 24 00 08
-FF FF 00 00 WI 25 00 08
-FF FF 00 00 WI 26 00 08
-FF FF 00 00 WI 27 00 08
+31 WI 24 00 08
+31 WI 25 00 08
+31 WI 26 00 08
+31 WI 27 00 08
-FF FF 00 00 WI 28 00 0C
-FF FF 00 00 WI 29 00 0C
-FF FF 00 00 WI 2B 00 01
+31 WI 28 00 0C
+31 WI 29 00 0C
+31 WI 2B 00 01
-FF FF 00 00 WI 63 DA 00
-FF FF 00 00 WI 64 60 6B
-FF FF 00 00 WI 65 74 00
-FF FF 00 00 WI 66 C0 79
+31 WI 63 DA 00
+31 WI 64 60 6B
+31 WI 65 74 00
+31 WI 66 C0 79
-FF FF 00 00 WI 67 20 11
-FF FF 00 00 WI 68 E0 3B
+31 WI 67 20 11
+31 WI 68 E0 3B
#");
}
sub init_early_direct_regs() {
return write_to_slic_file("#
-FF FF 00 00 WD 08 00
-FF FF 00 00 WD 4A 34
-FF FF 00 00 WD 4B 10
-FF FF 00 00 WD 40 00
+31 WD 08 00
+31 WD 4A 34
+31 WD 4B 10
+31 WD 40 00
#")
}
@@ -221,7 +203,7 @@ sub manual_calibrate_loop($$) {
# start calibration:
my $calibration_in_progress = 1;
- write_reg_all_slics($write_reg, 'D', 0x1F);
+ write_reg(31, $write_reg, 'D', 0x1F);
sleep $ManualCalibrationSleepTime;
# wait until all slics have finished calibration, or for timeout
@@ -256,9 +238,9 @@ sub auto_calibrate($$) {
# start calibration:
write_to_slic_file(
sprintf
- "FF FF 00 00 WD 61 %02X\n".
- "FF FF 00 00 WD 60 %02X\n".
- "", $calib_97, $calib_96
+ "31 WD 61 %02X\n".
+ "31 WD 60 %02X\n".
+ "", $calib_96, $calib_97
);
# wait until all slics have finished calibration, or for timeout
@@ -267,19 +249,16 @@ sub auto_calibrate($$) {
CALIB_LOOP: for my $slic (@SlicNums) {
logger("checking slic $slic");
while(1) {
- my $reply;
- if (($reply=read_reg($slic, 96, 'D')) == 0) {
+ if ((read_reg($slic, 60, 'D')) == 0) {
# move to next register
logger("slic $slic calibrated");
last;
}
- print STDERR "reply: $reply\n";
my $time=time();
if ( $time > $end_time) {
$timeout=1;
- logger("Exiting on timeout: $time is after timeout $end_time .");
- exit 1;
- #last CALIB_LOOP;
+ logger("Exiting on timeout: $end_time < $time.");
+ last CALIB_LOOP;
}
logger("auto_calibrate not done yet: slic #$slic\n");
sleep(0.1);
diff --git a/xpp/card_fxo.c b/xpp/card_fxo.c
index ed77684..7672db3 100644
--- a/xpp/card_fxo.c
+++ b/xpp/card_fxo.c
@@ -33,8 +33,8 @@
static const char rcsid[] = "$Id$";
-DEF_PARM(int, print_dbg, 0, "Print DBG statements"); /* must be before zap_debug.h */
-DEF_PARM(uint, poll_battery_interval, 100, "Poll battery interval in milliseconds");
+DEF_PARM(int, print_dbg, 0, "Print DBG statements");
+DEF_PARM(uint, poll_battery_interval, 100, "Poll battery interval in milliseconds (0 - disable)");
DEF_PARM(bool, report_battery, 0, "Report battery status to zaptel");
/* Signaling is opposite (fxs signalling for fxo card) */
@@ -54,22 +54,30 @@ enum fxo_leds {
#define BAT_THRESHOLD 3
#define BAT_DEBOUNCE 3 /* compensate for battery voltage fluctuation (in poll_battery_interval's) */
+static /* 0x0F */ DECLARE_CMD(FXO, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high);
+/* Shortcuts */
+#define DAA_WRITE 1
+#define DAA_READ 0
+#define DAA_DIRECT_REQUEST(xbus,xpd,chipsel,writing,reg,dL) \
+ CALL_PROTO(FXO, REGISTER_REQUEST, (xbus), (xpd), (chipsel), (writing), 0, (reg), 0, (dL), 0)
+
+#define VALID_CHIPSEL(x) (((chipsel) >= 0 && (chipsel) <= 7) || (chipsel) == ALL_CHANS)
+
/*---------------- FXO Protocol Commands ----------------------------------*/
-static /* 0x0F */ DECLARE_CMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on);
-static /* 0x0F */ DECLARE_CMD(FXO, CHAN_CID, int pos);
-static /* 0x0F */ DECLARE_CMD(FXO, RING, int pos, bool on);
+static /* 0x0F */ DECLARE_CMD(FXO, XPD_STATE, bool on);
+static /* 0x0F */ DECLARE_CMD(FXO, CHAN_CID, lineno_t chan);
+static /* 0x0F */ DECLARE_CMD(FXO, RING, lineno_t chan, bool on);
static /* 0x0F */ DECLARE_CMD(FXO, RELAY_OUT, byte which, bool on);
-static /* 0x0F */ DECLARE_CMD(FXO, DAA_QUERY, int pos, byte reg_num);
static bool fxo_packet_is_valid(xpacket_t *pack);
-static void fxo_packet_dump(xpacket_t *pack);
+static void fxo_packet_dump(const char *msg, xpacket_t *pack);
static int proc_fxo_info_read(char *page, char **start, off_t off, int count, int *eof, void *data);
-static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data);
-static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
-static int process_slic_cmdline(xpd_t *xpd, char *cmdline);
+static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
+static int handle_register_command(xpd_t *xpd, char *cmdline);
-#define PROC_DAA_FNAME "slics"
+#define PROC_REGISTER_FNAME "slics"
#define PROC_FXO_INFO_FNAME "fxo_info"
#ifdef SOFT_RING
@@ -80,11 +88,9 @@ static int process_slic_cmdline(xpd_t *xpd, char *cmdline);
#define DAA_RING_REGISTER 0x05
struct FXO_priv_data {
- struct proc_dir_entry *xpd_slic;
+ struct proc_dir_entry *regfile;
struct proc_dir_entry *fxo_info;
uint poll_counter;
- slic_reply_t requested_reply;
- slic_reply_t last_reply;
xpp_line_t battery;
ushort battery_debounce[CHANNELS_PERXPD];
xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */
@@ -119,42 +125,29 @@ void MARK_LED(xpd_t *xpd, lineno_t pos, byte color, bool on)
/*
* LED control is done via DAA register 0x20
*/
-static int do_led(xpd_t *xpd, lineno_t pos, byte which, bool on)
+static int do_led(xpd_t *xpd, lineno_t chan, byte which, bool on)
{
int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
struct FXO_priv_data *priv;
- xpp_line_t lines;
xbus_t *xbus;
BUG_ON(!xpd);
xbus = xpd->xbus;
priv = xpd->priv;
which = which % NUM_LEDS;
- if(IS_SET(xpd->digital_outputs, pos) || IS_SET(xpd->digital_inputs, pos))
+ if(IS_SET(xpd->digital_outputs, chan) || IS_SET(xpd->digital_inputs, chan))
goto out;
- if(pos == ALL_LINES) {
- lines = ~0;
+ if(chan == ALL_CHANS) {
priv->ledstate[which] = (on) ? ~0 : 0;
} else {
- lines = BIT(pos);
if(on) {
- BIT_SET(priv->ledstate[which], pos);
+ BIT_SET(priv->ledstate[which], chan);
} else {
- BIT_CLR(priv->ledstate[which], pos);
+ BIT_CLR(priv->ledstate[which], chan);
}
}
- if(!lines) // Nothing to do
- goto out;
- DBG("%s/%s: LED: lines=0x%04X which=%d -- %s\n", xbus->busname, xpd->xpdname, lines, which, (on) ? "on" : "off");
- XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, lines, 0x20, on);
- // DBG("LED pack: line=%d %s\n", i, (on)?"on":"off");
- pack->datalen = len;
- packet_send(xbus, pack);
+ DBG("%s/%s/%d: LED: which=%d -- %s\n", xbus->busname, xpd->xpdname, chan, which, (on) ? "on" : "off");
+ ret = DAA_DIRECT_REQUEST(xbus, xpd, chan, DAA_WRITE, 0x20, on);
out:
return ret;
}
@@ -221,9 +214,6 @@ static int do_sethook(xpd_t *xpd, int pos, bool to_offhook)
struct FXO_priv_data *priv;
int ret = 0;
bool value;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
BUG_ON(!xpd);
BUG_ON(xpd->direction == TO_PHONE); // We can SETHOOK state only on PSTN
@@ -238,11 +228,7 @@ static int do_sethook(xpd_t *xpd, int pos, bool to_offhook)
value = (to_offhook) ? 0x09 : 0x08; /* Bit 3 is for CID */
DBG("%s/%s/%d: SETHOOK: value=0x%02X %s\n", xbus->busname, xpd->xpdname, pos, value, (to_offhook)?"OFFHOOK":"ONHOOK");
MARK_LED(xpd, pos, LED_GREEN, (to_offhook)?LED_ON:LED_OFF);
- XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, BIT(pos), DAA_RING_REGISTER, value);
- pack->datalen = len;
- packet_send(xbus, pack);
+ ret = DAA_DIRECT_REQUEST(xbus, xpd, pos, DAA_WRITE, DAA_RING_REGISTER, value);
#ifdef SOFT_RING
priv->ring_sig[pos] = 0;
#endif
@@ -282,10 +268,10 @@ static void clean_proc(xbus_t *xbus, xpd_t *xpd)
priv = xpd->priv;
DBG("%s/%s\n", xbus->busname, xpd->xpdname);
#ifdef CONFIG_PROC_FS
- if(priv->xpd_slic) {
+ if(priv->regfile) {
DBG("Removing xpd DAA file %s/%s\n", xbus->busname, xpd->xpdname);
- remove_proc_entry(PROC_DAA_FNAME, xpd->proc_xpd_dir);
- priv->xpd_slic = NULL;
+ remove_proc_entry(PROC_REGISTER_FNAME, xpd->proc_xpd_dir);
+ priv->regfile->data = NULL;
}
if(priv->fxo_info) {
DBG("Removing xpd FXO_INFO file %s/%s\n", xbus->busname, xpd->xpdname);
@@ -313,16 +299,16 @@ static int FXO_card_init(xbus_t *xbus, xpd_t *xpd)
}
priv->fxo_info->owner = THIS_MODULE;
DBG("Creating DAAs file for %s/%s\n", xbus->busname, xpd->xpdname);
- priv->xpd_slic = create_proc_entry(PROC_DAA_FNAME, 0644, xpd->proc_xpd_dir);
- if(!priv->xpd_slic) {
+ priv->regfile = create_proc_entry(PROC_REGISTER_FNAME, 0644, xpd->proc_xpd_dir);
+ if(!priv->regfile) {
ERR("Failed to create proc file for DAAs of %s/%s\n", xbus->busname, xpd->xpdname);
ret = -ENOENT;
goto err;
}
- priv->xpd_slic->owner = THIS_MODULE;
- priv->xpd_slic->write_proc = proc_xpd_slic_write;
- priv->xpd_slic->read_proc = proc_xpd_slic_read;
- priv->xpd_slic->data = xpd;
+ priv->regfile->owner = THIS_MODULE;
+ priv->regfile->write_proc = proc_xpd_register_write;
+ priv->regfile->read_proc = proc_xpd_register_read;
+ priv->regfile->data = xpd;
#endif
ret = run_initialize_registers(xpd);
if(ret < 0)
@@ -430,7 +416,7 @@ static void poll_battery(xbus_t *xbus, xpd_t *xpd)
int i;
for_each_line(xpd, i) {
- CALL_PROTO(FXO, DAA_QUERY, xbus, xpd, i, DAA_VBAT_REGISTER);
+ DAA_DIRECT_REQUEST(xbus, xpd, i, DAA_READ, DAA_VBAT_REGISTER, 0);
}
}
@@ -444,7 +430,7 @@ static void poll_ring(xbus_t *xbus, xpd_t *xpd)
BUG_ON(!priv);
for_each_line(xpd, i) {
if(priv->ring_sig[i])
- CALL_PROTO(FXO, DAA_QUERY, xbus, xpd, i, DAA_RING_REGISTER);
+ DAA_DIRECT_REQUEST(xbus, xpd, i, DAA_READ, DAA_RING_REGISTER, 0);
}
}
#endif
@@ -496,16 +482,11 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
/* quick and dirty registers writing: */
for (i=0; i<sizeof(echotune_reg); i++) {
char buf[22];
- xpp_line_t lines = BIT(pos);
- sprintf(buf, "%02X %02X %02X %02X WD %2X %2X",
- (lines & 0xFF),
- ((lines >> 8) & 0xFF),
- ((lines >> 16) & 0xFF),
- ((lines >> 24) & 0xFF),
- echotune_reg[i],echoregs.coeff[i]
+ sprintf(buf, "%d WD %2X %2X",
+ pos,echotune_reg[i],echoregs.coeff[i]
);
/* FIXME: code duplicated from proc_xpd_register_write */
- ret = process_slic_cmdline(xpd, buf);
+ ret = handle_register_command(xpd, buf);
if(ret < 0)
return ret;
mdelay(1);
@@ -522,17 +503,46 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
/*---------------- FXO: HOST COMMANDS -------------------------------------*/
-static /* 0x0F */ HOSTCMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on)
+/* 0x0F */ HOSTCMD(FXO, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high)
+{
+ int ret = 0;
+ xpacket_t *pack;
+ reg_cmd_t *reg_cmd;
+
+ if(!xbus) {
+ DBG("NO XBUS\n");
+ return -EINVAL;
+ }
+ XPACKET_NEW(pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->id);
+#if 0
+ DBG("%s/%s/%d: %c%c R%02X S%02X %02X %02X\n",
+ xbus->busname, xpd->xpdname, chipsel,
+ (writing)?'W':'R',
+ (do_subreg)?'S':'D',
+ regnum, subreg, data_low, data_high);
+#endif
+ reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
+ pack->datalen = sizeof(*reg_cmd);
+ reg_cmd->bytes = sizeof(*reg_cmd) - 1; // do not count the 'bytes' field
+ REG_FIELD(reg_cmd, chipsel) = chipsel;
+ REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1;
+ REG_FIELD(reg_cmd, do_subreg) = do_subreg;
+ REG_FIELD(reg_cmd, regnum) = regnum;
+ REG_FIELD(reg_cmd, subreg) = subreg;
+ REG_FIELD(reg_cmd, data_low) = data_low;
+ REG_FIELD(reg_cmd, data_high) = data_high;
+ ret = packet_send(xbus, pack);
+ return ret;
+}
+
+static /* 0x0F */ HOSTCMD(FXO, XPD_STATE, bool on)
{
int ret = 0;
int i;
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!lines) {
- return 0;
- }
- DBG("Channel Activation: 0x%4X %s\n", lines, (on) ? "on" : "off");
+ DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on) ? "on" : "off");
if(on) {
for_each_line(xpd, i) {
MARK_LED(xpd, i, LED_GREEN, LED_ON);
@@ -546,42 +556,23 @@ static /* 0x0F */ HOSTCMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on)
return ret;
}
-static /* 0x0F */ HOSTCMD(FXO, CHAN_CID, int pos)
+static /* 0x0F */ HOSTCMD(FXO, CHAN_CID, lineno_t chan)
{
int ret = 0;
- xpp_line_t lines = BIT(pos);
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!lines) {
- return 0;
- }
- DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, pos);
+ DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, chan);
return ret;
}
-static /* 0x0F */ HOSTCMD(FXO, RING, int pos, bool on)
+static /* 0x0F */ HOSTCMD(FXO, RING, lineno_t chan, bool on)
{
- int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- xpp_line_t mask = BIT(pos);
- int len;
-
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!mask) {
- return 0;
- }
- DBG("%s/%s/%d %s\n", xpd->xbus->busname, xpd->xpdname, pos, (on) ? "on" : "off");
- XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, mask, 0x40, (on)?0x04:0x01);
- pack->datalen = len;
-
- packet_send(xbus, pack);
- return ret;
+ DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, chan, (on) ? "on" : "off");
+ return DAA_DIRECT_REQUEST(xbus, xpd, chan, DAA_WRITE, 0x40, (on)?0x04:0x01);
}
static /* 0x0F */ HOSTCMD(FXO, RELAY_OUT, byte which, bool on)
@@ -589,26 +580,6 @@ static /* 0x0F */ HOSTCMD(FXO, RELAY_OUT, byte which, bool on)
return -ENOSYS;
}
-static /* 0x0F */ HOSTCMD(FXO, DAA_QUERY, int pos, byte reg_num)
-{
- int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
-
- BUG_ON(!xbus);
- BUG_ON(!xpd);
- // DBG("\n");
- XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
- len = slic_cmd_direct_read(sc, BIT(pos), reg_num);
-
- pack->datalen = len;
-
- packet_send(xbus, pack);
- return ret;
-}
-
/*---------------- FXO: Astribank Reply Handlers --------------------------*/
HANDLER_DEF(FXO, SIG_CHANGED)
@@ -658,10 +629,10 @@ HANDLER_DEF(FXO, SIG_CHANGED)
HANDLER_DEF(FXO, DAA_REPLY)
{
- slic_reply_t *info = &RPACKET_FIELD(pack, FXO, DAA_REPLY, info);
- xpp_line_t lines = RPACKET_FIELD(pack, FXO, DAA_REPLY, lines);
+ reg_cmd_t *info = &RPACKET_FIELD(pack, FXO, DAA_REPLY, regcmd);
unsigned long flags;
struct FXO_priv_data *priv;
+ lineno_t chipsel;
if(!xpd) {
NOTICE("%s: received %s for non-existing xpd: %d\n",
@@ -671,68 +642,62 @@ HANDLER_DEF(FXO, DAA_REPLY)
spin_lock_irqsave(&xpd->lock, flags);
priv = xpd->priv;
BUG_ON(!priv);
- if(!info->indirect && info->reg_num == DAA_VBAT_REGISTER) {
- byte bat = abs((signed char)info->data_low);
- int i;
-
- for_each_line(xpd, i) {
- if(!IS_SET(lines, i))
- continue;
- if(bat < BAT_THRESHOLD) {
- /*
- * Check for battery voltage fluctuations
- */
- if(IS_SET(priv->battery, i) && priv->battery_debounce[i]++ > BAT_DEBOUNCE) {
- DBG("%s/%s: BATTERY OFF (%04X) voltage=%d\n", xpd->xbus->busname, xpd->xpdname, lines, bat);
- BIT_CLR(priv->battery, i);
- update_line_status(xpd, i, 0);
- }
- } else {
- priv->battery_debounce[i] = 0;
- if(!IS_SET(priv->battery, i)) {
- DBG("%s/%s: BATTERY ON (%04X) voltage=%d\n", xpd->xbus->busname, xpd->xpdname, lines, bat);
- BIT_SET(priv->battery, i);
- }
+ chipsel = REG_FIELD(info, chipsel);
+
+ /*
+ * Update battery status
+ */
+ if(REG_FIELD(info, regnum) == DAA_VBAT_REGISTER) {
+ byte bat = abs((signed char)REG_FIELD(info, data_low));
+
+ if(bat < BAT_THRESHOLD) {
+ /*
+ * Check for battery voltage fluctuations
+ */
+ if(IS_SET(priv->battery, chipsel) && priv->battery_debounce[chipsel]++ > BAT_DEBOUNCE) {
+ DBG("%s/%s/%d: BATTERY OFF voltage=%d\n", xpd->xbus->busname, xpd->xpdname, chipsel, bat);
+ BIT_CLR(priv->battery, chipsel);
+ update_line_status(xpd, chipsel, 0);
+ }
+ } else {
+ priv->battery_debounce[chipsel] = 0;
+ if(!IS_SET(priv->battery, chipsel)) {
+ DBG("%s/%s/%d: BATTERY ON voltage=%d\n", xpd->xbus->busname, xpd->xpdname, chipsel, bat);
+ BIT_SET(priv->battery, chipsel);
}
}
}
#ifdef SOFT_RING
- if(!info->indirect && info->reg_num == DAA_RING_REGISTER) {
- bool ringit = (info->data_low & (0x20 | 0x40)) ? 1 : 0; /* Ring positive | Ring negative */
- int i;
-
- for_each_line(xpd, i) {
- if(!IS_SET(lines, i))
- continue;
- if (!priv->ring_sig[i])
- continue;
- if(ringit) {
- if(priv->ring_thresh[i] > RING_THRESHOLD) {
- mark_ring(xpd, i, 1);
- priv->noring_thresh[i] = 0;
- } else
- priv->ring_thresh[i]++;
- } else {
- if(priv->noring_thresh[i] > NORING_THRESHOLD) {
- mark_ring(xpd, i, 0);
- priv->ring_thresh[i] = 0;
- } else
- priv->noring_thresh[i]++;
- }
+ if(REG_FIELD(info, regnum) == DAA_RING_REGISTER && priv->ring_sig[chipsel]) {
+ bool ringit = (REG_FIELD(info, data_low) & (0x20 | 0x40)) ? 1 : 0; /* Ring positive | Ring negative */
+
+ if(ringit) {
+ if(priv->ring_thresh[chipsel] > RING_THRESHOLD) {
+ mark_ring(xpd, chipsel, 1);
+ priv->noring_thresh[chipsel] = 0;
+ } else
+ priv->ring_thresh[chipsel]++;
+ } else {
+ if(priv->noring_thresh[chipsel] > NORING_THRESHOLD) {
+ mark_ring(xpd, chipsel, 0);
+ priv->ring_thresh[chipsel] = 0;
+ } else
+ priv->noring_thresh[chipsel]++;
}
}
#endif
#if 0
- if (info->reg_num != 29)
DBG("DAA_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
- xpd->id, (info->indirect)?"I":"D",
+ xpd->id, (info->size == 3)?"I":"D",
info->reg_num, info->data_low, info->data_high);
#endif
/* Update /proc info only if reply relate to the last slic read request */
- if(priv->requested_reply.indirect == info->indirect &&
- priv->requested_reply.reg_num == info->reg_num) {
- priv->last_reply = *info;
+ if(
+ REG_FIELD(&xpd->requested_reply, regnum) == REG_FIELD(info, regnum) &&
+ REG_FIELD(&xpd->requested_reply, do_subreg) == REG_FIELD(info, do_subreg) &&
+ REG_FIELD(&xpd->requested_reply, subreg) == REG_FIELD(info, subreg)) {
+ xpd->last_reply = *info;
}
spin_unlock_irqrestore(&xpd->lock, flags);
return 0;
@@ -742,9 +707,9 @@ HANDLER_DEF(FXO, DAA_REPLY)
xproto_table_t PROTO_TABLE(FXO) = {
.owner = THIS_MODULE,
.entries = {
- /* Card Opcode */
- XENTRY( FXO, SIG_CHANGED ),
- XENTRY( FXO, DAA_REPLY ),
+ /* Prototable Card Opcode */
+ XENTRY( FXO, FXO, SIG_CHANGED ),
+ XENTRY( FXO, FXO, DAA_REPLY ),
},
.name = "FXO",
.type = XPD_TYPE_FXO,
@@ -760,7 +725,7 @@ xproto_table_t PROTO_TABLE(FXO) = {
.RING = XPROTO_CALLER(FXO, RING),
.RELAY_OUT = XPROTO_CALLER(FXO, RELAY_OUT),
- .CHAN_ENABLE = XPROTO_CALLER(FXO, CHAN_ENABLE),
+ .XPD_STATE = XPROTO_CALLER(FXO, XPD_STATE),
.CHAN_CID = XPROTO_CALLER(FXO, CHAN_CID),
.SYNC_SOURCE = XPROTO_CALLER(GLOBAL, SYNC_SOURCE),
@@ -779,9 +744,9 @@ static bool fxo_packet_is_valid(xpacket_t *pack)
return xe != NULL;
}
-static void fxo_packet_dump(xpacket_t *pack)
+static void fxo_packet_dump(const char *msg, xpacket_t *pack)
{
- DBG("\n");
+ DBG("%s\n", msg);
}
/*------------------------- DAA Handling --------------------------*/
@@ -809,11 +774,6 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count, in
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
len += sprintf(page + len, "%2d ", IS_SET(priv->ledstate[LED_GREEN], i));
}
- len += sprintf(page + len, "\n\t%-17s: ", "ledcontrol");
- for_each_line(xpd, i) {
- if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%2d ", IS_SET(priv->ledcontrol[LED_GREEN], i));
- }
len += sprintf(page + len, "\n\t%-17s: ", "blinking");
for_each_line(xpd, i) {
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
@@ -833,17 +793,13 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count, in
len += sprintf(page + len, "\n\t%-17s: ", "ring_sig");
for_each_line(xpd, i) {
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%d ", priv->ring_sig[i]);
+ len += sprintf(page + len, "%2d ", priv->ring_sig[i]);
}
#endif
len += sprintf(page + len, "\n\t%-17s: ", "battery");
for_each_line(xpd, i) {
len += sprintf(page + len, "%2d ", IS_SET(priv->battery, i));
}
- len += sprintf(page + len, "\n\t%-17s: ", "battery_debounce");
- for_each_line(xpd, i) {
- len += sprintf(page + len, "%2d ", priv->battery_debounce[i]);
- }
len += sprintf(page + len, "\n");
spin_unlock_irqrestore(&xpd->lock, flags);
if (len <= off+count)
@@ -857,113 +813,38 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count, in
return len;
}
-
-static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- int len = 0;
- unsigned long flags;
- xpd_t *xpd = data;
- slic_reply_t *info;
- struct FXO_priv_data *priv;
-
- BUG_ON(!xpd);
- spin_lock_irqsave(&xpd->lock, flags);
- priv = xpd->priv;
- BUG_ON(!priv);
- info = &priv->last_reply;
- len += sprintf(page + len, "# Writing bad data into this file may damage your hardware!\n");
- len += sprintf(page + len, "# Consult firmware docs first\n");
- len += sprintf(page + len, "DAA_REPLY: %s reg_num=0x%X, dataH=0x%X dataL=0x%X\n",
- (info->indirect)?"I":"D",
- info->reg_num, info->data_high, info->data_low);
- spin_unlock_irqrestore(&xpd->lock, flags);
- if (len <= off+count)
- *eof = 1;
- *start = page + off;
- len -= off;
- if (len > count)
- len = count;
- if (len < 0)
- len = 0;
- return len;
-}
-
/*
- * Direct/Indirect
- * v
- * FF FF FF FF WD 06 1
- * ^---------^ ^ Reg
- * | Write/Read
- * |
- * DAA #
+ *
+ * Direct/Indirect
+ * |
+ * | Reg#
+ * | |
+ * | | Data (only in Write)
+ * | | |
+ * | | +-+-+
+ * v v v v
+ * FF WD 06 01 05
+ * ^ ^
+ * | |
+ * | Write/Read
+ * |
+ * Chan#
+ *
*/
-static int parse_slic_cmd(const char *buf, slic_cmd_t *sc, slic_reply_t *requested_reply)
-{
- char op; /* [W]rite, [R]ead */
- char reg_type; /* [D]irect, [I]ndirect */
- int s1, s2, s3, s4;
- int reg_num;
- int data_low, data_high;
- xpp_line_t lines;
- int ret;
-
- ret = sscanf(buf, "%x %x %x %x %c%c %x %x %x",
- &s1, &s2, &s3, &s4, &op, &reg_type, &reg_num, &data_high, &data_low);
- lines = (s4 << 24) | (s3 << 16) | (s2 << 8) | (s1);
- switch(op) {
- case 'R':
- if(reg_type == 'D' && ret == 7) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x\n", s1, s2, s3, s4, reg_type, reg_num);
- ret = slic_cmd_direct_read(sc, lines, reg_num);
- if(requested_reply) {
- requested_reply->indirect = 0;
- requested_reply->reg_num = reg_num;
- }
- } else if(reg_type == 'I' && ret == 7) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x\n", s1, s2, s3, s4, reg_type, reg_num);
- ret = slic_cmd_indirect_read(sc, lines, reg_num);
- if(requested_reply) {
- requested_reply->indirect = 1;
- requested_reply->reg_num = reg_num;
- }
- } else {
- NOTICE("%s: Bad read input: ret=%d buf='%s' reg_type=%c\n", __FUNCTION__, ret, buf, reg_type);
- goto err;
- }
- break;
- case 'W':
- if(reg_type == 'D' && ret == 8) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x %X\n", s1, s2, s3, s4, reg_type, reg_num, data_high);
- ret = slic_cmd_direct_write(sc, lines, reg_num, data_high);
- } else if(reg_type == 'I' && ret == 9) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x %X %X\n", s1, s2, s3, s4, reg_type, reg_num, data_high, data_low);
- ret = slic_cmd_indirect_write(sc, lines, reg_num, data_low, data_high);
- } else {
- NOTICE("%s: Bad write input: ret=%d buf='%s' reg_type=%c\n", __FUNCTION__, ret, buf, reg_type);
- goto err;
- }
- break;
- default:
- NOTICE("%s: Bad input: ret=%d buf='%s' op=%c\n", __FUNCTION__, ret, buf, op);
- goto err;
- }
- return ret;
-err:
- return -EINVAL;
-}
-
-static int process_slic_cmdline(xpd_t *xpd, char *cmdline)
-{
- xbus_t *xbus;
- struct FXO_priv_data *priv;
- slic_cmd_t sc;
- xpacket_t *pack;
+static int handle_register_command(xpd_t *xpd, char *cmdline)
+{
+ unsigned chipsel;
+ unsigned data_low = 0;
+ char op; /* [W]rite, [R]ead */
+ char reg_type; /* [D]irect */
+ int reg_num;
+ int elements;
+ bool writing;
char *p;
- int len = strlen(cmdline);
+ reg_cmd_t regcmd;
+ xbus_t *xbus;
+ int ret;
- BUG_ON(!xpd);
- xbus = xpd->xbus;
- priv = xpd->priv;
if((p = strchr(cmdline, '#')) != NULL) /* Truncate comments */
*p = '\0';
if((p = strchr(cmdline, ';')) != NULL) /* Truncate comments */
@@ -972,22 +853,70 @@ static int process_slic_cmdline(xpd_t *xpd, char *cmdline)
;
if(*p == '\0')
return 0;
- len = parse_slic_cmd(p, &sc, &priv->requested_reply);
- if(len < 0)
- return len;
- if(!sc.lines) {
- NOTICE("%s: no channels are marked. Skip.\n", __FUNCTION__);
- return 0;
+
+ elements = sscanf(cmdline, "%d %c%c %x %x",
+ &chipsel,
+ &op, &reg_type, &reg_num,
+ &data_low);
+ // DBG("'%s': %d %c%c %02X %02X %02X\n", cmdline, chipsel, op, reg_type, reg_num, data_low);
+ if(elements < 4) { // At least: chipsel, op, reg_type, reg_num
+ ERR("Not enough arguments: (%d args) '%s'\n", elements, cmdline);
+ return -EINVAL;
+ }
+ if(!VALID_CHIPSEL(chipsel)) {
+ ERR("Bad chipsel number: %d\n", chipsel);
+ return -EINVAL;
+ }
+ REG_FIELD(&regcmd, chipsel) = chipsel;
+ REG_FIELD(&regcmd, do_subreg) = 0;
+ switch(op) {
+ case 'W':
+ writing = 1;
+ break;
+ case 'R':
+ writing = 0;
+ break;
+ default:
+ ERR("Unkown operation type '%c'\n", op);
+ return -EINVAL;
}
- dump_slic_cmd("WRITE_DAA", &sc);
- XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
- RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd) = sc;
- pack->datalen = len;
- packet_send(xbus, pack);
- return 0;
+ switch(reg_type) {
+ case 'D':
+ REG_FIELD(&regcmd, regnum) = reg_num;
+ REG_FIELD(&regcmd, subreg) = 0;
+ break;
+ default:
+ ERR("Unkown register type '%c'\n", reg_type);
+ return -EINVAL;
+ }
+ if(
+ (op == 'W' && reg_type == 'D' && elements != 5) ||
+ (op == 'R' && reg_type == 'D' && elements != 4)
+ ) {
+ ERR("%s: '%s' (%d elements): %d %c%c %02X %02X\n", __FUNCTION__,
+ cmdline, elements,
+ chipsel, op, reg_type, reg_num, data_low);
+ return -EINVAL;
+ }
+ regcmd.bytes = sizeof(regcmd) - 1;
+ REG_FIELD(&regcmd, data_low) = data_low;
+ REG_FIELD(&regcmd, data_high) = 0;
+ REG_FIELD(&regcmd, read_request) = writing;
+ BUG_ON(!xpd);
+ xbus = xpd->xbus;
+ if(!down_read_trylock(&xbus->in_use)) {
+ DBG("Dropped packet. %s is in_use\n", xbus->busname);
+ return -EBUSY;
+ }
+ xpd->requested_reply = regcmd;
+ if(print_dbg)
+ dump_reg_cmd("FXO", &regcmd);
+ ret = DAA_DIRECT_REQUEST(xpd->xbus, xpd, REG_FIELD(&regcmd, chipsel), writing, REG_FIELD(&regcmd, regnum), REG_FIELD(&regcmd, data_low));
+ up_read(&xbus->in_use);
+ return ret;
}
-static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
+static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
xpd_t *xpd = data;
char buf[MAX_PROC_WRITE];
@@ -1010,7 +939,7 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns
if(p >= buf + MAX_PROC_WRITE)
return -E2BIG;
*p = '\0';
- ret = process_slic_cmdline(xpd, buf);
+ ret = handle_register_command(xpd, buf);
if(ret < 0)
return ret;
mdelay(1);
@@ -1018,6 +947,37 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns
return count;
}
+static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len = 0;
+ unsigned long flags;
+ xpd_t *xpd = data;
+ reg_cmd_t *info;
+ byte regnum;
+
+ if(!xpd)
+ return -ENODEV;
+ spin_lock_irqsave(&xpd->lock, flags);
+ info = &xpd->last_reply;
+ regnum = REG_FIELD(info, regnum);
+ len += sprintf(page + len, "# Writing bad data into this file may damage your hardware!\n");
+ len += sprintf(page + len, "# Consult firmware docs first\n");
+ len += sprintf(page + len, "#\n");
+ len += sprintf(page + len, "#CH\tD/I\tReg.\tDL\n");
+ len += sprintf(page + len, "%2d\tRD\t%02X\t%02X\n",
+ REG_FIELD(info, chipsel),
+ regnum, REG_FIELD(info, data_low));
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ if (len <= off+count)
+ *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+ return len;
+}
int __init card_fxo_startup(void)
{
diff --git a/xpp/card_fxo.h b/xpp/card_fxo.h
index 6e5186b..a22e193 100644
--- a/xpp/card_fxo.h
+++ b/xpp/card_fxo.h
@@ -23,19 +23,16 @@
*/
#include "xpd.h"
-#include "slic.h"
enum fxo_opcodes {
XPROTO_NAME(FXO, SIG_CHANGED) = 0x06,
/**/
XPROTO_NAME(FXO, DAA_WRITE) = 0x0F, /* Write to DAA */
- XPROTO_NAME(FXO, CHAN_ENABLE) = 0x0F, /* Write to DAA */
+ XPROTO_NAME(FXO, XPD_STATE) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, CHAN_CID) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, RING) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, LED) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, RELAY_OUT) = 0x0F, /* Write to DAA */
- XPROTO_NAME(FXO, DAA_INIT) = 0x0F, /* Write to DAA */
- XPROTO_NAME(FXO, DAA_QUERY) = 0x0F, /* Write to DAA */
/**/
XPROTO_NAME(FXO, DAA_REPLY) = 0x10,
};
@@ -47,11 +44,7 @@ DEF_RPACKET_DATA(FXO, SIG_CHANGED,
xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */
);
DEF_RPACKET_DATA(FXO, DAA_REPLY, /* Get status of a single DAA (for debugging) */
- xpp_line_t lines;
- slic_reply_t info;
- );
-DEF_RPACKET_DATA(FXO, DAA_WRITE,
- slic_cmd_t slic_cmd;
+ reg_cmd_t regcmd;
);
#define DAA_VBAT_REGISTER 29
diff --git a/xpp/card_fxs.c b/xpp/card_fxs.c
index 9aaef63..3d659fa 100644
--- a/xpp/card_fxs.c
+++ b/xpp/card_fxs.c
@@ -58,74 +58,50 @@ enum fxs_leds {
#define NUM_LEDS 2
-static int SLIC_DIRECT_REQUEST(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, byte reg, byte dL)
-{
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
-
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, lines, reg, dL);
- pack->datalen = len;
- packet_send(xbus, pack);
- return 0;
-}
+static /* 0x0F */ DECLARE_CMD(FXS, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high);
+/* Shortcuts */
+#define SLIC_WRITE 1
+#define SLIC_READ 0
+#define SLIC_DIRECT_REQUEST(xbus,xpd,chipsel,writing,reg,dL) \
+ CALL_PROTO(FXS, REGISTER_REQUEST, (xbus), (xpd), (chipsel), (writing), 0, (reg), 0, (dL), 0)
+#define SLIC_INDIRECT_REQUEST(xbus,xpd,chipsel,writing,reg,dL,dH) \
+ PROTO(FXS, REGISTER_REQUEST, (xbus), (xpd), (chipsel), (writing), 1, (reg), 0, (dL), (dH))
+
+#define VALID_CHIPSEL(x) (((chipsel) >= 0 && (chipsel) <= 7) || (chipsel) == ALL_CHANS)
/*---------------- FXS Protocol Commands ----------------------------------*/
-static /* 0x0F */ DECLARE_CMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on);
-static /* 0x0F */ DECLARE_CMD(FXS, CHAN_CID, int pos);
-static /* 0x0F */ DECLARE_CMD(FXS, RING, int pos, bool on);
+static /* 0x0F */ DECLARE_CMD(FXS, XPD_STATE, bool on);
+static /* 0x0F */ DECLARE_CMD(FXS, CHAN_CID, lineno_t chan);
+static /* 0x0F */ DECLARE_CMD(FXS, RING, lineno_t chan, bool on);
static /* 0x0F */ DECLARE_CMD(FXS, RELAY_OUT, byte which, bool on);
-static /* 0x0F */ DECLARE_CMD(FXS, SLIC_QUERY, int pos, byte reg_num);
static bool fxs_packet_is_valid(xpacket_t *pack);
-static void fxs_packet_dump(xpacket_t *pack);
+static void fxs_packet_dump(const char *msg, xpacket_t *pack);
static int proc_fxs_info_read(char *page, char **start, off_t off, int count, int *eof, void *data);
-static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data);
-static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
+static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
-#define PROC_SLIC_FNAME "slics"
+#define PROC_REGISTER_FNAME "slics"
#define PROC_FXS_INFO_FNAME "fxs_info"
struct FXS_priv_data {
- struct proc_dir_entry *xpd_slic;
+ struct proc_dir_entry *regfile;
struct proc_dir_entry *fxs_info;
- slic_reply_t requested_reply;
- slic_reply_t last_reply;
xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */
xpp_line_t ledcontrol[NUM_LEDS]; /* 0 - OFF, 1 - ON */
int blinking[NUM_LEDS][CHANNELS_PERXPD];
};
/*---------------- FXS: Static functions ----------------------------------*/
-static int do_chan_power(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, bool on)
+static int do_chan_power(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on)
{
- int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
+ int value = (on) ? 0x06 : 0x00;
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!lines) {
- return 0;
- }
- DBG("%s/%s: 0x%04X %s\n", xbus->busname, xpd->xpdname, lines, (on) ? "up" : "down");
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- if(on) {
- // Power up
- len = slic_cmd_direct_write(sc, lines, 0x42, 0x06);
- } else {
- // Power down
- len = slic_cmd_direct_write(sc, lines, 0x42, 0x00);
- }
- pack->datalen = len;
-
- packet_send(xbus, pack);
- return ret;
+ DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, chan, (on) ? "up" : "down");
+ return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x42, value);
}
#define IS_BLINKING(priv,pos,color) ((priv)->blinking[color][pos] != 0)
@@ -164,47 +140,34 @@ static const int led_register_vals[] = { BIT(4), BIT(1), BIT(0) };
* - A line number
* - ALL_LINES
*/
-static int do_led(xpd_t *xpd, lineno_t pos, byte which, bool on)
+static int do_led(xpd_t *xpd, lineno_t chan, byte which, bool on)
{
int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
- int value;
struct FXS_priv_data *priv;
- xpp_line_t lines;
+ int value;
xbus_t *xbus;
BUG_ON(!xpd);
xbus = xpd->xbus;
priv = xpd->priv;
which = which % NUM_LEDS;
- if(IS_SET(xpd->digital_outputs, pos) || IS_SET(xpd->digital_inputs, pos))
+ if(IS_SET(xpd->digital_outputs, chan) || IS_SET(xpd->digital_inputs, chan))
goto out;
- if(pos == ALL_LINES) {
- lines = ~0;
+ if(chan == ALL_CHANS) {
priv->ledstate[which] = (on) ? ~0 : 0;
} else {
- lines = BIT(pos);
if(on) {
- BIT_SET(priv->ledstate[which], pos);
+ BIT_SET(priv->ledstate[which], chan);
} else {
- BIT_CLR(priv->ledstate[which], pos);
+ BIT_CLR(priv->ledstate[which], chan);
}
}
- if(!lines) // Nothing to do
- goto out;
- DBG("%s/%s: LED: lines=0x%04X which=%d -- %s\n", xbus->busname, xpd->xpdname, lines, which, (on) ? "on" : "off");
+ DBG("%s/%s/%d: LED: which=%d -- %s\n", xbus->busname, xpd->xpdname, chan, which, (on) ? "on" : "off");
value = BIT(2) | BIT(3);
value |= ((BIT(5) | BIT(6) | BIT(7)) & ~led_register_mask[which]);
if(on)
value |= led_register_vals[which];
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, lines, 0x06, value);
- pack->datalen = len;
- packet_send(xbus, pack);
-
+ ret = SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x06, value);
out:
return ret;
}
@@ -212,14 +175,12 @@ out:
static void handle_fxs_leds(xpd_t *xpd)
{
int i;
- unsigned long flags;
const enum fxs_leds colors[] = { LED_GREEN, LED_RED };
int color;
unsigned int timer_count;
struct FXS_priv_data *priv;
BUG_ON(!xpd);
- spin_lock_irqsave(&xpd->lock, flags);
priv = xpd->priv;
timer_count = xpd->timer_count;
for(color = 0; color < ARRAY_SIZE(colors); color++) {
@@ -245,7 +206,6 @@ static void handle_fxs_leds(xpd_t *xpd)
}
}
- spin_unlock_irqrestore(&xpd->lock, flags);
}
/*---------------- FXS: Methods -------------------------------------------*/
@@ -277,11 +237,11 @@ static void clean_proc(xbus_t *xbus, xpd_t *xpd)
BUG_ON(!xpd);
priv = xpd->priv;
#ifdef CONFIG_PROC_FS
- if(priv->xpd_slic) {
+ if(priv->regfile) {
DBG("Removing xpd SLIC file %s/%s\n", xbus->busname, xpd->xpdname);
- priv->xpd_slic->data = NULL;
- remove_proc_entry(PROC_SLIC_FNAME, xpd->proc_xpd_dir);
- priv->xpd_slic = NULL;
+ priv->regfile->data = NULL;
+ remove_proc_entry(PROC_REGISTER_FNAME, xpd->proc_xpd_dir);
+ priv->regfile = NULL;
}
if(priv->fxs_info) {
DBG("Removing xpd FXS_INFO file %s/%s\n", xbus->busname, xpd->xpdname);
@@ -308,16 +268,16 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd)
}
priv->fxs_info->owner = THIS_MODULE;
DBG("Creating SLICs file for %s/%s\n", xbus->busname, xpd->xpdname);
- priv->xpd_slic = create_proc_entry(PROC_SLIC_FNAME, 0644, xpd->proc_xpd_dir);
- if(!priv->xpd_slic) {
+ priv->regfile = create_proc_entry(PROC_REGISTER_FNAME, 0644, xpd->proc_xpd_dir);
+ if(!priv->regfile) {
ERR("Failed to create proc file for SLICs of %s/%s\n", xbus->busname, xpd->xpdname);
ret = -ENOENT;
goto err;
}
- priv->xpd_slic->owner = THIS_MODULE;
- priv->xpd_slic->write_proc = proc_xpd_slic_write;
- priv->xpd_slic->read_proc = proc_xpd_slic_read;
- priv->xpd_slic->data = xpd;
+ priv->regfile->owner = THIS_MODULE;
+ priv->regfile->write_proc = proc_xpd_register_write;
+ priv->regfile->read_proc = proc_xpd_register_read;
+ priv->regfile->data = xpd;
#endif
ret = run_initialize_registers(xpd);
if(ret < 0)
@@ -326,7 +286,7 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd)
* Setup ring timers
*/
/* Software controled ringing (for CID) */
- ret = SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x22, 0x00); /* Ringing Oscilator Control */
+ ret = SLIC_DIRECT_REQUEST(xbus, xpd, ALL_CHANS, SLIC_WRITE, 0x22, 0x00); /* Ringing Oscilator Control */
if(ret < 0)
goto err;
DBG("%s/%s: done\n", xbus->busname, xpd->xpdname);
@@ -495,9 +455,9 @@ static void poll_inputs(xbus_t *xbus, xpd_t *xpd)
BUG_ON(xpd->id != 0); // Only unit #0 has digital inputs
for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
- int pos = input_channels[i];
+ byte pos = input_channels[i];
- CALL_PROTO(FXS, SLIC_QUERY, xbus, xpd, pos, 0x06);
+ SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_READ, 0x06, 0);
}
}
@@ -522,161 +482,125 @@ static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd)
/*---------------- FXS: HOST COMMANDS -------------------------------------*/
-static /* 0x0F */ HOSTCMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on)
+/* 0x0F */ HOSTCMD(FXS, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high)
{
int ret = 0;
xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
- enum fxs_state value = (on) ? 0x01 : 0x00;
- unsigned long flags;
+ reg_cmd_t *reg_cmd;
+
+ if(!xbus) {
+ DBG("NO XBUS\n");
+ return -EINVAL;
+ }
+ XPACKET_NEW(pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->id);
+#if 0
+ DBG("%s/%s/%d: %c%c R%02X S%02X %02X %02X\n",
+ xbus->busname, xpd->xpdname, chipsel,
+ (writing)?'W':'R',
+ (do_subreg)?'S':'D',
+ regnum, subreg, data_low, data_high);
+#endif
+ reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
+ pack->datalen = sizeof(*reg_cmd);
+ reg_cmd->bytes = sizeof(*reg_cmd) - 1; // do not count the 'bytes' field
+ REG_FIELD(reg_cmd, chipsel) = chipsel;
+ REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1;
+ REG_FIELD(reg_cmd, do_subreg) = do_subreg;
+ REG_FIELD(reg_cmd, regnum) = regnum;
+ REG_FIELD(reg_cmd, subreg) = subreg;
+ REG_FIELD(reg_cmd, data_low) = data_low;
+ REG_FIELD(reg_cmd, data_high) = data_high;
+ ret = packet_send(xbus, pack);
+ return ret;
+}
+
+static /* 0x0F */ HOSTCMD(FXS, XPD_STATE, bool on)
+{
+ int ret = 0;
int i;
+ enum fxs_state value = (on) ? 0x01 : 0x00;
+ unsigned long flags;
+ struct FXS_priv_data *priv;
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!lines) {
- return 0;
- }
- DBG("Channel Activation: 0x%4X %s\n", lines, (on) ? "on" : "off");
- // Make sure we use normal (low battery) power
- for_each_line(xpd, i)
- if (BIT_SET(lines,i))
- do_chan_power(xbus, xpd, BIT(i), 0);
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, lines, 0x40, value);
- pack->datalen = len;
+ priv = xpd->priv;
+ spin_lock_irqsave(&xpd->lock, flags);
+ DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on) ? "on" : "off");
+ ret = SLIC_DIRECT_REQUEST(xbus, xpd, ALL_CHANS, SLIC_WRITE, 0x40, value);
for_each_line(xpd, i)
xpd->lasttxhook[i] = value;
-
- packet_send(xbus, pack);
- spin_lock_irqsave(&xpd->lock, flags);
if(on) {
- do_led(xpd, ALL_LINES, LED_GREEN, LED_ON);
+ MARK_LED(priv, ALL_CHANS, LED_GREEN, LED_ON);
} else {
- do_led(xpd, ALL_LINES, LED_GREEN, LED_OFF);
+ MARK_LED(priv, ALL_CHANS, LED_GREEN, LED_OFF);
}
spin_unlock_irqrestore(&xpd->lock, flags);
return ret;
}
-static /* 0x0F */ HOSTCMD(FXS, CHAN_CID, int pos)
+static /* 0x0F */ HOSTCMD(FXS, CHAN_CID, lineno_t chan)
{
int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
int i;
- xpp_line_t lines = BIT(pos);
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!lines) {
- return 0;
- }
- DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, pos);
- //do_chan_power(xbus, xpd, BIT(pos), 0); // Low battery for normal (non-ring) operation
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- pack->datalen = slic_cmd_direct_write(sc, lines, 0x40, FXS_LINE_CID);
- packet_send(xbus, pack);
+ DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, chan);
+ ret = SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, FXS_LINE_CID);
for_each_line(xpd, i)
xpd->lasttxhook[i] = FXS_LINE_CID;
return ret;
}
-static /* 0x0F */ HOSTCMD(FXS, RING, int pos, bool on)
+static /* 0x0F */ HOSTCMD(FXS, RING, lineno_t chan, bool on)
{
- int ret = 0;
+ int ret = 0;
struct FXS_priv_data *priv;
- xpacket_t *pack;
- slic_cmd_t *sc;
- xpp_line_t mask = BIT(pos);
- int len;
- enum fxs_state value = (on) ? 0x04 : 0x01;
+ enum fxs_state value = (on) ? 0x04 : 0x01;
BUG_ON(!xbus);
BUG_ON(!xpd);
+ DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, chan, (on) ? "on" : "off");
priv = xpd->priv;
- if(!mask) {
- return 0;
- }
- DBG("%s/%s/%d %s\n", xbus->busname, xpd->xpdname, pos, (on) ? "on" : "off");
- do_chan_power(xbus, xpd, BIT(pos), on); // Power up (for ring)
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, mask, 0x40, value);
- xpd->lasttxhook[pos] = value;
- pack->datalen = len;
-
- packet_send(xbus, pack);
+ do_chan_power(xbus, xpd, chan, on); // Power up (for ring)
+ ret = SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, value);
+ xpd->lasttxhook[chan] = value;
if(on) {
- MARK_BLINK(priv,pos,LED_GREEN,LED_BLINK);
+ MARK_BLINK(priv,chan,LED_GREEN,LED_BLINK);
} else {
- if(IS_BLINKING(priv, pos, LED_GREEN))
- MARK_BLINK(priv,pos,LED_GREEN,0);
+ if(IS_BLINKING(priv, chan, LED_GREEN))
+ MARK_BLINK(priv,chan,LED_GREEN,0);
}
return ret;
}
static /* 0x0F */ HOSTCMD(FXS, RELAY_OUT, byte which, bool on)
{
- int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
int value;
- xpp_line_t lines;
int relay_channels[] = { 0, 4 };
BUG_ON(!xbus);
BUG_ON(!xpd);
-
DBG("RELAY_OUT: which=%d -- %s\n", which, (on) ? "on" : "off");
which = which % ARRAY_SIZE(relay_channels);
- lines = BIT(relay_channels[which]);
value = BIT(2) | BIT(3);
value |= ((BIT(5) | BIT(6) | BIT(7)) & ~led_register_mask[OUTPUT_RELAY]);
if(on)
value |= led_register_vals[OUTPUT_RELAY];
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, lines, 0x06, value);
-
- DBG("RELAY_OUT pack: line=%d value=0x%04X\n", lines, value);
- pack->datalen = len;
- packet_send(xbus, pack);
- return ret;
-}
-
-static /* 0x0F */ HOSTCMD(FXS, SLIC_QUERY, int pos, byte reg_num)
-{
- int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
-
- BUG_ON(!xbus);
- BUG_ON(!xpd);
- // DBG("\n");
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_read(sc, BIT(pos), reg_num);
-
- pack->datalen = len;
-
- packet_send(xbus, pack);
- return ret;
+ return SLIC_DIRECT_REQUEST(xbus, xpd, relay_channels[which], SLIC_WRITE, 0x06, value);
}
/*---------------- FXS: Astribank Reply Handlers --------------------------*/
HANDLER_DEF(FXS, SIG_CHANGED)
{
- xpp_line_t sig_status = RPACKET_FIELD(pack, FXS, SIG_CHANGED, sig_status);
- xpp_line_t sig_toggles = RPACKET_FIELD(pack, FXS, SIG_CHANGED, sig_toggles);
+ xpp_line_t sig_status = RPACKET_FIELD(pack, FXS, SIG_CHANGED, sig_status);
+ xpp_line_t sig_toggles = RPACKET_FIELD(pack, FXS, SIG_CHANGED, sig_toggles);
struct FXS_priv_data *priv;
- int i;
+ int i;
+ unsigned long flags;
BUG_ON(!xpd);
BUG_ON(xpd->direction != TO_PHONE);
@@ -686,12 +610,19 @@ HANDLER_DEF(FXS, SIG_CHANGED)
NOTICE("%s: %s/%s is not registered. Skipping.\n", __FUNCTION__, xbus->busname, xpd->xpdname);
return -ENODEV;
}
+#if 0
+ Is this needed?
+ for_each_line(xpd, i) {
+ if(IS_SET(sig_toggles, i))
+ do_chan_power(xpd->xbus, xpd, BIT(i), 0); // Power down (prevent overheating!!!)
+ }
+#endif
+ spin_lock_irqsave(&xpd->lock, flags);
for_each_line(xpd, i) {
if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i))
continue;
if(IS_SET(sig_toggles, i)) {
xpd->ringing[i] = 0; // No more ringing...
- do_chan_power(xpd->xbus, xpd, BIT(i), 0); // When not ringing, VBAT is always Low
MARK_BLINK(priv,i,LED_GREEN,0);
if(IS_SET(sig_status, i)) {
DBG("%s/%s/%d: OFFHOOK\n", xbus->busname, xpd->xpdname, i);
@@ -704,15 +635,17 @@ HANDLER_DEF(FXS, SIG_CHANGED)
}
}
}
+ spin_unlock_irqrestore(&xpd->lock, flags);
return 0;
}
-HANDLER_DEF(FXS, SLIC_REPLY)
+HANDLER_DEF(FXS, REGISTER_REPLY)
{
- slic_reply_t *info = &RPACKET_FIELD(pack, FXS, SLIC_REPLY, info);
- xpp_line_t lines = RPACKET_FIELD(pack, FXS, SLIC_REPLY, lines);
+ reg_cmd_t *info = &RPACKET_FIELD(pack, FXS, REGISTER_REPLY, reg_cmd);
unsigned long flags;
struct FXS_priv_data *priv;
+ byte regnum;
+ bool indirect;
if(!xpd) {
NOTICE("%s: received %s for non-existing xpd: %d\n",
@@ -722,14 +655,22 @@ HANDLER_DEF(FXS, SLIC_REPLY)
spin_lock_irqsave(&xpd->lock, flags);
priv = xpd->priv;
BUG_ON(!priv);
+ indirect = (REG_FIELD(info, regnum) == 0x1E);
+ regnum = (indirect) ? REG_FIELD(info, subreg) : REG_FIELD(info, regnum);
#if 0
- DBG("SLIC_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
- xpd->id, (info->indirect)?"I":"D",
- info->reg_num, info->data_low, info->data_high);
+ DBG("REGISTER_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
+ xpd->id, (indirect)?"I":"D",
+ regnum, REG_FIELD(info, data_low), REG_FIELD(info, data_high));
#endif
- if(xpd->id == 0 && info->indirect == 0 && info->reg_num == 0x06) { /* Digital Inputs Poll Result */
- int i;
- bool offhook = (info->data_low & 0x1) == 0;
+ if(!SPAN_REGISTERED(xpd))
+ goto out;
+ /*
+ * Process digital inputs polling results
+ */
+ if(xpd->id == 0 && regnum == 0x06) {
+ int i;
+ bool offhook = (REG_FIELD(info, data_low) & 0x1) == 0;
+ xpp_line_t lines = BIT(REG_FIELD(info, chipsel));
/* Map SLIC number into line number */
for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
@@ -751,10 +692,13 @@ HANDLER_DEF(FXS, SLIC_REPLY)
}
}
}
+out:
/* Update /proc info only if reply relate to the last slic read request */
- if(priv->requested_reply.indirect == info->indirect &&
- priv->requested_reply.reg_num == info->reg_num) {
- priv->last_reply = *info;
+ if(
+ REG_FIELD(&xpd->requested_reply, regnum) == REG_FIELD(info, regnum) &&
+ REG_FIELD(&xpd->requested_reply, do_subreg) == REG_FIELD(info, do_subreg) &&
+ REG_FIELD(&xpd->requested_reply, subreg) == REG_FIELD(info, subreg)) {
+ xpd->last_reply = *info;
}
spin_unlock_irqrestore(&xpd->lock, flags);
return 0;
@@ -763,9 +707,9 @@ HANDLER_DEF(FXS, SLIC_REPLY)
xproto_table_t PROTO_TABLE(FXS) = {
.owner = THIS_MODULE,
.entries = {
- /* Card Opcode */
- XENTRY( FXS, SIG_CHANGED ),
- XENTRY( FXS, SLIC_REPLY ),
+ /* Prototable Card Opcode */
+ XENTRY( FXS, FXS, SIG_CHANGED ),
+ XENTRY( FXS, FXS, REGISTER_REPLY ),
},
.name = "FXS",
.type = XPD_TYPE_FXS,
@@ -780,7 +724,7 @@ xproto_table_t PROTO_TABLE(FXS) = {
.RING = XPROTO_CALLER(FXS, RING),
.RELAY_OUT = XPROTO_CALLER(FXS, RELAY_OUT),
- .CHAN_ENABLE = XPROTO_CALLER(FXS, CHAN_ENABLE),
+ .XPD_STATE = XPROTO_CALLER(FXS, XPD_STATE),
.CHAN_CID = XPROTO_CALLER(FXS, CHAN_CID),
.SYNC_SOURCE = XPROTO_CALLER(GLOBAL, SYNC_SOURCE),
@@ -799,9 +743,9 @@ static bool fxs_packet_is_valid(xpacket_t *pack)
return xe != NULL;
}
-static void fxs_packet_dump(xpacket_t *pack)
+static void fxs_packet_dump(const char *msg, xpacket_t *pack)
{
- DBG("\n");
+ DBG("%s\n", msg);
}
/*------------------------- SLIC Handling --------------------------*/
@@ -857,112 +801,39 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in
return len;
}
-static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- int len = 0;
- unsigned long flags;
- xpd_t *xpd = data;
- slic_reply_t *info;
- struct FXS_priv_data *priv;
-
- BUG_ON(!xpd);
- spin_lock_irqsave(&xpd->lock, flags);
- priv = xpd->priv;
- BUG_ON(!priv);
- info = &priv->last_reply;
- len += sprintf(page + len, "# Writing bad data into this file may damage your hardware!\n");
- len += sprintf(page + len, "# Consult firmware docs first\n");
- len += sprintf(page + len, "SLIC_REPLY: %s reg_num=0x%X, dataH=0x%X dataL=0x%X\n",
- (info->indirect)?"I":"D",
- info->reg_num, info->data_high, info->data_low);
- spin_unlock_irqrestore(&xpd->lock, flags);
- if (len <= off+count)
- *eof = 1;
- *start = page + off;
- len -= off;
- if (len > count)
- len = count;
- if (len < 0)
- len = 0;
- return len;
-}
-
/*
- * Direct/Indirect
- * v
- * FF FF FF FF WD 06 1
- * ^---------^ ^ Reg
- * | Write/Read
- * |
- * SLIC #
+ *
+ * Direct/Indirect
+ * |
+ * | Reg#
+ * | |
+ * | | Data (only in Write)
+ * | | |
+ * | | +-+-+
+ * v v v v
+ * FF WD 06 01 05
+ * ^ ^
+ * | |
+ * | Write/Read
+ * |
+ * Chan#
+ *
*/
-static int parse_slic_cmd(const char *buf, slic_cmd_t *sc, slic_reply_t *requested_reply)
+static int handle_register_command(xpd_t *xpd, char *cmdline)
{
- char op; /* [W]rite, [R]ead */
- char reg_type; /* [D]irect, [I]ndirect */
- int s1, s2, s3, s4;
- int reg_num;
- int data_low, data_high;
- xpp_line_t lines;
- int ret;
-
- ret = sscanf(buf, "%x %x %x %x %c%c %x %x %x",
- &s1, &s2, &s3, &s4, &op, &reg_type, &reg_num, &data_high, &data_low);
- lines = (s4 << 24) | (s3 << 16) | (s2 << 8) | (s1);
- switch(op) {
- case 'R':
- if(reg_type == 'D' && ret == 7) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x\n", s1, s2, s3, s4, reg_type, reg_num);
- ret = slic_cmd_direct_read(sc, lines, reg_num);
- if(requested_reply) {
- requested_reply->indirect = 0;
- requested_reply->reg_num = reg_num;
- }
- } else if(reg_type == 'I' && ret == 7) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x\n", s1, s2, s3, s4, reg_type, reg_num);
- ret = slic_cmd_indirect_read(sc, lines, reg_num);
- if(requested_reply) {
- requested_reply->indirect = 1;
- requested_reply->reg_num = reg_num;
- }
- } else {
- NOTICE("%s: Bad read input: ret=%d buf='%s' reg_type=%c\n", __FUNCTION__, ret, buf, reg_type);
- goto err;
- }
- break;
- case 'W':
- if(reg_type == 'D' && ret == 8) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x %X\n", s1, s2, s3, s4, reg_type, reg_num, data_high);
- ret = slic_cmd_direct_write(sc, lines, reg_num, data_high);
- } else if(reg_type == 'I' && ret == 9) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x %X %X\n", s1, s2, s3, s4, reg_type, reg_num, data_high, data_low);
- ret = slic_cmd_indirect_write(sc, lines, reg_num, data_low, data_high);
- } else {
- NOTICE("%s: Bad write input: ret=%d buf='%s' reg_type=%c\n", __FUNCTION__, ret, buf, reg_type);
- goto err;
- }
- break;
- default:
- NOTICE("%s: Bad input: ret=%d buf='%s' op=%c\n", __FUNCTION__, ret, buf, op);
- goto err;
- }
- return ret;
-err:
- return -EINVAL;
-}
-
-static int process_slic_cmdline(xpd_t *xpd, char *cmdline)
-{
- xbus_t *xbus;
- struct FXS_priv_data *priv;
- slic_cmd_t sc;
- xpacket_t *pack;
+ unsigned chipsel;
+ unsigned data_low = 0;
+ unsigned data_high = 0;
+ char op; /* [W]rite, [R]ead */
+ char reg_type; /* [D]irect, [I]ndirect */
+ int reg_num;
+ int elements;
+ bool writing;
char *p;
- int len = strlen(cmdline);
+ reg_cmd_t regcmd;
+ xbus_t *xbus;
+ int ret;
- BUG_ON(!xpd);
- xbus = xpd->xbus;
- priv = xpd->priv;
if((p = strchr(cmdline, '#')) != NULL) /* Truncate comments */
*p = '\0';
if((p = strchr(cmdline, ';')) != NULL) /* Truncate comments */
@@ -971,22 +842,85 @@ static int process_slic_cmdline(xpd_t *xpd, char *cmdline)
;
if(*p == '\0')
return 0;
- len = parse_slic_cmd(p, &sc, &priv->requested_reply);
- if(len < 0)
- return len;
- if(!sc.lines) {
- NOTICE("%s: no channels are marked. Skip.\n", __FUNCTION__);
- return 0;
+
+ elements = sscanf(cmdline, "%d %c%c %x %x %x",
+ &chipsel,
+ &op, &reg_type, &reg_num,
+ &data_low,
+ &data_high);
+ // DBG("'%s': %d %c%c %02X %02X %02X\n", cmdline, chipsel, op, reg_type, reg_num, data_low, data_high);
+ if(elements < 4) { // At least: chipsel, op, reg_type, reg_num
+ ERR("Not enough arguments: (%d args) '%s'\n", elements, cmdline);
+ return -EINVAL;
}
- dump_slic_cmd("WRITE_SLIC", &sc);
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd) = sc;
- pack->datalen = len;
- packet_send(xbus, pack);
- return 0;
+ if(!VALID_CHIPSEL(chipsel)) {
+ ERR("Bad chipsel number: %d\n", chipsel);
+ return -EINVAL;
+ }
+ REG_FIELD(&regcmd, chipsel) = chipsel;
+ switch(op) {
+ case 'W':
+ writing = 1;
+ break;
+ case 'R':
+ writing = 0;
+ break;
+ default:
+ ERR("Unkown operation type '%c'\n", op);
+ return -EINVAL;
+ }
+ switch(reg_type) {
+ case 'I':
+ REG_FIELD(&regcmd, do_subreg) = 1;
+ REG_FIELD(&regcmd, regnum) = 0x1E; // FIXME: card dependent...
+ REG_FIELD(&regcmd, subreg) = reg_num;
+ break;
+ case 'D':
+ REG_FIELD(&regcmd, do_subreg) = 0;
+ REG_FIELD(&regcmd, regnum) = reg_num;
+ REG_FIELD(&regcmd, subreg) = 0;
+ break;
+ default:
+ ERR("Unkown register type '%c'\n", reg_type);
+ return -EINVAL;
+ }
+ if(
+ (op == 'W' && reg_type == 'D' && elements != 5) ||
+ (op == 'W' && reg_type == 'I' && elements != 6) ||
+ (op == 'R' && reg_type == 'D' && elements != 4) ||
+ (op == 'R' && reg_type == 'I' && elements != 4)
+ ) {
+ ERR("%s: '%s' (%d elements): %d %c%c %02X %02X %02X\n", __FUNCTION__,
+ cmdline, elements,
+ chipsel, op, reg_type, reg_num, data_low, data_high);
+ return -EINVAL;
+ }
+ regcmd.bytes = sizeof(regcmd) - 1;
+ REG_FIELD(&regcmd, data_low) = data_low;
+ REG_FIELD(&regcmd, data_high) = data_high;
+ REG_FIELD(&regcmd, read_request) = writing;
+ BUG_ON(!xpd);
+ xbus = xpd->xbus;
+ if(!down_read_trylock(&xbus->in_use)) {
+ DBG("Dropped packet. %s is in_use\n", xbus->busname);
+ return -EBUSY;
+ }
+ xpd->requested_reply = regcmd;
+ if(print_dbg)
+ dump_reg_cmd("FXS", &regcmd);
+ ret = CALL_PROTO(FXS, REGISTER_REQUEST, xpd->xbus, xpd,
+ REG_FIELD(&regcmd, chipsel),
+ writing,
+ REG_FIELD(&regcmd, do_subreg),
+ REG_FIELD(&regcmd, regnum),
+ REG_FIELD(&regcmd, subreg),
+ REG_FIELD(&regcmd, data_low),
+ REG_FIELD(&regcmd, data_high));
+ up_read(&xbus->in_use);
+ return ret;
}
-static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
+static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
xpd_t *xpd = data;
char buf[MAX_PROC_WRITE];
@@ -1009,7 +943,7 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns
if(p >= buf + MAX_PROC_WRITE)
return -E2BIG;
*p = '\0';
- ret = process_slic_cmdline(xpd, buf);
+ ret = handle_register_command(xpd, buf);
if(ret < 0)
return ret;
mdelay(1);
@@ -1017,6 +951,41 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns
return count;
}
+static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len = 0;
+ unsigned long flags;
+ xpd_t *xpd = data;
+ reg_cmd_t *info;
+ byte regnum;
+ bool indirect;
+
+ if(!xpd)
+ return -ENODEV;
+ spin_lock_irqsave(&xpd->lock, flags);
+ info = &xpd->last_reply;
+ indirect = (REG_FIELD(info, regnum) == 0x1E);
+ regnum = (indirect) ? REG_FIELD(info, subreg) : REG_FIELD(info, regnum);
+ len += sprintf(page + len, "# Writing bad data into this file may damage your hardware!\n");
+ len += sprintf(page + len, "# Consult firmware docs first\n");
+ len += sprintf(page + len, "#\n");
+ len += sprintf(page + len, "#CH\tD/I\tReg.\tDL DH\n");
+ len += sprintf(page + len, "%2d\tR%c\t%02X\t%02X %02X\n",
+ REG_FIELD(info, chipsel),
+ (indirect)?'I':'D',
+ regnum, REG_FIELD(info, data_low), REG_FIELD(info, data_high));
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ if (len <= off+count)
+ *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+ return len;
+}
+
int __init card_fxs_startup(void)
{
diff --git a/xpp/card_fxs.h b/xpp/card_fxs.h
index bed1a4f..2af2884 100644
--- a/xpp/card_fxs.h
+++ b/xpp/card_fxs.h
@@ -23,22 +23,18 @@
*/
#include "xpd.h"
-#include "slic.h"
enum fxs_opcodes {
XPROTO_NAME(FXS, SIG_CHANGED) = 0x06,
/**/
- XPROTO_NAME(FXS, SLIC_WRITE) = 0x0F, /* Write to SLIC */
- XPROTO_NAME(FXS, CHAN_ENABLE) = 0x0F, /* Write to SLIC */
+ XPROTO_NAME(FXS, XPD_STATE) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, CHAN_POWER) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, CHAN_CID) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, RING) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, LED) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, RELAY_OUT) = 0x0F, /* Write to SLIC */
- XPROTO_NAME(FXS, SLIC_INIT) = 0x0F, /* Write to SLIC */
- XPROTO_NAME(FXS, SLIC_QUERY) = 0x0F, /* Write to SLIC */
/**/
- XPROTO_NAME(FXS, SLIC_REPLY) = 0x10,
+ XPROTO_NAME(FXS, REGISTER_REPLY) = 0x10,
};
@@ -47,12 +43,8 @@ DEF_RPACKET_DATA(FXS, SIG_CHANGED,
xpp_line_t sig_status; /* channels: lsb=1, msb=8 */
xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */
);
-DEF_RPACKET_DATA(FXS, SLIC_REPLY, /* Get status of a single SLIC (for debugging) */
- xpp_line_t lines;
- slic_reply_t info;
- );
-DEF_RPACKET_DATA(FXS, SLIC_WRITE,
- slic_cmd_t slic_cmd;
+DEF_RPACKET_DATA(FXS, REGISTER_REPLY, /* Get status of a single SLIC (for debugging) */
+ reg_cmd_t reg_cmd;
);
#endif /* CARD_FXS_H */
diff --git a/xpp/card_global.c b/xpp/card_global.c
index dda4480..4740eab 100644
--- a/xpp/card_global.c
+++ b/xpp/card_global.c
@@ -29,13 +29,24 @@
static const char rcsid[] = "$Id$";
+DEF_PARM(charp,initdir, "/usr/share/zaptel", "The directory of card initialization scripts");
+/*
+ * BRI: Temporary software workaround for firmware limitation:
+ * - The BRI firmware count PCM channel number globally across subunits.
+ * - The module parameter 'bri_pcmshift' enables us to cheat and shift
+ * each B-channel, 4 bits for each subsequent subunit.
+ * - Eventually, this should be fixed in the firmware, otherwise we won't
+ * handle PRI (all the space we have is 32bits).
+ */
+DEF_PARM(bool,bri_pcmshift, 1, "TESTING: shift bri PCM bits by subunit number");
+
extern int print_dbg;
static bool pcm_valid(xpd_t *xpd, xpacket_t *pack);
/*---------------- GLOBAL Protocol Commands -------------------------------*/
static bool global_packet_is_valid(xpacket_t *pack);
-static void global_packet_dump(xpacket_t *pack);
+static void global_packet_dump(const char *msg, xpacket_t *pack);
/*---------------- GLOBAL: HOST COMMANDS ----------------------------------*/
@@ -66,9 +77,6 @@ static void global_packet_dump(xpacket_t *pack);
BUG_ON(!xbus);
BUG_ON(!xpd);
lines &= ~xpd->no_pcm;
-// if(lines == 0)
-// return 0;
-
/*
* FIXME: Workaround a bug in sync code of the Astribank.
* Send dummy PCM for sync.
@@ -86,6 +94,10 @@ static void global_packet_dump(xpacket_t *pack);
}
buf += ZT_CHUNKSIZE;
}
+ if(bri_pcmshift) { /* workaround for pcm problem in BRI */
+ lines = lines << (xpd->addr.subunit * 4);
+ RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines;
+ }
pack->datalen = sizeof(xpp_line_t) + (pcm - start_pcm);
packet_send(xbus, pack);
XPD_COUNTER(xpd, PCM_WRITE)++;
@@ -176,6 +188,10 @@ HANDLER_DEF(GLOBAL, PCM_READ)
}
// DBG("lines=0x%04X\n", lines);
+ if(bri_pcmshift) { /* workaround for pcm problem in BRI */
+ lines = (lines >> (xpd->addr.subunit * 4)) & 0x7;
+ RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines;
+ }
if(!pcm_valid(xpd, pack)) {
return -EPROTO;
}
@@ -201,6 +217,7 @@ HANDLER_DEF(GLOBAL, PCM_READ)
XBUS_COUNTER(xpd->xbus, PCM_READ)++;
spin_unlock_irqrestore(&xpd->lock, flags);
xpp_tick((unsigned long)xpd);
+
return 0;
}
@@ -222,14 +239,44 @@ HANDLER_DEF(GLOBAL, SYNC_REPLY)
return 0;
}
+HANDLER_DEF(GLOBAL, ERROR_CODE)
+{
+ byte errorcode = RPACKET_FIELD(pack, GLOBAL, ERROR_CODE, errorcode);
+ reg_cmd_t *bad_cmd;
+ char xpdname[XPD_NAMELEN];
+
+ BUG_ON(!xbus);
+ if(!xpd) {
+ int xpd_num = XPD_NUM(pack->content.addr);
+ snprintf(xpdname, XPD_NAMELEN, "....#%d", xpd_num);
+ } else {
+ snprintf(xpdname, XPD_NAMELEN, "%s", xpd->xpdname);
+ }
+ NOTICE("%s/%s: %s CODE = 0x%X\n", xbus->busname, xpdname, cmd->name, errorcode);
+ switch(errorcode) {
+ case 1:
+ bad_cmd = &RPACKET_FIELD(pack, GLOBAL, ERROR_CODE, info.bad_spi_cmd);
+ dump_packet("BAD_SPI_CMD", pack, 1);
+ break;
+ default:
+ NOTICE("%s/%s: %s UNKNOWN CODE = 0x%X\n", xbus->busname, xpdname, cmd->name, errorcode);
+ dump_packet("PACKET", pack, 1);
+ }
+ /*
+ * FIXME: Should implement an error recovery plan
+ */
+ return 0;
+}
+
xproto_table_t PROTO_TABLE(GLOBAL) = {
.entries = {
- /* Card Opcode */
- XENTRY( GLOBAL, NULL_REPLY ),
- XENTRY( GLOBAL, DEV_DESC ),
- XENTRY( GLOBAL, PCM_READ ),
- XENTRY( GLOBAL, SYNC_REPLY ),
+ /* Prototable Card Opcode */
+ XENTRY( GLOBAL, GLOBAL, NULL_REPLY ),
+ XENTRY( GLOBAL, GLOBAL, DEV_DESC ),
+ XENTRY( GLOBAL, GLOBAL, PCM_READ ),
+ XENTRY( GLOBAL, GLOBAL, SYNC_REPLY ),
+ XENTRY( GLOBAL, GLOBAL, ERROR_CODE ),
},
.name = "GLOBAL",
.packet_is_valid = global_packet_is_valid,
@@ -245,9 +292,9 @@ static bool global_packet_is_valid(xpacket_t *pack)
return xe != NULL;
}
-static void global_packet_dump(xpacket_t *pack)
+static void global_packet_dump(const char *msg, xpacket_t *pack)
{
- DBG("\n");
+ DBG("%s\n", msg);
}
static bool pcm_valid(xpd_t *xpd, xpacket_t *pack)
@@ -267,9 +314,89 @@ static bool pcm_valid(xpd_t *xpd, xpacket_t *pack)
XPD_COUNTER(xpd, RECV_ERRORS)++;
if((rate_limit++ % 1000) <= 10) {
ERR("BAD PCM REPLY: pack->datalen=%d, count=%d\n", pack->datalen, count);
+ dump_packet("BAD PCM REPLY", pack, 1);
}
return 0;
}
return 1;
}
+#define MAX_ENV_STR 20
+#define MAX_PATH_STR 60
+
+int run_initialize_registers(xpd_t *xpd)
+{
+ int ret;
+ xbus_t *xbus;
+ char busstr[MAX_ENV_STR];
+ char xpdstr[MAX_ENV_STR];
+ char unitstr[MAX_ENV_STR];
+ char subunitstr[MAX_ENV_STR];
+ char typestr[MAX_ENV_STR];
+ char revstr[MAX_ENV_STR];
+ char init_card[MAX_PATH_STR];
+ char *argv[] = {
+ init_card,
+ NULL
+ };
+ char *envp[] = {
+ busstr,
+ xpdstr,
+ unitstr,
+ subunitstr,
+ typestr,
+ revstr,
+ NULL
+ };
+
+ BUG_ON(!xpd);
+ xbus = xpd->xbus;
+ if(!initdir || !initdir[0]) {
+ NOTICE("%s/%s: Missing initdir parameter\n", xbus->busname, xpd->xpdname);
+ return -EINVAL;
+ }
+ snprintf(busstr, MAX_ENV_STR, "XPD_BUS=%s", xbus->busname);
+ snprintf(xpdstr, MAX_ENV_STR, "XPD_NAME=%s", xpd->xpdname);
+ snprintf(unitstr, MAX_ENV_STR, "XPD_UNIT=%d", xpd->addr.unit);
+ snprintf(subunitstr, MAX_ENV_STR, "XPD_SUBUNIT=%d", xpd->addr.subunit);
+ snprintf(typestr, MAX_ENV_STR, "XPD_TYPE=%d", xpd->type);
+ snprintf(revstr, MAX_ENV_STR, "XPD_REVISION=%d", xpd->revision);
+ if(snprintf(init_card, MAX_PATH_STR, "%s/init_card_%d_%d",
+ initdir, xpd->type, xpd->revision) > MAX_PATH_STR) {
+ NOTICE("%s/%s: Cannot initialize. pathname is longer than %d characters.\n",
+ xbus->busname, xpd->xpdname, MAX_PATH_STR);
+ return -E2BIG;
+ }
+ if(!down_read_trylock(&xbus->in_use)) {
+ ERR("Skipped register initialization. %s is going down\n", xbus->busname);
+ return -ENODEV;
+ }
+ DBG("%s/%s: running '%s' for type=%d revision=%d\n",
+ xbus->busname, xpd->xpdname, init_card, xpd->type, xpd->revision);
+ ret = call_usermodehelper(init_card, argv, envp, 1);
+ /*
+ * Carefully report results
+ */
+ if(ret == 0)
+ DBG("%s/%s: '%s' finished OK\n", xbus->busname, xpd->xpdname, init_card);
+ else if(ret < 0) {
+ ERR("%s/%s: Failed running '%s' (errno %d)\n",
+ xbus->busname, xpd->xpdname, init_card, ret);
+ } else {
+ byte exitval = ((unsigned)ret >> 8) & 0xFF;
+ byte sigval = ret & 0xFF;
+
+ if(!exitval) {
+ ERR("%s/%s: '%s' killed by signal %d\n",
+ xbus->busname, xpd->xpdname, init_card, sigval);
+ } else {
+ ERR("%s/%s: '%s' aborted with exitval %d\n",
+ xbus->busname, xpd->xpdname, init_card, exitval);
+ }
+ ret = -EINVAL;
+ }
+ up_read(&xbus->in_use);
+ return ret;
+}
+
+EXPORT_SYMBOL(run_initialize_registers);
diff --git a/xpp/card_global.h b/xpp/card_global.h
index 5ab8124..94e073b 100644
--- a/xpp/card_global.h
+++ b/xpp/card_global.h
@@ -31,6 +31,9 @@ DEF_RPACKET_DATA(GLOBAL, DEV_DESC,
byte type; /* LSB: 1 - to_phone, 0 - to_line */
xpp_line_t line_status; /* hook/ring status, depending on unit */
);
+DEF_RPACKET_DATA(GLOBAL, REGISTER_REQUEST,
+ reg_cmd_t reg_cmd;
+ );
DEF_RPACKET_DATA(GLOBAL, PCM_WRITE,
xpp_line_t lines;
byte pcm[PCM_CHUNKSIZE];
@@ -45,6 +48,12 @@ DEF_RPACKET_DATA(GLOBAL, SYNC_SOURCE,
DEF_RPACKET_DATA(GLOBAL, SYNC_REPLY,
byte mask;
);
+DEF_RPACKET_DATA(GLOBAL, ERROR_CODE,
+ byte errorcode;
+ union {
+ reg_cmd_t bad_spi_cmd;
+ } info;
+ );
/* 0x04 */ DECLARE_CMD(GLOBAL, DESC_REQ, int xpd_num);
@@ -52,5 +61,6 @@ DEF_RPACKET_DATA(GLOBAL, SYNC_REPLY,
/* 0x11 */ DECLARE_CMD(GLOBAL, PCM_WRITE, xpp_line_t lines, volatile byte *buf);
extern xproto_table_t PROTO_TABLE(GLOBAL);
+int run_initialize_registers(xpd_t *xpd);
#endif /* CARD_GLOBAL_H */
diff --git a/xpp/firmwares/FPGA_1151.hex b/xpp/firmwares/FPGA_1151.hex
new file mode 100644
index 0000000..e554933
--- /dev/null
+++ b/xpp/firmwares/FPGA_1151.hex
@@ -0,0 +1,576 @@
+#
+# $Id: FPGA_1151.hex 2478 2006-10-17 13:50:18Z dima $
+#
+:020000040000FA
+:80000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6AD6FF4000E0E508006AD6FF4000E0E508006AD6FF4000E0E5080000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4455544455557475577775577675577775577765566665563625523235D2E37C2B511115511115511115511167
+:80008000155111155111155111155111155111155111155111155111155111155111155111155111155111155111155111155111000000000000000000000000000000000000002552222552222552220025522225522200000000001AA1111AA1110025522200001AA1111AA111001AA11100001AA1111AA11100001AA1111AA1111AA113
+:80010000110000002552222552222F21F112122F21F112122552222552222552222552221AA1111AA111001AA1112552222552222F21F112122F21F112122F21F112122552222F21F112122F21F112122F21F11212255222000000002F21F112122F21F1121200002552222552221AA1111AA1112552222F21F1121200001AA1112F21F149
+:8001800012121AA111002F21F112122F21F112121AA11100255222255222000000000025522200001AA1111AA11125522200255222000025522200000000EFEAFAAEAE5F56F66565000000000000000000000000001AA1111AA1110000000000000000000000000000255222000000002552222552220000255222255222255222255222E0
+:800200002552222552222552222552222552220025522200000000000000000000004F44F444444F45F554541AA1114F44F444440000000000000000255222255222000000004554446F61F116162F21F11212000000CAACCC2F2DFDD2D22F21F112124F48F884846F61F116164554444AA4446F65F556566F61F116164F41F11414455491
+:80028000446F65F556566F65F556566F65F5565600000000002F21F112122F21F112120000004F4CFCC4C46F6DFDD6D62F21F112128AA8882F21F11212004F44F444446F65F556562F21F112122F21F11212006F65F556563F3FFFF3F3EFE5F55E5E006F65F556566F65F55656000000008F8CFCC8C8AFACFCCACA255222000000CFCCFC12
+:80030000CCCCCFCCFCCCCC008F8CFCC8C825522200CFCCFCCCCCCFCCFCCCCC000000CFCCFCCCCCCFCCFCCCCCCFCCFCCCCC00000000CFC4F44C4CCFC4F44C4C000000008F8CFCC8C8AFACFCCACA255222CFCCFCCCCCC55CCCC55CCC4AA444EFE4F44E4EE55EEEC55CCCC55CCCEFE4F44E4EEFE4F44E4EEFE4F44E4E00000000C55CCCC55C42
+:80038000CC000000008F8CFCC8C8AFACFCCACA255222CFC8F88C8CC55CCCC55CCC4AA444EFE4F44E4EE55EEEC55CCCC55CCCEFE4F44E4EEFE4F44E4EEFE4F44E4E00000000C55CCCC55CCC000000008F8CFCC8C8AFACFCCACA255222CFC8F88C8CC55CCCC55CCC4AA444EFE4F44E4EE55EEEC55CCCC55CCCEFE4F44E4EEFE4F44E4EEFE4FD
+:80040000F44E4E00000000C55CCCCFC3F33C3C3AA3330000008F8CFCC8C8AFAFFFFAFA2F23F33232CFC8F88C8CCFC3F33C3CC55CCC4AA444EFE7F77E7EEFE3F33E3ECFC3F33C3CC55CCCCAACCCDFD6F66D6D00EFE7F77E7EEFE7F77E7EEFE7F77E7E000000008AA888BAABBB3AA333000000CFCCFCCCCCEFEEFEEEEE2F22F222228AA88867
+:800480003AA33300CFCCFCCCCCEFEEFEEEEE2F22F222220000EFEEFEEEEEEFEEFEEEEEEFEEFEEEEE000000004AA4441F14F44141155111000000CFCCFCCCCCFFFFFFFFFF3F33F333334AA44415511100CFCCFCCCCCFFFFFFFFFF3F33F3333315511100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000008F84F448489F95F559591F11F11169
+:8005000011000000CFCCFCCCCCFFFEFEEFEF3F32F223238F84F448489F91F119198558884F4CFCC4C4FFFEFEEFEFBFB2F22B2B955999855888FFFEFEEFEFFFFEFEEFEFFFFEFEEFEF00000000CFC4F44C4CFFF4F44F4F3553330000008F8CFCC8C8BFBFFFFBFB3F33F33333CFC4F44C4CF55FFFC55CCCCAACCCFFFFFFFFFFFFF3F33F3FF50A
+:800580005FFFC55CCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000004554444F42F224242AA2220000008F8CFCC8C8BFBFFFFBFB3F33F333334554444F42F224244554448F8CFCC8C8FFFFFFFFFF7F73F337374F42F22424EFE6F66E6E2F2EFEE2E200455444FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000004AA4446AA6662AA2220000D5
+:8006000000CFCCFCCCCCFFFFFFFFFF3F33F333334AA4442AA22200CFCCFCCCCCFFFFFFFFFF3F33F333332AA22200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000CFC4F44C4CCFC6F66C6C2AA2220000008F8CFCC8C8BFBFFFFBFB3F33F33333CFC4F44C4CCFC2F22C2CC55CCCCAACCCFFFFFFFFFFFFF3F33F3FCFC2F22C2CC55CCCFFFFEF
+:80068000FFFFFFFFFFFFFFFFFFFFFFFFFF000000004F48F884846F68F886862552220000008F8CFCC8C8BFBFFFFBFB3F33F333334F48F88484255222008F8CFCC8C8BFBFFFFBFB3F33F333330000BFBFFFFBFBBFBFFFFBFBBFBFFFFBFB000000008AA8882F28F88282255222000000CFCCFCCCCCFFFFFFFFFF3F33F333334F48F884842552
+:800700005222008F8CFCC8C8BFBFFFFBFB3F33F3333325522200BFBFFFFBFBBFBFFFFBFBBFBFFFFBFB00000000455444655666255222000000CFCCFCCCCCFFFFFFFFFF3F33F333334F48F884846556664554448F84F44848FFF7F77F7F7F73F33737DFDAFAADAD4F44F4444400655666455444FFF7F77F7FFFF7F77F7FFFF7F77F7F00005D
+:8007800000004F44F444447F75F557573F31F11313000000CFCCFCCCCCDFDFFFFDFD1F13F331314F44F444447F75F557574F44F444448F88F88888DFDFFFFDFD5F57F775754F44F444444F44F44444DFDFFFFDFDDFDFFFFDFDDFDFFFFDFD000000004F44F444445F55F555551F11F111110000008F8CFCC8C88F8FFFF8F83AA3334AA4445F
+:800800001F15F551514AA4448F88F888888F8FFFF8F87AA7774AA4444AA4448F8FFFF8F88F8FFFF8F88F8FFFF8F8000000004F44F444445F57F775751F13F33131000000CFCCFCCCCCDFDEFEEDED1F12F221214F44F444441F17F771714AA444CFC8F88C8CDFDEFEEDED1F16F661614AA4444AA444DFDEFEEDEDDFDEFEEDEDDFDEFEEDED3A
+:80088000000000004AA4445AA5551AA111000000CFCCFCCCCCDFDFFFFDFD1F13F331314F44F444441F17F771714AA4448F88F888888F8DFDD8D85AA5554AA4444AA4448F8DFDD8D88F8DFDD8D88F8DFDD8D80000000000000000000000000000000000005F5BFBB5B52F2FFFF2F2000080010000000000000000000000000000000000000D
+:800900000000000000000000D0510F480000000000000000000000000000400100000000000000000000000000708F0D0000000000000000000000000000000000000000000000000000000000F04FFE8004001800000000000000000000000040010000000000000000000000000070C10600000000000000000000000000000000000061
+:800980000000000000000000000000F04FFE8002004001008004148002800414800200008002800400002148000000484001002148000010F277C2000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE808401800200000071
+:800A0000100200001002400140110240010000400128140000882800008088028002E08207008084010000200100000000000000120000400100000000000014000000000050358084410128004840818102214860118002211A01148002211A041400B01281041480028004148828108204808802214800CF5506481800280000000021CD
+:800A8000000000210014001002400100004001280000808802000088280000F08CBF000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000100200000000002800008008000000280000F0AA2100002002000000100200001002000080018001000000000000002200002008E7
+:800B00000000F09F5D00000000000040020000000000000000000000000000000000000082000000DFE20D000000000000000000000000000000120000000000000000000000000000CFE70B000000000000000000000000008001000000000000000000000000280000F0F5FA0000800200000000000000210000002100000000000000D8
+:800B80000000000000000000F051E8000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000000002002000082000000000000F0B1AA000000000000000000000000000000000000000000000020020000000000F0644100000000000000000000000000000000000034
+:800C000000002200000000000082000000FFB40A0000000000000000000000002002000020022424000000000000000000000070FC0F000000000000000000000000000000000000210000000000000020080000F0EFA70000000000000000000000000028000000284002008002000000000000000000CF490D0000000000200100820061
+:800C800000200100001C01000000000000000000000000002028021F23010000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000240000000000000000280000000000004F6409000000480000200100000012000000000000000000000000000000000000007BD700000017
+:800D00008004000012000000200100000000210000000000000080020000000000F0DA9A000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FF87
+:800D8000E40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000020020000000000000080040000F03C530020040000000000000000002001000000000000000000000000000067
+:800E0000000000AF420A000000000000002001000000000000000000008001000000000000000000D0E30E00000000000000200100000000000000000022001800000000000000000000EF38080000000000000000000000000000000000000000000000000000480000001FEB030000000000000000000000000000000000000000000035
+:800E800000000000000000F04FFE00000000000000001200000000180000000000008001000000000000000000F0F17E000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000012200112200100200100000000000000000000000000000000DF880900000000000000000000000000000000C2
+:800F00000000000000000000000000000014EFE8030000000000000000000000000000000000000000000000000000000000F04FFE00000000000080810100120012000000000000000000000000000000000000005FF7020000000000000000000000000000000000000000000000000000000000F04FFE00800400000000800200000085
+:800F800010021880080000140000480000000000280000000021143FD803000000000000182001121812200100200100000000000000000000000000000014F0F3FC00000000000000000000800100000000000000001800000000000000000000AFA30F000000000000800112000000000000000000000000000000000000000000F0B98C
+:80100000B50000008004000000800118800100000000000000000000000000000000000000AE1B000000A0444A0400A0111A011212A0111A0100000000000000A0111AA1111A010000000000000000004F290CA0448004A0444A0400A033A03112121AA1111A4112022B11A098800800150114005AA5111AA511000000A02280020000243F
+:801080002110F2824F004800000000001AA31180011A01A011218001880000400100A0511A0100000000280000000021009FAC0F800442000000001A033A8101A011A011212418A081200800141001A0511A21040000008002220000002124F0DFAA000000000000000000000000000000000000001880010000000000000000008F2F06C4
+:80110000820000000000000000000000000000000000001800000000000000000000141F340E481B21B01122B411324219B24291212B9419B24239112B94322F1429F34291322D912AC4912E421CE82264112E4296E12264192CA4292CB491C2421B29241B29421B2923B481324219B24298212B84112B84222B84222B842229A842882E9A
+:8011800042CFFE0D481B61481B21421B212119B64291212B941B212BA41B212B84322F1428F34281322D812B422D912E521CE922EC11E82264192E4296C1439E212CB491C2421B692CB49122B49132421B282394212B8419B2429A212B84222B84222B842229B82294822E422FB40800480000000000280000000021800188000040010089
+:80120000800400000000800200000010022FD40F82000000000012000000000000000000000000008001000000000000000040F13449008200000000000000000000000000000000000000000000000000000040013736004200000000802102000000240012A018000010010020040000000020020000002400F0D2CE0000000000000073
+:801280000000000000000000000000000018000000000000000000F0D73E000000000000000000000000000000000000000000000000000000000000FFE40F0000000000001200000000000000000000000000000000000000000000008F740F0000000000001800000000000000000000000000000000000000000000002F9503000000DC
+:801300000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0088000000000000000000000000000000000000000000000000000000005FD702008800000000000000000000000000000000000000000000000000420000F074123E
+:80138000000000000000000000000000000000000000000000000000000000480000F01A3F000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000000000000000000000000000000002D
+:80140000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000E
+:801480000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00820082000000000000000000000000000000000000000000000000000014149F7F02004800000000002800000000218001880000400100800400000000800200000010022FD40F2008000000000000000000000000000000000044
+:801500000000000000000000000014706303200820080000000000000000000000000000000000000000000000000040018F730E0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000B1
+:801580000000000000000000000000000000F04FFE00CA0448000000002A022800004012022B11A098800800150114004A0448000000002A02280000401202214F5F0280040000000080020000001002188008000014000048000000000028000000002100BD6F008A0442000000002820020000104282011A0882004001110048200400E1
+:8016000000008002220000002124F0739F000000200800000000000000000000000000000000000000000000000000B0910C000000000000000000000000000000000000000000000000000000000014EFE803481B21B01122B411324219B24291212B9419B24219B14229F24291222F1429D212A9421CE922C4812E4216E12264192E42B8
+:8016800096C1429AC2421B292CB49142B29122B49132421B282394212B8419B24218B14228B24228B2422892822A84E822B42C01481B61481B21421B212394212B1419B24299212BB419B24229F24291222F1429D212B922D412E922C5912EC21E812E4296E12264193CE419C2421B292CB491C6421B29421B2923B481324219B242982132
+:801700002BA419B24228B24228B2422892822B4229E822F465822022880400000000800200000010021880080000140000480000000000280000000021B0470E82008002000000A014000028000000000000000000000000008008002008000040B14F0D20080000000000008800800400200200000000000022000020080000004800002D
+:8017800014F0211D00C20000000000220082002848240012288200001001002004000000008222002028044002004F8507000022000000001A0400000000000000000000008002000082000000000000006F4204000000000000200100000020040000000000000000008028088200008004000070A40200000000000000200820820820B3
+:801800000200000080080082121800000000000000000088008BA5000000000000001800002282004A0200000000000018180000802808000000000000D03F080000000000000020080000000000000082008008000000008008000042008008100A000000002001280012224880820220810400480040020000004218000000008088047F
+:801880000000006FE7018004220048000080020082480000202182080020041A040048000000480080040000008200486F3C0400000000202201000000120000000000004200000000000000000000000000F049E90000280042002880022081A284482800200128004800422C2404000080840120040042008842000000D0360200000055
+:80190000002081010000001822008004000000200100000000000000000000800880F4B172000000000020040022280000000088008001202128082028080000800400800880040000F07BAD008004002002428028222488A8488882288082248801881288202224015842184820218401C28882A0484280280C8A0400008F7E0542008063
+:80198000044800202A0200004A82020080012004004200820020A8840080040088000000800C88002D7B0000004A02426822A0418A0448009200A041824A0222A02480840A000000800448882024840420042004202824A8849F260900208402280028880080080000A0C200882218923A248A2129019220018A21812101000082000020A0
+:801A000004882048F1B96420248404488024010000000000008008808908000000A08442480000000000000000002004AF210E000000004888004818A0282200800600228002200400000000C20080084A084888428008004200B0110C000020044A022006004220042800000000228280280400000000422004000088200488000088CF50
+:801A8000D50D004820220200928026A828A0412002324290226218808A24040086018028880488000000008A024820080048211C748108484200424AA4244A26A42882AAA16818A049828A02226AA4A4A02E2A086828B2E2C8CA24892881288DA88418A05442C8A0C4A0C4800448202C044886A1C8DBF92004002A064880A6426A8E24A4F2
+:801B0000484A0A2218AA220122C200B212724A08921A8109C28009929AAC411288C282008248CAA848CA0888A0C842008F46020020042A022A011A084A82088AA4A24AA486800258A8588228228A8585A422008218CA0482200400A044824A088A0800CA84840888C842CF3A0100008200808401188A8401188218823880014A028001187C
+:801B8000800118802184011848188008200848002008002004426FBC084A0480A4664AA6447A2724A9276AA6959AA1354AA5773AA331185AA5519A8B84A8123AA2E6CAA855BAA8448AA899A0D18AA8991AA484124A044AA444884AA48C824A84A4C4CAA444A088A0888AF817DA80A44480A46C684AA4447AA389FAAA377A2BA8246AAFB377
+:801C00002AAAA22AE3219542282B7388AAA81388A0773A51118AE819A1889AADCC9AA9D9CAA81120A84C4AA4C44AA4268AA8EC484AAC4C00242B44B0C2FCC3B8A04448004AA6644AA4734AA47262FAA3EC8AAC8CD2CAA52AAA22A1722B62EAAADC2AAA82327AA6995AA58B5E419AA9995AA1D59AAD99125AA4415A84A8C4CAA488A0EC4807
+:801C80004A24A8C8CAACCCA0CC21CAAC883FB3054A8404A0644AA6666AA677AAAFAEEAA2FD9AAD8CFAAAFEFAAFAA3AA2722BFBFEB2EAAFA22AA8577AA7BBFAAFDFDED19AB991A99DDAADD91AA999DAAD515AA5CCCAAC48CAACCCCAAEC8EA2CA8CCCAACCCCAACCC2BCCCEC2CAEC390E00002248221A242228A24120081A8482840242822890
+:801D000082004A024A82A82488800888800888004880048A048280048A048A0482001F470A0000000000180080010018120018000000000000000000000000000000000060183F2E0E481B21B01122B411324219B24291612B941B282B9419B44229FA4291A22F1429D212AB424E912E421CEA2264112E4296E12265192CA4292CB5D1C2F5
+:801D8000521B292CB19122B49136421B282B841B282B8419B24298412B84A22B84222B84222B842AA4842E422F290F481B61481B21421B212394212991612B941B282993612B94A22F1421FA4211D012BB22F442912CC1B12EC21CE82265182E5286C1538E212CB5C1C2121B682CB58182B181B64291212B841B28239421299A612B84A209
+:801E00002324B24228B24238222B8426B28E0F20880400000000800200000010021880080000140000480000000000280000000021B03F0C1A820200002842A0818A0480A44288229200802684228202808188218801000018486842002004008820A448C8004A68148F7F012008824800482004A0854288202404200812000028200488AF
+:801E80000000240080880920088820A4842004004A0814F06DCB00A280840480024212888842A8282026082C081248222A018820813881820040024820A4434280088822428A048084286C24A04842FF8A0F2A0180080048428088A4142084A4848001004A020028228004188001000018828800004800202804428008007F21090000005B
+:801F000000000000000000290242000022281800008008002A0100888A0400480000002008F04FAE00200220041A84010000008004C200000000420082423A0880220120A4214A22220248800882202C24044200FFD40B0000008081010000000080342280040020222401009A0288221220013242222200800482A08448482008B0A50CC4
+:801F800000220048200400000000422008000000200280280400008082042882C22004820000008004F0B7C42001002084042004004800420000188082080000002008008002822004002288000000800880D4CF02482A0400000000008848C8A2A028000048228812528812002084B152081220240420088280840880040000004DF600E6
+:802000000020040048182004800120048004488004000042A01880020020822108480000420000004800F04D4A8025020042004812002084A184E8200A800168882021051242A01842B0820400624A09488A048280240C0000800880F44C4C00002004420048800482420048004220044A0200820000881A8201182800880000288800204A
+:8020800004004200B01F05800400002004004248002004004A020020019A840400200400004880240200008800002004001B9B008004008004202408188004880048A0184280240400880048888A862888A82420088220040000828888A0282828F0C3D8000012A0120000008024048001185200808808001800C2000000008008000080DB
+:80210000044880240A80027F640D4800284842480020080012C24A08D2820080080048480048A028001200808804422008C800002800684288F0747900008002008008C2488842200800828232480000820000000020080000420000000088222006147F8B050022420048004800000048000000800C4842002026882404800200282004E7
+:80218000200448A0486280220420082FFC020020218181010000200100C82004200400008028040080280880084A880400A0848200822A080000882FFA07202822A243221220040082000012421A0828A800008820040000421800000000C88880044800008008F0D39A800448004800A0848248A02892008021848134428858488812201D
+:80220000880C1C240800480000004A0842A028C200A0248008211CF8FEDB202428026AA4114A812424084A88A4491A84A8C892D2921A88AC69802404184288C24A868484ACC2800A008A8C2824882428A4444AA8C4C822C86A8AA82814F0CD43008228621A21A24180A4C48A2888A8944A88044A858485042A8804C84A2424084800282044
+:80228000A89920080042484AA48C4A2428880462288A02684AA48A8AF888378084041A83A26400004848428021248488A1844AA1264AA18CCA0818C8D8DA8408CAA88C42420088AA84AC24482A0800C8888220A88862202E8202CFDC0D000000480000000000200800000000008002288828882880828802288002000082000000F0D8475C
+:8023000000A0222A27A13152A044CAA4444AA488DAAD940020A4D55AA577FAAF88CAAC44121AA8111AA9CCEAAEEEEAAE444AA63B3A03CAAE662AA288CAAE66EAA66E82A0444AA466EAA6466A26A2A8AA08EF6B06A0442AA2731AA1314A014AA444424AA8A24AADF44AA488884AA9D5DED22B777AB792AD88CA29A1815AA551CAFCC1C1CA69
+:80238000EC1CAC6ECAA67F1AA1624AA66ECAA4AACAAE66EAA66EAAA2848AAA26CAACEEEAAECE2E222BAAAA1AF216F92084A4223AA315125AA1444AA4CCCA28A4A88AADD4CA2C2428A8D45AB552A7EC8AAD4C4AAC111AA5999AA944CE81CAACCC4AACC6AAAC918AA8CA2AAC84886AACC6CAAC4C8AAACCCAACCCAAAA666AA6668ABAE2AA2A98
+:80240000F0D85BA044482AA2125AA4745AA14448CAAC8C4A88AAD46AADCCCAAC88CAA8D5DABDF2EB2CAED88AA8C51AA551CAACCC4AE41EAEC41BAECAAC8EAAACB3CAA8CAAAACEE882AACC6CAAC488AAACCEAA8268AA8EEAAAAECAABAC26E2AF0389E0000800118008A048A048A048A04009A0482288242200442984222422A0822A012A094
+:802480008248224822822008828084A248A048288228828F3A0B8220026200000000800142120080A41448008001200842200400000082802482044800808482048A04F0C8D480B411021B21421B212394612B1419B24299212B94112B94222F1429FA4291222D912AC4912E421CE82264112E4296E12264192CA4292CB491C2C21B292C03
+:80250000B89122B491B242B881324219B24298212B84112B84A22B84222B842229A842882E421FD30F481B61481B21421B212119B64291212B9419B2429B212B94222F1429FA4211222D912B422D912E521CE922EC11E82264192E4296C1439E212CB411C2C21B612CBC9122B411B242B881324219B24298212BA419B242283A42222B84B1
+:802580002229B82294822E427F470400480000000000280000000021800188000040010080040000000080020000005012142FDD0F8200008004002002200C421222000000002081818421090080282804000028800800000000004F6D0BA01A80A1142A01488084020080068004424882004800828008A08222001800A24A010088C82086
+:8026000084A82880828222284881F8BD6500188025A412480020222202422848184A0246220412800488008819A11820024282002242008028AC824280022880C2824001FFCB04800280018004480000884800000088000020892104A082008021282488010022008028088002200882CF870F000022A0140000008200208102004220040A
+:802680000028800282482888000000004888008242004828200428F0DC32008002184200288828C800800442486822622842822002420082004880020080A484888222884200C8002008A048883F2705002820828401228082048200808184840248484880024800008022880200004A28A88422884888428820242228044A02DF6F0C0001
+:8027000000182004800888008004422822A024228008002280822888240400002004008800004800000088829F7B0242488082040020044A022904888A02004821484A084A0200200182820000380048288200800A824880080000C89F320D80068002208204002820818284248802210080288102422004A0428A8404884200808482A84F
+:80278000246888002004428008F0C67B80010000000000800800182200000020022082080000800800824220040048004A080088A048F04FC6002280020028424220048A24A182C2188222004888001A2202289848888084048818482008422288284848824882422024882888FC624C8005006200000028240080828402420048A0420020
+:80280000800400882888008A022084868804488882004282000042F0264A00802182040048008800482800E288002820020088800400882200E8480000002004008848420028882AF4D3B8A042122001122002284A01002A2104220018C218220088281A0488200428888022012880A24800288024282224022A2402003F47012800002017
+:8028800004008220822408488082042148808208004848800400280028C8000088200880044222004222F0216200224800004AA1210028CA01008A21842108222024A8421282422812421A882621A48100208124082004A084420020282408005FA2074242004818488025A9418248821A8481014812921A2829048042A2124A012001C0C0
+:8029000042C21A8AA31CA0852024A828200A822882200882888214DF320220A242202204004822380000C8180000808A24041280A22812820012904200000000484200002084080048EFDC0618002224800200001602800A29180268800200230524821888802925082488002084880400A042000020842484F264B700004A012100228A43
+:802980008328048A8108210018424A0100C02228200100008002202188880200A200000000002282AFEC0D0068002C022800222C012C0200CAA181280021A01C80A84180282241018212184820888582088004008028840820843242F029C42024A422682CB64282A212283A23890A23A119222B912B848AAC135AA8311A8CAC884622B1AB
+:802A000022C2929AA16A428A25A9C84AA89582989A8B290288884828CA84AC482242484A84A4686246217E66012838181A011A0180248C052B48C280288C06822A1182A3244A84884222A3C2528242283224AA22A2614232C84A8824A428A220044AA248CA22A82442482A86F6ACECA043222022042B444AA217886AAA5B5A83B8428E8700
+:802A8000A4192B374A88A4CC22222A82A6529AA5444A82A9111A2884A15B241E22A248CA24AD2AC2A084422A086A2888082A888888AA88F0F95820040048244822488004488044220848000020082100800888004221000048800482200882200882200882F0A466A051523AA2732E222B3321A033AAAA2F1E9229E829F952B22F22F27265
+:802B0000722BFF2AAA913E326AA4822B666AE622E626F672F22F29BCE2AE73481A01E023F9B2B22F22B2B2AFC4DAADA8AAAA88A0446AA6C6424AA66688A0C46A24A6224AA266FF92043AA5631AA2316AB612B142A4337AA7AADAEA21F162622F29F9D2B22F23F3F2F22F27BF62AEB3BEB22BEE2ABA32A3EA8EF24E622F21B992A46A9A5B03
+:802B8000119AED13A7AAFAAD773E122BEA6AA6FFDAAFAACA0CEAAE224AAC44EAAE22882AA2E662EEC22B668AB862F678DBA0511AA5333AA3332F27B732A3551AA3EECAE8259DA2DED22B8DDED22F27B772AD825AAD372B663AAAFEAAEC22FE62627E722F2CB4E2A6738EC15AA5FF6AE621F1B2F22F23B3B2AB66FAA7BBEAAE88CAAC66AAD3
+:802C0000AAE4CAAC44AAAAA2AAAAE6EAAE222BAA4AA4EE3F87041AA5331AA1317E722F25B572A7777AA7EECAE92CFDC2F22F2DBDD2E82DFDB2F22F26BF62AFF7BABAE2AEF76AA7EA3EE22F27E623B2B2A66AFAEE1DACD91BFBFAEE2DBCB2EF29B9B2AA62FAAFFF6AAECCCAACEEAAAAC4CAACCEAAAAA6AAAAE6EAAEEE2BEECEC2CAFC4C2563
+:802C8000800100220020222922080080228922A9249242A0242084A124984A82210480092A0898488800004800800400484220047FBA0E2200284228A041228A2424212419A24324484222808422028082040000180012004212200880088848888280840888824AE218F4132A80B411021B21421B612396612B1419B64299612B9419B486
+:802D000042A94A2F1429F242912AD412A9421CE92AC4812E4216E12264192E4296C1C29AC2C21B2D2E421B29241B29421B2923B68136421B682B861B282B8413B84228BA4228BA42289A82AA84E82AF441BE001B61581B214E121B616A91412B1419D6229961299B612D92AAE41421F242912AD412B922D412E92AC5112AEC11F822429672
+:802D8000F1224216C1C31E212EC21B2D26B291D422B49132621B2923B28114B281366213B842B281B24228BA422ABA422A9AA22B4A21AE42AF9E0D00000000000080020000001042820188000040010080040000000080020000200821F05F8D001814A024581800241218C21A840842388008288A850400288820880448E022850820A463
+:802E00002400A88A0600482088084AA8282268A822AF3E0A1122000042424252420020812401882B42988A041022842221A214200129012122121221802222048A24228808420000888214822F340DA024148024A54142420080248403183288E286822A241502808A2A85384180044A222AC142482A242222AE424A8822A284A0848280A4
+:802E800084CA224222226F55011412002200001AB4422181288188240424808184098084820100189012D02201200100008200880000800888A288826F930400000020812121044200480000004200004810022A010022008200002088082008822882004A02004306422001124832A0484880011848238168244E82003820A248282021D1
+:802F00002801422C84012081032B21286A81882284820C00428220222C882822F6C6258004122021A421A018200480612458004221A01280228802129012004200202121B81202488822820000802C228802228880F4F86300000000124252202104008242230800422004802408A04330122002220022380048A84A08880088004AA8849B
+:802F80008082F27AAC808205202104212004181A04000048249022481A48A224128024220200282880020000422828800E82282228C220060057C88081041A02230200A04842284A8801222128481022A8218008220012202104800428802404004882284A288404008088A842F0FD47000080020068218002800420040080010040020023
+:803000008022084821200100000000000042000080F8DB848081011830420048200812881A0430422AC4422022012480218204182021240280820120044822288842888AA424224282208A08823DA2200280A2122824602248421A268404800200004A280A2A04242082022888E0220480024800004280880400224220044A029B71008AA8
+:80308000012001484248128001245220010058800520048005808204002C048002002A0428200888200880042880F2E3F98003200812242C81016280810222A012212280041012324228004A0200903200420018000020040020840C424842F08A5500822880042800181220A4412021042004182C242224820122181880082824002212AF
+:8031000080810248480088004248000082482F250F4880240310A2122222282901211082024A81012228421800468204224682220448602220840280228228024A22048002428880021F5C01484A01208424044220044A02422004422004000000001880280A488021020000222A288208888028828E82888868188F4C0918281A84822174
+:80318000819122124220022818481842001800202282292301243200282821402222012200488002482242828028024828FD9C200200000024000020022001001002002D421092222084311248182424184200000048002004000000425D470082124200124002200423412201249012208401204C82012B1400904248800300480048005D
+:8032000082208422280228208202F0544120084818000022262201182C0224248042822211A2214212A80010022712282301A061002200800C00000000003022F09C5A00922818A0141A822431521A031E5210A2311AA421243829A521244AB242A42CA0242E121E1222F0B2829E422AA453483A2121250280A444424282A02482C26AA8D3
+:80328000442A24A48446A126AF8F015AA51818125A054A21A234286AA44142247A25F442122024A521182A250225B21274122201287E6228425A022F2102A0221A8601288288282A88A4C8800A8A88A8A82AA2A848A7F4A0224A22A16260212CF412322E422A119232222B152421224E122B6120A4445212222AE524A3122B442B425E12E4
+:8033000020B422022F24022D222F228604122A22A622AA268AA484208684A6224222A042885FD40F4222008A04482448244826820448A042242A0422001002200428214288901280011800000082200882200882A04820083FF203BAA3261AA1511AA1195E1227212B111AA1372A83D122B112F322322B333AE323C1322F21A3112AB3329B
+:80338000B242B462B532E121A8117AE323B322A6335A61253E222A021AA5773A27A1224AA444884AA4C64A84A2642AAE44484AA462484AA462E78CA0451AA6111AA1C51AE1257112F252522B117AA3326AA7115E522F21B152A5337E521E322B752B774AB172B242B4F2AD531E522B113AE421F33371BA6B142CE223A2752CD222B462A4EF
+:80340000731AA1224AA4444AAC444AAC44EAAE646AAE44CAAC46AEE22B62CABC22D6FE081AA1713AA3331AA1547E322F27B612B152F572322F26B712F352522B112F25B512F172422F21E225B57211A2732AA7444AAC177E323E327AE327F372712B732F2DEF21A2273A27A1116AA6773AA2224AA4EC88AAAAA4CA088AAAE6EA8EA4CC6AF8
+:80348000B2C2A844AA3E3DA07F3AA3331AA155DAE527E325E525B562B552A3555AF752522F25F552522B772F27F552725E522B173AE325A544485AAC575E522F23F332722F27F152732BFB3F2CEC21E223A2711AE223B362A6773AA3226AA2EC4AAEEC4AACCCEAACEC6AAECEAAACCAEABAE2E82AA8AA8F43020000001820022001000000BB
+:80350000202421040010220400420022001002000080044880848204800242F0F1C28005008AA1414E1220044A014A21011A2404230400400248800158A01212884224280022481800488880888428820A4A2888220814FF850A481B21181B2146B2117642B211B64291612B9419B64299412B942AF442B33AF442B13AD412AB421CEB2236
+:80358000C4812F2264152E4296E122641D2CA4292CBC91C2421B29241B29421B2923B68132421B282B841B282B8413B84228BA4228BA4228BA42A84A88AE42990E2A94412A351146B21136621B4190616A99414A9B6198481CAB414EA11AC4A129C4B12D521CDB22EC150A9E2148DE21141E212ABC81C2521B692E521B284AB19132621382
+:8036000038621B2823B681B242BA81B242283A42A22B24A22334A229E22AF42FCE00820000000000800242000000001800000022140000480084000000800200000010026EB440444204296181450280C44258881246844482842141048242450824002829AA121227232820C112008329A421200AA28882C880084B8222A800886FF20E98
+:80368000A018407861028283314483088034480040C84820058D24400244E041041A4434484384341221418400182094484A88011688B118840480142CD814084F530E201C0233C11841292134884823A58489C1240027845688C1463088522482001E44222B581B2184284662213014A904811A2421C488821AAA82A04884C220226228B4
+:80370000884928F8318A102411446826204818840400484248000018C0245048401402801224D526850212002009288026046089181A04C084488D240070CB0B1880010000202104000000812200200224004200002200800821001004A0410040088281604480025FFA022218442470122801800400298128842142249518001008006172
+:80378000458221831C8494122812814C21242304800888884A280100A8818281F0B428A012005022838101004200218800224448008042480224484118388A444422011800808204802801884A88018820420C005F660580C1140000001A040018202401813883010000004424008082042882846321840141004288008100848242888C26
+:8038000002B7120048124341342200102C013844412A114422C2544828604121004400824004411AC254814308128480420428284440648826088C0260428A71260C68482800444A2184054C022829911841200480110212444C042382112822A114108884848221242202424004B852812A040088852424A1344FA6091240028494D0841B
+:803880000216028901244002441200400400222448282100160410120412841842208444088C08004182A0928184F0A4EC80071E2241C493A24149024721388140361C38001844800244614924922629113822301410A4434481492925A121801484242261C9812A14C82C828CB2A4415884E867580000122444C0484A4108122C210141F9
+:8039000025944429A2414A014400002024228821941440223124008C128824820484884810840820188884033FEB0221230242223024104284018444304480468402408201280010A4214841450800414C040010140400428244008844604210F4AD3C00418D24304C4142222438002F2411A8141881C012644C3124290300162441042134
+:803980003012212381220100124400428B18608110A412A018818A820100AFA60A42008D4428200200000020014C8102288420049022858201100812A012000080010042811008401808008140D8380D004D42100225440424800124478200304418484850246041484C0484001014084C8214120444002800803218A0122818840086087E
+:803A00007FAD0727488D128322C142C9242422820448904C424449142804002C0240044410141404000010C248201484A21482824488A01880C188896148C243F2A4116F8E048C2484041240A841522046840480142214824428014912140880C112805182240024121A840100C08418A08228431488282882280288F06B4C0022484444A3
+:803A8000221006288421800221D04202612564C249048052848449048B42C042811014844402422064412860442024284408422842874218D09A09001018180812001684341812182011282121213114008001A0521818184AC1144C8181011843C1182880118808892892A418411818490541485F780A451884240200482698442226044B
+:803B000028008504222A84841422C416E082984242214618689400A44A021086044862008D4489C424844843C2289044849022847F420244274860213AE2C482A21460652242167844E4836545C74420A145562C415244214341985412C1448B144D184D18184C81B11421051A114C84B16482880845A8A88F4808AE88B668424B868B82CA
+:803B800047581AD82A44B246142852464E4441442D424E122283C43248249054212F4431262C31268F44B714A24441844B12878443F4324262163C428F615482436164C04256C444424828888CA5488B8448424B428F8308A0E84C052A8BF455C4004F27D2CCF24868C5582ACB464F43B22892644B3129F4481287814314C218CF82E66476
+:803C0000F726245847822E542B12442F42F21A6425D442C514AF8147F218422116E422B2344212961E421E144A7264E4413598878447838B8CC7C15AC334CB318B94CF8131184D6C84C7C22FB80B0030248223821402613022504248004448008504400224002841811018040000411084244208406488004C2288028B2410F82CBBE02C85
+:803C8000F4763E6D2665F65A52AF24FC6E2C4F62F24E6E4F64F468484E422F64F444464F655146C7E46F467664F626222B44CFC4F464646F635222CD1C2F44F6464E4F45B142F44422E74447444E48246552A6614B518F84A451CFC4A4625AA1A81E588F88FCE884CB448F84A6CA8FC8F828288F84FCACE8CFC5F9ECC89AA9EF3FB10F4E9D
+:803D0000426F63F7262CCFC1A15D83F26C6E6F23F15E6E4F64F26C6E2F25F1527245F654766F61F1524E2F27F7525627212F25F426444F46F4667625F28C8CEF42F24ECE4B542B644E4A7FD4F44C54CF54D5ACD122B126D124B144F5484C4AF44C4C6AA6154F4EFADCCC4AEC4CFE44C4CAACC68FC808CAFC84C4CFE9F82A288F89B966F7E1
+:803D80001C1E242B664B734D262D266B554AFE6C2E2F46F24C6C2B758FE7B462E484F6464C2725674447646F46F664266F26B262F67E6C4F47F66476D0CEFA4C7ECFE57544F442466F66F74A51424E4A255A222D6265F414148F8484F54C4C2E645AB784FAC8CC8F8CBCC8BA4CFCCCC89ABC98F83CA48F85FCACECCFC4F8E6CCBAF9E4F42C
+:803E00009F8D4FF2E2626F63F326266F63F352522B66CFC6F67476EFC5B652F3786C7E322B446FC4F476466F65F556466F67F766626F27F66868EF87F464464F6616F42EACCFE6F7DC5E4F44F46666EFE4F44E5FCFC4F44D5E65DE22B122D264F14614CFC4F44444CFC4F464647AB7E4FEC8CC4ABCCCFC44C4CFCCFC78C88B8ACF4BEA8E88
+:803E8000FEA4E4CFCEFEE6ECBEB24F4EFE1C13302600841884430222000084444044C8241008000081001018120810060021001024018400608144128922C1245048F08C3A00104294124480044400004449542222244934422A441404412840040044214002400400002800818200608842002608145FC5062CF41124C5F2112487241FAA
+:803F000041724AD241F64E121D24AF249921AF2419F54A944F82F44A9143F242954F82D41AF924485CF9244A1CF8264A56F1264A87192FA27498C54A8F49C24A1F49C2421F4952281F4932481F49324A1F48B26AD141B24AF91128AB9453B94A7924B84A39A42BB44782A9FB244889FB244A6F6C0CACD141F62C121F812672112CF4116CBF
+:803F8000C9F111284C79118C7B11F848B44F83D41A69832F54F93448ADA12B435CF826588DB14BC25E814F827188D124F588213CF588252CF581282E5A1F48D628F191644AF181286B161789A3F2114427441F81F24A341B292B844783AB24922BB44781A93316AB344D1217F50082002008000000280000000021800188000040011002FE
+:8040000048000000004400000020021002DE6E00244410028183141248088C04E02112440420440400704422C224222A14C214182821004381020085048820018400A0828AF4881485048A725206433582A0A12C0524448863040043D48454486828400442428A442C8643028120040043844208CC2412C81430848904A081488A816184C0
+:804080008184001C18749F0E4A31C2211E224821844C245886C1306849944883E242C42410C44243042B81C1A23E442D224184621384213128424281184C048418C1444F8804228A818401842E88C6481A84E843F8AA2410044188184042188204004034142100002084044800282210420410860244838202442008800181821848004CCC
+:804100004908F0A6E5000012180050240084004008484490284183044224422128614222400261008081041A1468812088489888004144128800223F1907434242144A1428345883EA41A624521048642849D22A28A141481288288522426841C9042823C8682E9448284443E1221114E242014C2104420042890C8394488A4438288482E7
+:80418000EFBF0E430244A11280C4488E242B12284E181048145824463A149048C048C04A2C4232144D42C042C0484B122C44442481731602162465C118A0844088A48460844818848C4228F2484C00108241440812844C840400209822888025C2148228008904261824A282222C0822100420840260840088308884105484C8880088FF3E
+:80420000E2094AA1418481402148820160249012460821411818102A32188285040080184824118CA441222302A1883088C184421A0281440020117442849218CD7640860618568212180A422594184A120420618488463822238161652C86682349041E246243041008682021848182A5416048842843041004A22A241882A158CD37140C
+:804280004002004D182A28E28492341220881454820000412244220000289012128008104604604283518200008888128C81489814448008F0DD4C14D02243381846D218322827223AC424121823B81644442A41A88183742234284CE3224452843632442816B4327C58148408E042C1242923D48461AB18484130481243484804814B29D7
+:804300002E5443288493881F350E4B58008061414018A841218C2404872400490412200145A8A4000022008041C442004082028C949884890888481816C8840000430848AFFE081304202116146142222420D12249044C61442C1248C2161228286044812D2426082D282C94189014248444224C04214996C4840042845844825084E04439
+:804380000140F4CE83C016002260A4281281304842481221423042222B4148006022241A6421408C2459244868C42C2201214242809144224A084E84A0844286044C0CCCA884883F330A82D02A0281200290482048084A01A490682A8488E428052902008C0422252CC822304298C014400418A02848248081885284004A0140E221F49238
+:80440000B940140860418648041280018001822311041828201204218004B01404842518484824022301008312488492B88122A0120080088126F82A7810220147844042A12124121002002311E48228084188200218002281888006006028C84426128848048820080089A824CC1128C82840F47F7F602100206244814140242124094BC5
+:804480001442484244414AB11424084A112494186150844E181286384441A98BA1214248284902688C820EC842C8200888C14928A182EF6B07100450822B28803428242216182804249244308200214280544828E04204880020026120084842D20012001280410880042744846FB50C6028C490822148244162460848244482002B148137
+:804500008200181008400400295C2400412220C9141008A041B01804860420A448328442471814CFBD052D48C062836244114429A44125C822874A21C9121846388844A22982FA42144418244C994452242C0154C8F02248A04844102282216248C01480034C2154841024012588F4CE3F341E1482282F86B3623A8881183258588F88EBE2
+:80458000297514AC544D92442C88E9A4B282A5182C86044D4689F436462A7428B892F39A448F21DE86EA82D56432244BA34F2B21A4258926FB7414A6C874528BC456E843AD253A31488524E444C1444D5346F8C4CA503227684342D648D444F626211E442C7142ECA6C242A142C7214CF444888E44CB626B8247472AE84A39142F2242289E
+:80460000C438E784446E482CF144188A644423E228F88214D046CD422364C48AB24CA884AE42928B48C24F4874C4E8C89414AE448D88C78A9CF8885457B1B0443418A51A78147A437A41B664F24E288D22A331524E882C514223FD1A52EF867242AE59A86B45522E244823F5161C421E244D42C5E6847882744852264AF41A3C244E2496D8
+:8046800052442249C7C84C3628B88CC3948098C84B824E884F81B9948478C8B424FA275A201404806412008C24C2486081A041C048201828A1241242001883044A8229840120A412A0924841A08212228A24A249A0492892A04820292488F2867250212F85F12C2ACFE3F11C1475F76F2E6F42F24E4441AF23F3A2922FE819F61E1C4B8816
+:80470000C768EF62F27674CEE44F6BFB84944B996F63F64262EFA495166B324F63D346F4141C1E426FE7FFE4E8CF42C222CE9E2F28EB2113B234D3CEE484E7C4F544EC8F810B8FC1D148C114A0454F46F65818CFC2D368A1228F85F57A4E1FDA4BB257B512752CF83C5ECF65756EFF6A2E6F46D7CE3524EF46F6F2BA2FEABB46F44E7E6FCC
+:804780006CF8DCD66F64FA767CEAEE42FFC4F44B986F62E326F6CCCE6F41F56EF84F63932643F1D5454F4FFFE4E14FE2A6444FCBFFA4B41E64CAB474F36E6C4E488FCFF448E8CFC7A7A78F8DFB48CCDEC46AFAF4E42EE48F81F124ACCFC9F86EACCFCDDDEEFD8DD8143F74F414544FA2F23C3ECFE5F54727F7E66F42F24E56C5FA7A76AF5F
+:804800002EF9DAFAEF61F15E5E6F6CF8CE5EEFE6F27EB88FEDFD34F46F4EBD94F924766F66D6AEF8125AEFE7F73636EFC2F4125C4FF1F47676EF8FFF24684E622F29F592B23E326F45F57436ED4C4D7CCFC4F34CEC8FC5AFB68F8DFB4CDC4F4CADB6CF4FFF6C6CCFC5F12CBCCFC8F92AA8DAEDE2FDFC6A347F55F51414CF82F26C2CCFE493
+:80488000F46327FFE6F26674EFC4B734F37A748FAFF3DEFAEF64F56A5E6F6CF8DEDC6F66FA76BC8F8EEB42FFF4744F29FD24666F66F64ECE6FE1F5EE5E2FE3F72A6E4FCDFDD45F6F6FFFDF9849E426F6BAB22BBAFEA4DAF47436EFC6F6E4FCCFCFF34CAC8FC7AFB78F8DF94CDC4F4DADB6CFCFFF6CECCFCDF964BCCFC9FC68EC4F6DFD2CC3
+:80490000EE8FB50C290122008447221A542460229648C2482049066CA2484C2209A0246044188912269412839484100249094130248C04482008922081C24844120042827F360A8603C112414C041042AC145022124448242E4824A014000000611002241222422642742202184860818302224889810449840A4098884308846B2BC0527D
+:804980001F4152281F417248F21164A3D441B24AD1C1B24AF91168AB945781AB944B42AF14F924482F147934F842914F83C4914FA2D418F8264A56F1245A96E1A2645DACE549C25A1F4DE222F591248F22F19124CB141F49366A1F49B26AD141F26A921F89B64AB995B44AB9B4B44A3B242B94478B29F9A448984FAAF49A6CD0A49561892A
+:804A0000F51124A7261F417442D1C1B222D1C1F44A941FC1B642FB15282B844F82E414F9B448271443F342812F81E454FB221A8D956FA2FC48814F22651CACF148254FB26D18ACF5C9242E5A1F48F4285215B46CB981B4687111B46E3991A7461FC9B448BA91F64A944B4BABA44399229E482F447A9688FA865A8FDE0800000000004004DA
+:804A80002800000000210080080000140084000000000000000000004041F1D2BD001245129841188904260C4A08C8D0224882042C0180874204904889A481C942642218410020B81298A483828439548C024A4208006DA84181CCF82884446084CF840B428284412122142011048B811081C42828428324741218688C48234408242608FA
+:804B0000895B484922912480418802411014981480884994C818D082A2682442128641F285132024556864482A11084D2890C489284691C28902E08411522A5E2826B8149442828446B288C2282618A1124189024E18A418A6942C80D148E1C112A4282A49348818272AC4AAD468D8A48E61188725DF8C0200404801460118442081082431
+:804B8000B04282044818A0840084428412419674244A84410480A828004286240480140842504822810041006B26100421204208204208400120C122451888041281004004442110044981029012702A82048441008240088400A0484A0280F451F4100153435225C01110845121C212211F41946AC8D02484C16C8842904480143268E03B
+:804C00008214926489068A020010A418B0884288B842011A58A41A686418A850844228826F830900794252140090241648314210C2421628148634428C0400444002450A2244B028840224184048A481814C1828B842081245EA81181422A284490220D4D707450112C02281160100809811701481264A182C912492890442304480068D80
+:804C80004230644C018A02002D2242002608200186082024210883242482F8E2B2602249041658281428211880C118308490882230148400321225184C082A01281E448A0244C68244688144848A1102800818488911A24126648424106641F0291EA0146819522238442183C621C3444482C2124004A04850422D142001882CE462C482FE
+:804D000000004A9128284828200481411A02288428478849A4422883044EA449180218BFB5068041342190188400212004890448122902402864448148000043321440648830148051223608440083218101009200221840688428FFD10D2AB52201A5C218742889A22146244118C25E604C2A81329481615634248184C48466823224495E
+:804D8000A341A62494241E242138A18B253088411A02388190C447812B876A012A646682453844288FA60B407424B1116222165828483484A04120088424200481A0142442201426190241C098800C811261844D120016882881412804F024488192449018F05E99402214C94280459811292494428C8201D02C8481048C4482014481589A
+:804E000000408841088B6843184416644443C2248638821084648810C4C42D1420088E1C188E442487481B5B00000028CE224224138201A142411054824880024148482622C114621848D082042C448A811118180280A186206184C884890800A028C02848EF3B0A181C024542288871249818CC51811448418489012C51483088418F44FD
+:804E80000110081A22218202181220240222220040446281241800A018A01400221226F2DFDE00D0249411114501211D240010914880C2884118108203A418001042C4444846048902E0A2444222813424299452882180341222A1414126821218029FF10A823227128D4448522061842004830124422842420061128C220450422014127E
+:804F000082C12488828140488802888228C0C22001582688084AD842B14828A2821F1943C14844001244444C420232250C611843D8840840221408484C93422066840048895A8276C2442A41342244891C8C028684C5188092548912C45A86983242284A49F87FF2501280143124211C22244104004004424D282A812822844204B042411E
+:804F80006242A94108A0482002230148A0A42B148B24400842834898821220048110087F6B0A17411485265248288B143440524825714201896422284034848E142289825142444220810284101204840021105424122C81982283418A48C2848923714204184449F5D86E24260A2B4316E81251211460421362122E44902821232801237E
+:8050000022220400182982184A4CD4485222544D1260A8442E4844C04C28124B28004624BA140243A424491418481C3442F03BA110F2B1435D141A7678F87131A784BB12AB34E3F2412B2CB4484158AA8B264D94C7462F44A488EE142E381E54D048B42216D2265222414F2414E8A9D4A8EA8D62482F83C32C8D6246EC8A72A4BAC2F3BE7C
+:80508000145E242BC58CD88881BC4EACA26BA2CF4198182AAC623EC47AF864E2AFC8091F334154B8DFF4D14493443E254F35D6C5D421B63C143B118F44F444148E428782ACA4218B42292A51841E4E4722A0452E144F46D2C8F1283C46982449E1423C44701C026982A4444D864AB2A6A4182B5C4AF4C81AECE16D7598AC1A6F24B89CF115
+:80510000841C8E28C4929FCC4B934429B22212521325D4214564235C91122E292D4961D0C6F9D222184F825124ACD446B428326C23F44C122CE181F418583E62D022F44A142F4F54242DE2C5B62271267C28F24E148DA432C82C59A88F21B232781424598E4AE184E481F4422EA3314C8957CA7F230B000080C148002001480020C1241257
+:805180002820042800184220142284092242222082E422080020080082288A04C0228002284F120B6F24F4562EAF21F121258FC7F63C7EAF86F22B2BFF94F54747BB77BF37F75B1E65F65A586F68FEFEFC48AFA5F5AACCCFCBF91C784B3227A1AF24F46E762F23F31C2E2F23F33A7A844D4EAFA6F6486C4F49F984C667E44F615266676434
+:805200004F62F2484AAF86FEB8DA6F45F558D88F8FF3D8D26F64F54ECEAF44F464944F6AF3D6D46F49F1B612CF89B1F4F9EE2CFFBA4BF346437F71F61B32FF51F3787AEFE7F66A6A6F63F173737F76F46F6FBFB7F77B7985F25E7AEFEEFEEEECCF44F66E6AAFC8FCB496CFC3B334D3E8F16A66EF6EFE3262AFA3FA3232AF83C3485D4FAFDF
+:8052800087F7DC6DEFEBFFA6E26D46EFE3F22A6665D624F2E84AAFAEFFBABA6F65F7DEDC8F8FFFEABE6F25F5D2D66F66F6BE94CF6BFBD694EFCAFBB6B46BBB4B9F6FEFF9C7FA246F27F716668F61F13B262F47F43C5EEFE7F36B2BFFB47547F77B7F3F36F25B3BE764AF85B5AEFEFEFEAD442F65F5E246EFC3F13E7C4F87E7A6F74A4AEFC8
+:80530000E4FC3232EFA3B226C24E45FE4C4F6FE6F65E7C4FCBFBC4C66F63D766E262F26E2ECFE25264AF8EFEF8DA2F67FD4AC62F2FF7DAB2EBD4CFC5FD6EA4CF47E92BF3D6D46FCFFFB69C6F8AA3DFCFCEF34875347F37F71727FF71F31F376F67F57F6FFFE7F77F6FFFF7F67F3FBFF7776BFB5B79CF64F47E5AEF6FFF7EFEEF47F77E7A0A
+:80538000AFEEFCB6D4EFC3F73C38CFE6F66A2ECFE4FC3272EFEFF73676AFA3F4484ACFF4F4FEBEFFCDF6F6FE6F66FE3636EFE3F36C2ECF66F2C6A66F6EF6FAFCAFAFFFF6F6AFCDACFFEFADFBDEDCCFCDFDEEE6AF4FF9FCB66F6DFDFEFCEFCBFBECF88FAFFDE4DE4FC4014B12E012415812844362814712166832123440668944128526588C
+:8054000048128744604480129228B0480283342242230223022284248C948448241E48C048E081C424164886E44422F14824F065BB308290161243E281228254126022848D124820522A101804844AC242508212C0246901411260484116542C00442296342490920043592282004E141E48402844F1B5E5C0521F4152281F417248F21129
+:8054800024AB141D6CAF24F11124AB9419B24A9945AB9443F34A9143F3429547822D914F82C4914FA2C4814FA27418F1245A96E1A2645DACE549E2A2F5D1242E421F497228F2912483F69124AB141F48B24AF1812CAB9419B24A3985AB9443BA4A3B242F24792498B24F8284FB244A5FC40DACF1116485F2116485D241E234D1C1D628F174
+:8055000011248D841D24ABB45B61A93834AD81122DB547812F147A26D812D9A4C5B12ECA5E854F22611D26685D2FB245E5A27DC1EC22F5914C8F22749134281D448B941F48B242F18124AF465941AB345B28AB944398BA49A4344588D38684D38675EF0D000000000000800200000010020088000040014008000000004004000000000084
+:80558000F085A82014C21459D22A941884111548210A1015084226189A2242804202845084208278120A48124224000052004184B01808A1A24226420418226012BF6B44021B1824004424478170240823C38A002C1358421887418AC14449488C4404287044A8412624122C32242184169644161244840498004024514280112428611B61
+:80560000C42F744F8234511662228C341884C71115382D4922A2821514883242876285D284C182496442161C328C7024082684DC2101818B212C64A484432104214410D48401260845881A22624160282A21E9C1F2251F4002411544424402002C2851280012850218224A0188200400C04812678228490443020061124B142004888009E0
+:805680002112460421411880028FF6030041122411A041800480014480029860442004101448185884282282221604802141E2810630242888001200008524A18410086BDF2422182351282E18833214812A0800408AC148448130182218284244100442288CE8C40143012B244912043220B22401832822018C98848C811288A5844982B5
+:805700008326F45A9B2428184C012F828112B448812A0400901283144488012800484004008D2426C85488441684041604187228182624A28212209884124038444AC9A41AC248488F5F02002189415218180000801148042220C8184684A142100445483848803828204382C22420612281C024908800901840880289014220025F1E4934
+:8057800091224887618284891408231A18020018218187242002122E9842842608A042002810081812001A1408443044406882882042A42482444528C1144AF2BA9F6021482843A1250081001D842548088142104208F042284416821404216044636121414C416264480030428A64842902960C22188301004828286180F13EFA00008E9D
+:80580000224480B22281384212002D444C040000408434214C024A1204A9024C8484042241830120123812C22220010025880A18421A28C448882FFF06272150486B124614C8282E124022598290461A14125822810056EC417661922C26AC42414AF2482463C14644489072121608306A8B481A84262281418891182508228A34241A2828
+:80588000C5484AF839DF200A2A01AB1248248426C2481410088584048C04222092882004100221A012424D18502444004A0124C429C8448948088220C2A44818488D24414C6122CF9B042881241828442CE34184224164828C0110C818481812258802212228482284418124182A4504122200004243A12900004446420448002280F4411A
+:805900002F4068220000101828642200002422C0622A844148088440C8482100A11026B32251422181250A40088420E988E5851848849888818981481424F843C3604C50842480914820518412842904812A844482021032243604842800268402100441406AC2A021C144850482820020440884411692484BC1223F6E0122874148444568
+:80598000C82241831294328C82016412C921922C844F8401444048042B14411E281E484442CC42081222001004284094388B21108C21883124412AC42800C4E7D8602400201124354240042183C148402264246400840024814028448201D02202002824C3028442808928220924124C0188A0140045F19BC17012682218264808222081AC
+:805A00000200301420011249420C84C484C01848A042C4C0541822004004813018288D244044081008C1B02408C8221E483B4200188081C8882149838214022118460241690284230300200249C112812082428801450200442A9424211008B014A81C20228A8301228078EF0A2028628418894104840012008416140881004C82014022AE
+:805A800082428421C22C004084012A018C92241822E04201420085140843C2888AE481E82102DF2A05254CB41804412942086D4281122684F41A6645825624814C04490225042D14412C88A1422120744881144418C2484004008301400C2881382B828084648241298CF23BFA60418E2685C87A8D8864A9D34CF5543A2B24448351888460
+:805B00001AB11492148F42A43189B21802184190288B754D58364CF4142443E423F648281E24293116878245C422C4C13A62424F4861819281857418E441B918A92249F8445CD2A5E41983FCFB1EF022224F8901C361414F82DA44A427444F8394122D2823D5681156683E684F2432686F655482457C2498288C52A426E847E224E2832528
+:805B80005288E5A41210C41250A245B82463844F8491221E88CB2A608D4B999881AE2CC748B09862824B486A747AF86C7D244B4483F23214214F22B11861A725382A8D143E2A2E122CB5547448FE6258A76425D8E6E482F12414AB2285D4E2516C2221A1A9F54E2285B822E684F116464B1236664229B238524A812E248D44CF81B1288297
+:805C0000F928B8D88C64846FA614C6888FC6A78289EF87DA44F884247B660000002C08241A04120024480000200100002100008001004302008014060000A048280082200882F06A18E026F6661CAFA2F3321AAF43EB63E325F54A4C2B232F42B238B238F35A544E528F84E423F37E7CCF23B752E1847612F82428CB33AFA2F2262E65BC8A
+:805C800062F65C286B312FA3F37476AFC6E644F7644E4F63B332A3222B111AF3282A44AF22922ACFC2F3ACA48BBBBAFBB8D445B418F11C34CFC8F92C243E188F87F734F4CF81F15CC8EF88FC3171242F26F6A676AFA2F23A5AAF83F3383E8F25F54C7C3E64AFE3721E3618AB774F24D588F73A32EFC7F67E5EAF85F15E4EE7E1EF82F23C46
+:805D0000388FE3B32EF28C8CAF85F65CE84B318FA3E3E7F7436DAFC4F74A5BC7A12F42F2646C8F21F118728F22F22C24AFE2F63E34CF43F3B8A4CFCBFBB8388F8357448FA9F71E3C4FC9F924284F8FF778D84F63FF1698CF85FC9C9CCFB348F222622F42F62E2EEFE3F1AA3C2F63F156542F61367E6F42E341F33232AF85F7125AEFE5F512
+:805D80003C16EFE7F5747265EA84F71A38EF82F238388D36ED2EED8EAFA7F37C3E8FA5F6282ACFE7F72A2B4FE6F7344E4FE3F316366F61A7116F41F32A2ACFC2F24E2CCD2EEFC3F33CB48F4BB9A8BAC81F7C4CF8181AAFC1B12CB23CF36C544F4AFD3A384F4FFF8CD8CFC845F226626F6AF22A288F87F13C38EFE2B95AF55676AF47F43A30
+:805E00001EAFE1F11A1AAB756F61F17E5EAF63F15A5EEFE7774EFE5E5E2F4151CE8FC3D3AC932ECD8E2FA7F7D47EAFA5F61A6ACFE7F72A2BEFE2F73B5E4FE3F21226EF61F71A1AEF65F12A2ACFC2F24A6CCF61F33E3CCFCBF9B8BC8F8AFBC8F8CD88CFAEFDB2B2AF8BFB2CACCFCFFBECDCCF4BFDBEFC4F4DFF2CFC2E51003026846B128406
+:805E80002AA14124122484C0484484441AC422128D24D048028912B248024E246991286142230229016B12008460814322296289A0414486084024F94824928F4422F84E48001E24C5022100C4814C022818C012328744412344080045080018442608481A424814A421CD12004443821228081008244189014A5284001847925FC1052C13
+:805F0000F4112485F2112487241F41324A1F41B24AF11124AB9419F24A9251AB9443F24A9143F2429147832D914F82C4914FA2C4814FA264116FA264192E4A96C54A9E24ACF591244F22F4912485F2912483F49124EB141F48B24AD141B24A9921AB9451AB9443B24A39342B94478A29F9A448984FA2F41A97C0421FC1D628F411248724D1
+:805F80001F417248F21124811F41F64A841D24AF249B2589B924F44A9143F2429147832D816F83D412F8245A1CE982EC51F8264A96E1A26458BCE558C25A1FC9F2244A1B498D421F48B2687181941C1B688B141D24AF44D941B24ABB85921A4B42ABB443BA4272A498926F8A84F9265A9F710784820000000040042800001800100200893B
+:8060000008000014204208480000000000000000001002DFDF086412008144818002840011C1262404184582314470840A008742102241444262424126064C31323028202412182808C200448A8102260422CF4D04204852242C1448322C1285031058482B418502644283029C02002D4400274122218112164802400884280085848101F7
+:806080008110088301109C14C011414F480244D648126484618449A21250843028D4EB14AC02644A712844C2413096218E443028632132129544425A48444726846412C02820A4214901830A830884441A982C64268431143FEC012400104248420815180200102404002971240884100241100220818112022031282800C11048082004D0
+:806100001800800120D28D0D0000008042020018000040021440048121005082000044000000000000000081000000F0F4BF00230121000000004004254404101444042244415042104402001221288122404238240082100812002880120441F0447A0000210080020000441014042444444024420C1004650821002400812800844C02D4
+:8061800080088480012002284400F0A6CE406281000000240060414002000011610010062100000047818002002400000044001008000041F0BC41004400184018028100100425424402450244CC54844426088504104404446120417488440400228182188484412041584812401454484F74020044604200102204248001004200408878
+:80620000020040821118024512082400208102000000440010A41881830216086FA1091002400810081100101218080000003042000020020000440028008100100892812141000012006EAA40120460C21058287048012440441802001042BC4452244C9428502C1860424441251C0663018C082800100881814F8158842112848E148C9F
+:806280001128D14811FCCF78001004184002000024124058424821410081840000400A00000041444B120084228028010040141408284100EF820A0000002410080000002400450800244002002400004002000060810000000000400800F0AED90000008161400200212440044002508484008140542284401204250640062100301412A3
+:8063000084180040040000454808FFAA0D4008001014420A404204002400441002000000A1004440081014020016080012440000000044005BBF5088830400A400004554444342024400508224E552A21221872840144202150224C558AA8304100200168451C445342400440040481248A8115F7308000010041002210000008400004076
+:80638000040000810000210000100400000010088441000000DF3309818C24841402000044414C72288202400400249012129882491802405121148485C24842480000004441CC228202001800250229F1A6CA400A48211002002140042881400800002190148008000025012484801402000000449028004008001012A4410000005022EC
+:80640000005064000000004012020044000024005088000000000045040000000000A011DF2845420210020000100224000000000000001014080000001002000000000000000000B0CC0A1028240421100250645084222224000024212460411282824100101151881028240400005044814126280200120024241E149DAC4058884848D5
+:806480000000244054484584922200000021251282819188880000254101848588840400004044544428280000001012F2689F10020000210000008100000000444100400424004002101202210000004008841210080040045FD209004124004002000000000000000044000010020000410000000000001008000000CEAD004014124207
+:80650000022121254212082400844400000000841004002124101202240000000085088011480C0000417F850D21400224412400005028001002000010544445044121854A02004002440041000000508884002001004144CF3C4F4212022410124242022121508825084008001044040044440025022121404212020000008100814018DA
+:8065800088010000EFD406672225A2122B119012C0122582F8121117118B889659888F18E484041D4911489518F84448874445B444E242024C02286514E442722652222E122B11882B98C0922582E8317111B188699985B888E484048C04488518F84448FFDA0E6F2252241812231102182592823CB11391818E88818D4142464859114819
+:80660000848588F44844C1492262424480425444286F22522418121A388282182592821CB11191819E888391484246480848848588F4D956000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000026
+:8066800000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000003C
+:80670000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000BB
+:806780000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000003B
+:8068000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000BA
+:80688000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE003A
+:806900000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FB7
+:80698000FE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000000000000000000000000000078
+:806A0000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000000000000000000000000B8
+:806A80000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000038
+:806B000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000B7
+:806B8000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000000000000000037
+:806C00000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000000000000B6
+:806C800000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000036
+:806D0000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000B5
+:806D80000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000035
+:806E000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000B4
+:806E8000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000034
+:806F00000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000B3
+:806F800000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000033
+:80700000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000B2
+:807080000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0032
+:8071000000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE4C0
+:807180000F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000000000000000000000000000000014
+:80720000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000000000000000000000000000B0
+:807280000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000030
+:8073000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000AF
+:80738000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000002F
+:807400000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000000000000AE
+:8074800000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000000002E
+:80750000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000AD
+:807580000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000002D
+:8076000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE004008410045181404000000AE
+:807680004004004008002100818144810000008484004118004400441200200145F8CB81241008A48445180C004450848514141454240085124808442100855448104448440C81818552844144C91184110449014144109414181648C818122FC502000021000000100400004410481848181402400C8441000010080044100416040000C6
+:807700004112001881836181BF89062100400850484100105848100400400200000040048441414410082400848C0112001800440041188400411ED1000000448100410000414004210000000021100800810000844004000000000041002001F072EF008484814484440040040000400400000000000010088400008514084110044014E8
+:80778000140400180000F044BF2004000000000000000012004008000000000000210000800200000000000000D02201180025040000008100C0148C0240024141200200004004000000844181504840081004440010088001CF284E4214140810848214181C01844481840040088428101204841008844008446021801208200280018204
+:807800002028634818440084D094042D1444810044004044110841D048C128002410144402000084400C844004182184C4004C0281120040A41241100420015EB6004042042082144808100881000084408802284140080000000000221008810000430882208841081008CF28062420024048020040081648022480412814040000250820
+:80788000610010044110020000008180A1410020011246741408847FD8086124502C50221483016508312424C01400604220312400812002D026722842424202694214026244435184008440886141430160428002445F670E6480022121901A50825083C018212301211241000000244042440221212542441604201224110840088440B7
+:8079000044240144604140F42A4C104202C4401A011004400210040026289414260440088C0224436282400424281002481044048180A114181218001A32442608843FD84A024612140422182420447814880200004028224408005048444120912400A1200460821881000022491884284122880100D0A403204402480000004128901871
+:80798000000050820016020000000000830242210000128444200200001200256441187FDF0D0000008121280024848110315200001004200200100824004094140044001084028160812128000000F0C27E2440120480420222404802811608420084A38214440228104C144408008042241102260C80112C028141CC812842222901C0A4
+:807A000014F0E7160040422404890121486081810011290100008100000000184C1202211004001884000020480218000041005FDF04248304420040420200404202244022020000002518024129410441002004100840040000124412000020F187AF2002002A841408E082141208009042484848212800241002120000004054424160F3
+:807A800042C0141624088282820018434804C24400BF6C0300400824404408100840086062001008C31292280060812181101202230421450841400C00184141410018002011F878C7001008814014025048C028009028000000100400400424400800410000008001209198908880081800F02E48004008400845084002401848040044CD
+:807B0000304440040049020018264C0A2440820400440044124130188181814818122844F02EC20041904600815082508210820240082121210010022C4282113214241004C4840000002001440080418411040021F0673300800246022082C268008504102204422228282800210020020010185224002100126048408418448208640067
+:807B800088168405EFEC0B100281A40000C022C022000022000022200222205282220040040044400400208121014480011200214582F198870080440284231422046042D028020081002810021828880041001441508680042304001218884480034100002011024FB3092429148844528825D84C4262842684922881212485E8C20223B6
+:807C00008282A422C5860228807338C8245044851C1C04412460428041E84129A1117014749818768C18240D4A411494182FE30B22C424C48C5422851452822E62A18467228410844492424512322C0065A22223522C164234128D12254812425662246D442304847014240830848A514487414483118641A2134C3512DFEE0C008C3248C1
+:807C8000A3866424248B2481A4A18424851A622648468226820228104A322221614123C122416421C9544242C44144474118414929A8918081A9118E144C019A182401C786800228800228800400000000000000000000182002000000000020080080082908800448F0C3CB602267C285FA26268F86B46254CECFC6B622B2625284265833
+:807D00004A85528AC5FC686A87A46AF26464224F44064D266D24182845E421C32425F436248558E8E54652E62425A4664F420245D444718404829E944748CDAEEFC8F8889AEFC189A8DDDAA9371AB14274860426F226448F22F226668F26F46A4AE5FE6664AF82B22A427E22382224A7A2CFE2F2484A87A46AF266662CF24644F012326D1B
+:807D8000262F2849D264F812324D2425F42725855AFA254ED2664452622B662A02800145A418AABB94A1B1855EEAEFC189A8DDDE926B374B555AF4FAA6C0226D46AFA252EE8F84D6A8F42A28EFE4F42A68AFA656C222AD2821A55846AF26F648482F24F464442AF24644D0645164882165D68AC2264F6161316F4252E8654CD24644526209
+:807E00004F4454444554444D144F49E941A9999A7B84D4ECF81E1CCFC1F19C1E2B18CAAC512B224A85F15DC2C022655622EFE6F24862AD4AEFC2F24E4EAF86F64A4A257A22D88A528AA5FA2626AF24F448482F24F446662AF24644244D1665F61282257286F61A3A6F61F314161E13EFE252EF65562225566225A64400E041F194948E9468
+:807E80008AA9B843F93C98CFE9F91E1C4F293182DAAD516F4293144AF5FC9400104208844542682284248424404248424882840200448012026100100600411004411241122001404448648120091244F076DF0040028034420000008400802404200200210012A410140850224002222800002008008001000040F13715E022F411248798
+:807F0000221F4132681F41326A1D24AB141D24AB9419B24A19B54A3924AF143B242F547924D81AF924488D914FA2D418F8244A87114FA264192E4A8759ACE449C24A1F49C2421F4952281F4932481FC9324A1FC8B24AD1C1B24A9921AB9453B94A39A4AB9443BA427924B842F924488B944FA2F4A94AF0244217C5CF223411837611346AF0
+:807F80001D44A9D141F66A9415B44A9B25AB94F04AB543F242B54782AD952F82D45AF924528DB14F22FC18814FA2E459C24A8F58E2326559ACF4912CACB49156281F4916F8912C23F4812CAB141FC8F24A1419F24AB459324A43B24821827124B8427926B848FB26126FCB09848004002008000028000081001002188008000014000048B2
+:80800000000000004448280000000021F0A87A004008001008C1250881810041182868800181210022418982120452800210041844440080011008810041184484812FB20C25022D1210028C41441281022442A4C9420A242044080010344400442B244440140481100880240588221800A012481210041441ABD90023448804101808550F
+:80808000922C3028834468828412224A42820116182208484181225B42805148414281100840A4149084282A0184303880115424443018FFDA0821D02201218041444208400224416440024284000044430222442144482002400412414800200100004800181018F45ED400442001001200000081450800124A01288602224008002240BA
+:80810000420400440000811289010089088148188C048042F8869C3021211481B6022B2984264418CA188484008444224450844144108862211062444334242882280081236A4420A1924128BAC418803114282110A6417212F01727C02140011E222438C024248410088444844122004140060018004246C42422690800100200A280224E
+:808180000300442608122D482086022FA80524446081882038181008160881100800492145684282608228A42410840200220045289A442031184991184A381860891824424084252111F815E124644E148062212248238811183824A40010040026384612242221C3084D8218188810028148890321892888A2210041284148221228401A
+:808200000827842283D2F90A800420044144284304C13820010080022120014362282828C12220E482141488042921248244140282488C42880848848922012180F14B8620040022008A02005229C4448400420018831118840422601180081812802202002001908820020000004C0480089F910646C414005A22C24241181018B842C13D
+:8082800044160820042218C991184126624222222247813A085827820022281223A48252262201826284458888220483C2546084A883F2FBD65022002824108422C24CA061850200440090284840220485146259218008584422D02801408848246288440020041826088400002F7C01288280021840A821842942080022004420022844A6
+:8083000020024488200282608200A02842001200001880E12201121890181210F276190016048240280100184008102426820218414602000040080000428120011A1408200200000000008044F8B4968022982840082982428842881202008400260222000023810A22008002800200002001120000800300202481F47791102282150807
+:808380002884000020048C012A1184010023A324208C682448A021000026880100420080010000418005008421F0D588002885C22120018721181A021A322812892103122A2183A141802122222106328081014AA34142182383818104000080812401000048421CF1F3BC40C8112014280242818189524880020000426810021800A012C3
+:808400004848808401002A0448004A81A124A014414A2222240420041829018B95002448A028862801222001419410289128420020A44242486A0800120000000000128004408404000080210400CF470A2088132802898202000085028421450A8420020080022224004002221A020000001258301818184922031A2481410848FFD844B5
+:80848000410848460480041041C41412280084004124182341A816844A280912804481276481800481001008C01426840210440260244421D05A4C22729162224AE288B218287448E8831348982818911E18C0184CA21466A212442AB312A264E823A1441A248103A0212AA22728A011A01412181220044B1420E74321A2112041B24C61B6
+:8085000011814F560328A289332983A2123A21127821B82CE383B12C0481891212C8248C82A271528420A46618299838008024812502100884124AA133181A313818184D2238425A018B45124A61245F2A07903416C84CC02A8D2838212C234142C818212E1C8B634F82313249E1212482E44624628218AEA42AE222A4431AA4C12E124E22
+:8085800048E085E121A2A25AA441424281421242445220644510A214188C84B412749C4B021800821800000000000000000000000000002220020000000000002800000041F024F9342358B12FA2D25752883AAB225E52AF8151994B338D1816F419132B3187222B33CF21F37654CFC1E123A3573AF76A68488F86A5536AA5332E322B555C
+:8086000080E127B61AA75484242B118F85A5154A048F85054A058FC7044A7524D444C11229A154ACF41C1C5A55668F184CE122F233511E1AFD4587821AA3338FA2F21A189F93E3C2F228283E3895B312F13812AF82722CF23614CFC2A2332B137AF75858428F86AE176AA5773E32211F1121E133F252385AA7663E322B118F8484A411125F
+:808680008F81A1114F4181D1C823A121474347415E522B11E085F15E5C5AE525F5FBA514F03163AFA3D25712A8338F81F25872AF837321F1183C8D388B219F31F11A1826F21A184F63F37654CFC3A1132B454AF568586AD688AC573AA5112CB3524581E125F472782AA5533E322B338F85A1444AA4118F87A7114E44188F85074AA5114B1D
+:80870000332CB112A1548D48AF81D144C452FF584BF3A2223F13F3282AFF56B228F8B8388D288F21F33A381F92F218388D288F81F31913AF817128FA3A384F63F13614CFC3A1133AA3668F86A7668F86A2577AA1773E322B3314121F23B272A7353A47B232F318585AA5111AF138381AE14181D18CA1111AA1334B334E5229A1118F85F558
+:8087800058584F41C452CF570422A01284402802222002400880024480022820044A02288002802124020080040012002001122001100842F0542900000080410812200110281108002001480000008001182800182800180028001800220000181240F13BE2D024F411248D121F417248F21124AB141D24AF24D141F24A9219B24A99455D
+:80880000AB9443F24A954B422F347924D812F924485CF9244A5CF8244A16F1264A87592FA26C59ACE449E2A2FC91242E421F4952281F49B248F89124A3F4812CAB141D24AB9419B24A19F54A9243B24A3B242B94478229F9244889F9244A1FF90C4D491F41D63CB111766A53418D121F416624CCF242971D2CAF24BB14F2488322AF74391A
+:8088800014ADA34F83F442856782AD954D5A8DB54BC2142FA27DC8F52212D6D5B2E45DE2827481FC225A1F49D428D441B242F1912CA11FC916DAC1F64A941996B25D68AD924B42ADB64B424AF924482B942782A9A9521F260684820000000000800200002004288001000000140000481800000040040000000000B0510720130280410286
+:8089000024121881818110082820028001A024210000264222A212182400180000808104100444A9820300C0414F1F0641821216129828DC231304911800440084001243022200602245C8441A04412C040080420280820114901800160800244A215718414FEE04201F82013899922200478130288110082220622128121A0282C02245C8
+:808980008884145162248901460200210018100483034140342A12C0424830145F9C0E418001A184492151241214160840044008004100E0220400411222A04228180028180028001C8104001608800229211388E4980D008280080088000000000000000000000000000000000000000010010011400170E70525821245A41289422104D3
+:808A000047C12981643284A908418AA492507884281A6848494443B848A2413083D088C1646A0871442A91285C2804451882E432A188211698148AA4824006289E88AF520468215B11448782285442D084F23311482484A97814A454822A0885071EB88A4435458D2284621A0437888594142429A82451448F82A1A814461444381258AECD
+:808A80008384A14F458421A882C01687812843FCD32F002008880080080000000000000000000000000000000000000000110010011400775E502200302A0010280128140000002228806222004A02422081012011020000000000001860242240882308F0AFDA3024121220C11836110830232C11481EB98861429C0118418C0100D04A8E
+:808B000061256C42A242103832200216420420C1C800A08118C04218228E482832423044F03C79800212241283811118C8121982125268918A91248400004002D082A2414C44A224128421240012210012890C00881220044223226281488244F02B3550261800890219020020110940081C012A31248C212202B0144482122201A0121202
+:808B80002200440000002001C0121228890C223820043DDB004D128024416843004508188D648C418813442161429022C0128A42048800400100283E488088060082004A880220020020922228F09D3E248014086021842881008CC224800110140910828101882026280414460283042C0400202282024C02280000281838822149C17268
+:808C00008FA207009011000000000000000080044242224810022C010000002A1108100420014021014200008100EF330310548218D028614328100C836284181608504119C124A042184823C624A024232884012C0442281A021AC82820624222A012881081014828008228E022F463E5102201111810088100124008324410080000888A
+:808C8000200400100200002128420080088004002200183228844C03BE9F240022242230318140082A21022832800343222105188002410018A02100001226081C8281024E18200184800283022289013A047DF9C0141245080081504838004608811100893111002819020083012228008022A42820018042018048C12120022242838329
+:808D0000011028D2B707210011211D282200111A021800004100420023044324622420042420840142208424512258292491221A02100258002466820646F2D7ED1024D22494388112801204C14490284C41341C100230281210443214224118902850184021018400422061821880C1294200100881502841FFD501821302488A830414BA
+:808D80002608008001288440D484C612488006484880040028904880A221A0148B14102822048100901818831402006016DF6A0F8C022828008082C5381C11A114421218400820829142812A64421288122218122084821608183C1281840219C8C100002A040018808443F423CD1420914818413014240025C818812400C011281241145D
+:808E000022001901138142820220112281011480321234142490411121110038120000F0714630218001C183324420022284218511082D24C93214244982024428004B28200122423218180022920020091148290118A40080220480F173CF4008488CA44116031240014C428402852401680030129012812A88942489148161110024C0C9
+:808E800061298842088E181C12A212260C3CC3411200002A811302BF350545A11A26C8582E14843A4238428F811172389818428F81B1117218742C14F814184B511A22B14403661134482F42E285A411892226A422283A43A23E78BB242AB449A2531BC21AF1186816119B438B2229B728942A26A2122361142E222FE2092E1413C124A7E2
+:808F000014C3B56172461C712824A232284E681D18214514C2394D241384228202684D2823E31A03601230129985A15489A41384121AA11426D813F21818CAEA141143882325814388C148628D1844EF7542932228C9E123D282F218111CA1234D381D2197C11971121498242E184D3816A2172E2427628F14E522F5214A43E24184F714A4
+:808F8000C44B412E32283A8163238B411721881C32191B86263B122F39C1824672233121381663148C0146A8111AB25882E623B254F4AB194004444084410C4400000014404148011440011440814101000011008150181008811008811028114808842816082F75427112F4151D47224F21F178545D13EF86F41D1FAF45F615372B131740
+:809000003227C31FB4F41E3C2E1BBF92F3391197137E5B7F77F531111F17751EFF47459F92F361714B465F16F5494B2B133AA3452E623F13F321233B373E2BBF11F421A91FB5762BF96973AF96FEE1EBAF9AFF2923BF82F1111BBF85F638322F85E7A4362A89E2A6F638788B57EF62F41ED3144B231F53F5282EEFE1B57EF74D5FAFC6F7C3
+:80908000191F6F85F6111F2F83F3213B6FC4F74547AF81F1341BFF93B33CB318C31B7F57B572A575CFF4F663618F862DF375C15D359FB696321E315AE633B662E622F23B788FB1F313198F84FC4943BF17F5717BBF16FAF9A3FF56F3716BBD359F31711BE1A7F75A388F24F232188F81B348F532787E58CFE3557690351F51F6281EAF23CA
+:80910000F36E589FA3F3734C1FF3B35EE663F3121C1F32F15A789FB5F51E1C9FA2F322393E183E18DF26F46E4DAF87A557DFE6F566458F86FE5858DF97B474F5585AB7928F92F278788FA4F772685E423B733E333F93F271F19F17B668F661799F17FDEBD1AF5AFF212BBF11F319119F15E4A3B372F7686225A8228B112F83E785F464568F
+:809180007F3F0A1F42F33121CFA2F37E3AAFC7F77D7A7F87F7313BAFC5F6393B3F91F221336F84F54547AF81F13D3AEFD2F33D194F83F12D26EFD6F679596AF76D6E2F16F67D6D8F85F4FC485F16F6787ABF92D288F258689FA5B632F37173BB331E3BBF13E3A4FC535B2F27F77B733F17FFF3F93F5EFB79437F31F1131B3F15F438322F37
+:8092000086E7A616BA38E384A5718B45CF66F5CB71A012A012A01220628122122284E0810484441244C024120028C0240011000000800122C0111214122212141214122081024A0200DF5C0782128180618118804108001210941800414C21014004000080810242008022020022A08600001A042220013260124FCB014D421F41522C1F44
+:8092800041724CF11124EB141D2CEB141D24AB9419B24A19F54A9443F24A9343F24A9147822D914F82C4914FA2C4814FA264116FA264192FA26559ACE449D2A2F491242CF491248D821FC932481FC9724AF1812CAB141D2CAB941D28AB9455B84A7934B84A7924F84A924782A9F9344889FB244A5F72066D4B1F41561C1F41563E1E644F3A
+:8093000034D1C1F24C134CF248971F41F24AB35B218F7419F54AB353D23AFB2548AF143927AF14BB25F148917F227858F123928F5CB222F198252D438F5DB2227591FC225B1F49D41AF4112CAD939E6C87361D4C8D92CCF648971D2CAF24DB85F248924781ADA24F82F44A924782A9F93648ABA42E184E4E00800400200400448002000017
+:8093800000008001000012000084800400000040040000000000F0C47D4041141C012A518589D21802847018512342280000811281100885425828301821A301221200211226C8628D2124E024010000008B4322816800FF5F0842864101111418205116128503301818B026810128662C614442441844437444822228C21427218019849C
+:809400004102122418460222000032002418811601BFA50D1974444109111E211604326531149187221512A812D0420340CA141668458486C41825442AC418356281128D2212CA11341210AA6125225122432122020022C0282CC21A8B2420F19B650010140150188C521810082D11A014008001282E480042008446542428882845220108
+:80948000008081021D28806424000080014A010018B0470B3C01210040638121842001008400282229226344240090428004225604422480018084018084010080041A04801104F0872B201241029012292222123222212583012123F34222809148412826B44C4294423694441E22435422282723640045C2128564C1C018228382648597
+:80950000460818411A52862A04222844F0AF66A01200002321121A522A281082012091222890628046324490422B1249E42102244C13D22404211052825608842242188C0180614418422A042AC12444F016954051232400241432220029111102A1296224201338344143922841C0448094442382A41221004C8141448481018922243456
+:809580004800602247810000001F2507484889120881440081002D248604102414180423614289018158421883240160828C21034CC258004881485084421A120481121004002218ED468081444221048410081884281502222484124227412524C11222000060229024C04880058012022828442D248128102822240441100218BDF900D9
+:8096000044140020312824200200121002802202A0424944140422102485450400C024124400214214004200418081266284007F720610C428A52104853428812003211D8618224481897144128441742882428824A41246E842819434845818902449235142488168C02883044C0422528081044608F0A9AA80051400841840424844089E
+:80968000005022482082138483644441160400901242430222124028028012C24425011810484884443424288002EF15012038280040080044104408188062828C0148001022018001468A0200580018892204602100481018084400121218F03BC1008344220212611822222120042951260080A24189C242A40022424062844068244059
+:80970000081602280000702498288420014018082002F0A24640A4182881818110C81800814C11082011343C410000000080121822410800A04240082682818104188044081880031884F042B7C0282001800210048C01902400848100C430424846BC2854843014892487120800302812203122002608000000281884818904F0E6F5005F
+:80978000144422601100000000004528120212402804584022014430240029140840280100A024800422008002808412B4420384001024021223721201301228162401122081F61A44218118282A811408188001488421188400424A23248681055A924843042290240021F0149500400800442041041270120220011200100421008981B5
+:80980000C412202464A18180012A810100184048880112008116084008B06B07208941014008001098688002200183322400800423240128608320210400002001C048200400200144243840C9118F78014588924460C88812002C83C114A02143042544C84410AA122983811188088189240246210484818C141282420800C034221E2852
+:8098800000844100242821F0ED4C40A42826B8212298214D1CC02C39E38141385884126460C24B2412A76458499142412B4541848B112CA144188B2485280484A46A3218324AE122028B2346A82448848941182852C88362818B211621E1530449F281181250883A19A811606220B1227112D622A311121A63C28B324781424E48842F848C
+:8099000054A81E284692448F84D68AF348483E1458A12489A121A123D2889168A0148CD44822A212E0851408281A912425E2844411F4AD26001AD44C135A448502812B13122594184D4489714404ED1C81AB11C42AF73C28288725A0226AA151843236A6222D4856C242481A94181A81C122A014124E122AF5185856A815224384D1CC218B
+:809980008281A3128782F0436E4004442244400444000010044128412880024241424181A0240000000000008100480000400884408802F0415D50445FD3F32C3C5F1252CC5F53721C5CAC2B311F32B31241F24A4C85FE465445F41E1C8D2E6F44F6283E6F66F76C3C8F85F55A4A2B44CFE2F53E6C87A465FC787A6FC6E785F444645E4227
+:809A0000A9C4422F8151A82B22288B136AF728288B551E183E387AF5784C8F81F1584845A4114F42F23C38CFE1B332F378788F81711EF4938950441F55D544D3DD52449FD3721CDC647126F431332FC1E1A1F14A7CCF61F1466441ED1CCFE3F3667CCFE2724EFC7E7CCFC1D5EC5546EEC22B624F65598A8FA7F7465C9F97F67C748FB4742E
+:809A80004AC8422B418FA2F21A588F81B23881F168685E188CF57C7C8B578F81F258588F81F34C448B114F43F32C284D2E2F23B362D788D1CCF12D5550441F52D7CCF12121C57C11D5CC51A86F43F311318FC151A8AF85F748484F645524EFC1F1282AEF477528FE7E546FC6F11838CFE4F544462EE2AF81D4A8F44E4C8783CFC7E596F484
+:809B000064645AC4482CB41255A88FA2A2118B338F87A7338B443E387E5C7AB258B718F1585845BC18F12424CFC1F1341EAF83F31A188F83D34CF1AB2F50441D41CFC2F22521C57C11D1CCD1ACF136367F73B11AF11812EFA4F55A566F65E521D1C6F1383EEFC6F53C3E6FC7F7741CCFC5E724E424E426FE3674CFE9558A8FA7F73E7EAFD6
+:809B800096F67C7C9FA57142DA2234128FA1F1383A87818B338F87A7225E182E788FC7B778B158B418F15858C5BC18F12424CFC3F334162B33AF83F31818C5EC12040018844008000016081200608189028324210483040083841188314820040084228400800412C048C04820010000F06F95200881288112002A418441080012200280F9
+:809C00003224188C24041A8224A512124828200412802202421242284228830418482001226082005F5B0A2CF4112487221F41724AF21124A3D441B24AD1C1B24A9921AB9451AF443924AF5439242F547B24D852FB24484EB14FA2E414F8244A16F1244AD6E1A2E459C24A9E242D4A1F49C2421F4952281F497248F29124A7241F48F24AA4
+:809C8000121D24AB941D68AB9451AB9443B24A3924AB944782A9F92448B84FA2F4CB9BF0224A1E648F126441A7361E2427341D2CAF24C12C8F34D941F242B25D688D924B428F3419D432FB14482DB16F81F442B12E184E952FA2EC51F8224AD655869E216D4B9E212D581FC9D222F4916CA9F49124AF24F181246E121F48E224F111248DD1
+:809D0000841D6CABB459B24A29F34A9443F242B636E844F8164829EAA2F5993B008004000000000000000000001880080000140084000000000000000000004041F12D19207824312244008460A18502502224C028004C9328284C226482CC52844C91449048122588A124184CA221A1121AA41248209124106A8448302241100221C0241B
+:809D8000425FE10D208828582960418128288C410881840041004A012004280064412872224141003885440220820220018004842800804421F2F795006694224181218C419818A5321C8522028126086042C05280B4181234A84361444187442E121903466441416E181E28184A118284223124458221024622420400252264121A74420F
+:809E0000061081284801412082024042180210846182284302488912040021C0481A22022210420C1A0220024038484800812221004024F24C4B00001A0212000000810000410060820028000000000000000040040080010000001004227F8D018002000028812280020030180020016046B04C024180044228290490240000208201819E
+:809E800000800481289024182810F413B90022A02120010028008400804104806182B024044F82040042003042004C0200004118100812200484004112226042BFEE010000008042082002001008000000220044002024020000000022000000008002284004F01E55100100002100000012002001480000000080058002000000400212CF
+:809F000020820100211222002001F0991B8042028420010040080000400818842822508422612002228025010000200218000000420081000022F06F54000000142221000000200400200200420044000000008818100A12004200000080010000F05CAC400140083C612200400820014290188034282800490421448021020000821250B0
+:809F80008222241818488001C042809138008001F02CA62002210000000000000000120028102842042848005A820100000018002002000000000028D0C5060000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F800400001A
+:80A0000000400428000000002180018800004001400848000000004480020000001002183F5F0B0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000000000000000000000000000000B1
+:80A0800000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000000000000000000000002
+:80A10000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000088000000001008000000000000000000E1
+:80A18000000000000000E066050014000081008041212481410200004100002042040040020000424400000000008422800241F011F310024042021602248361120000421088022200009044124904100218902480410860228140880200100800100800CE28004001001008001814004A414208001004004C8421020020012302008044EB
+:80A200000400000010088428800241F0892410020025022C01241668120048180080022800000060444110020041804108602284402802000000008100F0D64B100245415822408112220100120020110818480044004094443022202221021800100440180800208202A1224200D011094C0180C1143038A12884282C11411811D222325E
+:80A280002C4460421828462884D48292182C064E18121A0444002722806282004C052C2247180881248C21A214208624F42CE93012001800188429428802218400D08212044C82013044003044614E1821582081021A0200004484284048088128218382052800DF460B415014812D167028830212201181411132224341081248288C0498
+:80A30000422782168822042A012244002502228C12044A01812B52008002160A2242424248FF550118181048CC24000028431228120823110218508248004C22234498644452001883151298644222480062444200282884005883724288C4447FE403101418010028400411442280028400100212221008108802106882008005000040B4
+:80A380006481008902F01428120021002F9C010044280083012902182440040020A22422008004402202420022201204302200000028004004002200001F4E0F1218C41782102421024128148444001825084800004A6242830125C828492201812AC13210F824126222480042E0820100264478380442228904E0C2074004108C1208237C
+:80A4000002182821102812022832288442008082849244424820024844000000800248008100802113084249F4574E60221818120044802211880120810289011624518283040018200441188051482418A0142222222A0190248041043012811A1204382842BFD50B12004C12C82429022110824218942200220020522426026860A2E0D1
+:80A4800022045048A400008440A41481814A2211081281008024028C04F07737202202211200411648080000C01800833222441248E400003018200100411004818144428034180018444002801124016DAF00100C10418C02398211889121840080010025140400608100004002C068102831129012108A5282100284430212830223749D
+:80A5000024F28E6F201801100828801284012416180884811008E0840148840042160884848100403822200112224B2189024F81921822608112C0288021E114F2DD19002D241E28142821D0820128283480224124022222802122A1120080024302413016904448811A02508442420080024C012002489022C42FB30118008C0100243054
+:80A5800011212042038118400881001002818C022400000018008410429218A40000834108000000F0AD4A00902485840381360D8428848118801242220232C321022A24341280B21264232412001881001800008021018480012200A97422880487861484124828C023008901814C82810284224312088122212E488C419488D0822142B6
+:80A60000081400848004C0288120220126042C020000122A815422F0BDF9C012A23E1CB5B4281146D44CC1283331228123111242782218F812288C721898144F845642495284C0226A46C82C84450447C17042048C6281C9F21848874221281824400845648124122A61A58CC1316722D7B62041044D18164832281D2283F2281A1213C1A8
+:80A68000188F21E18191248962814002841E1446D282A4641A7128F81218293516297118C81821008C1298282E18184B118F8687D1C224F1141885743A08182AA14216B82A721824A6248F9A4BA1223B31C9A223281F12D2867232B812C1258D382E288352518932281AB124322887432AF33A2483E283766842528810E827B2284182514A
+:80A700002824184F81512849A512163222A4128F67B438F2283883E22181F1181281CC82C224586AA641CCF4EC980021000020220100008002000000830481800281418141100441000010842402220040042880020046D4C249B312F315176F42F325258F82F2292BE57C157F1AD8FDF232289FB3331217312B11CD2629F21C3EAB338F93
+:80A780008361218FC3F354346F66F626244FE4548A8FA1B152F16C6E2B134FE1F112184FE131124F41012E222B338B133E12EFC3F2282A2B11C55E8E8F814154A8A5F818184F41818252A8AFA7F618781A53AA2F7B45B332F3757FEF42D355F6282897B265D4F1F13A385FF3F33E1C9FB3F312241731AF81F124262782CFE3F33A388F83EE
+:80A80000E183F22E2C4FC3F63C7E6F46F4CCCEA5E8A1B912F5247E2B33DFF1B112F11C1FA3F114148CE422B212B118F33822EFC3F2282AA781C55E4A8F81F1183885BA127118F814143AA3138FA2F27A48AF87A7338FA3F3B74C343F31F237676FC3F2212DCFC2F2252555F51D158F83D3DDF3393D9FB3D38A73157515F52C26AB33CFE2BA
+:80A88000F32A38CFC3F2343CEFC3F2742C8F86E782D6E4FC1A181E1A8FA5F17C6E4FE3D2F4F1161C4D1C47C14F41F114542E222B328FA2F33A3AE7E3E7E2AFA1F11E1EAFC1F118188D32AFA1B112F11C1CCFC1B138A3338FA2F26A682F87A712CFE2F37722343F33F23F77EFC3F3752DCFE2F22727F5DF7FF33A3AFFF3F33B3D9FB3D3AE68
+:80A9000051FFF5FD2C2EAF83F12C3EAF82F33C2C4FC3F32C2C4FC7F66C7EEFE6F64ECEAF81E1ABE1A5F5747ECFE3D2FCF11E1CDD1E67E16F41F11C148F22B212F1183AAFA3F33E1EEF62F15A1AEFE1931A8B318D12AD1A29F11C1CCFC1B138A3138FA3F27A488F87A713CFE2F7B465200222842284400884608160810040081281124460CD
+:80A98000440000001881000000400884202162816081608120010012004F2F03AA21110E188422162402181A020016882203221880828482042A21B42401492191148061418342888192141A228204000050482200382E484245F18898D022F41124A5F21124A3F41124A3F61124AB141D24AB9419B24A19B54A3924AF143B242F347924FC
+:80AA0000D812F924488F14F9244A8D814FA2E411F2244A8F19F2244A87594D4A9E244D4A1F49D224F49124E5F29124C3F49124E3F48164AB161D64AF269961AB9451AF643924AF6439242F44FB24482DB44F82E444F9244ABF26076F92F41164AD431F41724EE34172687311746CC3248F74D941F24AB349F2489743F24AB743F24297439E
+:80AA8000D252BB26F44A912E188F54D9A2E8519A468F19F2264887196D4B9E216D481F89D226F49168ED421F49724EF29124C7241B684F26D141F468961D44AF249B258F6429F24A9643F24AB64F82D442FB2648AF44E982F1B8BF4008480000000044000000000000008800004001400800000000000000000000003F7C024D11165414D4
+:80AB0000901A6012503411850281218D14400C2D248942148843887248447422024B124165D228D42462422E121221304244C5322881385A42622400400C812002832572EC0D2286C11800260228811800184214C41283628100402802228C11484C229118B048018002103828188092828132209142492101124321214391486FC9075CA5
+:80AB8000315481208112834267114508362A341D1014983C8952248436688322A63C1C81841624516985D248322CB042032448266841818382D884A51223162284911CC0181826028CE183644E2012D11401A12002814002005084892112020000800427224426429412422C052A01211048542828241A2202201112040041183242A0C6BA
+:80AC00000080018092181200002C0821902216480483240200410028000018120041800180028418800142008001A04242F0162E808262824138A42012682222001890628004AF241314E8840225C822288C1222F442281E22282D242926042A014C02322189A3282220B49244886344812A84AB241008DBF2808202411018880128008220
+:80AC800021242280012E48C0286840982421228064821828411200442003008392A828208468842844842AA412482848F061E300E08201322C822142082902201182342289542418E3048424002885224222C422242CA3424280034460232812800116220512482021888214084F510E8924C4280000804214A42420024028044C012534A0
+:80AD00001810124898248C149824124A02102822A2410020C12818CC0480A8212212184100290541CFAE4511E84401444481282223014382018B4248241644044821218081942412000085042034384124890650682011442482018B244400811014A2414AF23A9B8021524200224812850110080083220420423848222826024890128020
+:80AD800081045608001034184D28482820024A01812442812232121A282822B8A5071843D28442143428481E22164984B2280184428D224D1841E04245384884282C466C8144A90560812024044126923C16D884C2421AE281A2124822128446E2443218288021A118124EA6AFC3074812210020022200488004208404101284430222421E
+:80AE00002240E84192444AC218A012280000C10044811A0482890120D148034C88A424F02AF9808222822221334424242240C212C012422C8162260040828412221122914283548212290221848012028002008844828088820880B948392842DF320C184046F44428842220840421832431240030144141404848480A00280000280020FE
+:80AE800081120818488B2538891308108411848821128481F2D7230085042C81421828C224143304281002211002293442400210D4A4022C012E42222418204302894102200287428028218B32240084802208EF38074418490449012847841225040029624461842D1C26746208122921421204702442682140424802841224800280213A
+:80AF000001852401008818122A480221819F5B0D8212222084C1422848282C044344118204414883010080021002812124902832A042241A84021880241428882308432828C88420AA288A64135F4F0F16082C040012106214100184841200001248122400404828922860820032802602A98182018C2285428802120022800443037FCE25
+:80AF800005284C24411418142421018156041842400C1054424441811008560600810000000010020080012028020080311881F029D91004A021800412224129A1141248121823012301804124024418D0482181839418001A22013018282022020088008011841188849444F0BC3240889258482122126954840044A1890244443608687F
+:80B00000002180418288010022141042081A06002860810044800212442241A281412592481F960330C48B11412F84E182D444F542544F4142839442C3C5522554646781CF21C364CFE6863546304A21855824CC74127868983A8427828D2823A222832412B228721A322228488B315E149A72A824084328234AB488B8A8F38C1C8F93CC18
+:80B08000281F6606182E24642F43F3346489E181F23422222219F1511248139154128544B82601611AF118142632283012E932282C63874E228321A211183A83A2211E182688A211522A04268889A1812E248EB449B1348882B412E44493487FC8094F43B218B124C242811E246612F84A527F44764A022D3AA5F858222B542C71226425BF
+:80B1000029418414C4282C5266181E124D162341B22AC43225C2222341E821E12611822221B22863848F829298168828AA91414CA81836A8856A3A8423F7D8E800222042382484802482048444484088020044000000001008000020022220E281240222822009822089220182F0945F50444741C7A22D22AF84F4581C4F46E726767EFCE8
+:80B180003537A5F85311AF85F54D4BE5E865F11E1C87A2EFC6F75C1A2B445A85D1A29222455CECCFE7F63A3887A12B551E5AAF81F1282A2B331AA1113E122B338F83F1383A2B133AA37385F8687889C89488D044D844A9B34F43ABBB8F2DEFC2FA78ACAF84F44CF5A0114F41F43C2A6F21F24A485E185E766F64F74E3E7F71F74A4E3F316C
+:80B20000F15A7E3FB4F45A5A6F61F11E1EAFA3F34A4EEFA5B556F552541E141E3A2F22F2869EEFE1F17EFEEF63731AFA5A52BFB3F73A3AA7B22FA3B112E181E721F31232AF81F2183A29A2315E387E388FC4B728A239A0884F43F184141E144F4BA39B8BDF6FC4F7D8348F86F5769650444F41F42C1E2E228F45F5585C4F64F16466E78760
+:80B280006F2753EA3F15B14AF75F1BEF84F55616ED1CA7A22F46F77E7E216B55CFC1D1A8D1AAD2A858AA6F67F73A2A87A12FA5E5B4F41A3A8FA1F1323A3AA27336F232328F83F138383AA1332AF728288FC7A7A38DB8888AB824BA34BB34FB34B48F83BB98FE6AFCCDDC8F8257D1E041F11424CFE3F336348FC5F5586CCFE7F67E7EEF8722
+:80B30000F37777BFB4F45353EF85F55F1BEF84F51616EFC1F13A322F47F77E7E6F45B554F51C1C8D1AAFA2F21C8EAFA1F1D646AFE1F1381AAFA5F5484BAF23F3393A2F23A3118B333E322F23F3383A2FA3B322A2338F85F768688F85B738FA98981AA1994F42AA994F41F9A4A48F8BBBB8FE6CFCCFCEFF68487774B02401001890148C146D
+:80B380000420011A04122041242124018002441088212412A812A01280011884180000824008822882289281828902EEBE2028118422C248A021622004C048425048B048024A020000D08481021AC24812840020022220026A2121220180091880013848181CF4CE3FE022F4112487221F4132681FC1324A1D2CAB161D64AB9419B64A5972
+:80B4000085AB944B42AF147924F842B147822D914F82E414F9244A1CF8244A16F1244AD6E1A27498C54A9E24ACF491242CF4912487221F4932681F49326A1F49B26AD141B66AB981B24A3995AB9443BA4A39B42B94478329FBA448984FA2F41ECEE0A2F411442AF4112C2376117842D2C1F222121E6C7CD881F642B75D287CF924484E936C
+:80B4800047824EB326E814F922482F14F924581CF926CA5E812F82641D2782875D25E159D282F4912C2D421FC9B628F49124A726174983769134221F41F66A941F49B44ABB95324AB2AF4439B4AF44383429FAB6482D944FA2F512B9000000000000440000000000218001880000400100000000000044000000000021702104504100808F
+:80B5000082A124184009180083220429944242A02440682284C48428002880020010A2242A2402444A020030221843324426028420F24293A0148A4328013C11CC128410C222812CC14400844042A4248422222116046044848372122656224223616200218110382288228A0586484C14921800488691449D6C2074744128011323E1264C
+:80B5800001245128A3622149C428002446C2424A22A421262A285148846644D881723622D42A22B4424146024AB228244298244B24222A08A428412624C422242028F5B27580010000E19018100818002044384240048902602285040000200200224002002480084A018845C812D04801C04830244F69070000414440180A890124000005
+:80B60000304820242204460400831122444204302244214C0200A0120000001688914428412082028FFD03419012901226826141242250821224906846A224167248322484848421101A94464954A68F41622526044C04412592242826A612C44212588481450843240330384A08F043560000244CC124D048118812186821100242621A72
+:80B68000C448430200441048945E46944C2D1E582302624092244428641A32140000402431142828E0822122028FF2094130120024121012622100008C4602854222342889448A44020025022844445042442504230228608242185281818181424B1410044A08F089C530184602608100A10061428422902820022448290400848448217E
+:80B700008484428C6441248122904889023022212C614100A021264288214A7824384200DFCF0581428181422249042781C1450830688C0484508426C4282932241618024094140012302A8C845242282924A442208102441840C4282015648143022901F0928C00402411D42811880100840000701428021088044A0200220020012842AA
+:80B780000028000012448002890800002041482CF4C372001048784408C9542A18448484008C04F01428452802A042858216086CA4128120C11A478266223624248982021032124118183084162872524824792824C318458864D380016112181E28211281842148818C042618082841AB242E484400100844108824840124200283840690
+:80B800001A222211820284002091285048480037682400402201272444848324245442814240522C006042491208108204464C1814782204434442062542C8248C020084008304411A3214848125982C213D720012C01485410110024048181208000021480081850484A4002C044824248942284288324260C41A22E121628100818C0411
+:80B880004A02410012FFD70F1250288180012140422204105224818034222800000024812444502485C22450284C52486302002220022812100445084120328843F285B74052481A04214444604410080022214048180C8122240048C04280544868008C428404400C460446444808414921020022100484EFBC0E821210C21290114260CE
+:80B9000044434418080000204208240010280440288611480628008421224548083022120041100442400CF0B1C20044290481C440460281642CC42440121842542448422180111A12140221216128A14558424821902441109426814441C420A62842812249022644F87FAB10063014D0210100842100848144440081448181004444A169
+:80B98000100400444008842604100A12181240084260C1184B420000E09F0E42901815082528216424400228241002454214021088012110024648D4822206222200100480062904001243012A048B18A0122810F4553540CA424848008304450840042800441008852612129812D0480C4880041448408884C6482820044A42922444C0F1
+:80BA00002820044E286044002301DBD980A418A19568811C81016548426284A3144208650284D08294688502A1D0A4542C8D488744AD446E628B4427624C724462422C922A474281CB224E6C4F22F142542A5128163818122AA2C2224ABE2422628228F079D640741642A2513463F112442B448F24F44A4C469848404A1256C825586C2F8F
+:80BA800042722C2424424A522EA53442212450464F62C228272244CFA4024782284546342C4C3214ED2822414D1C8C044F84714C588C004CF22414C9D1E44172127248E4815166A951E99724454604E95422261EBC2A4406C59642C54A62C2CC3218402CC44846D28674445A8823B14C14BC2212722ECC46A5FA22282B44F048482A22F11C
+:80BB0000122889034F44F1444C8D241E743E148F44D44C137E88D8C2A21400404801004110840400844008100889028100304820044222810040280224200224126081E081048C84A2410000284FBD082B441AF1141C395146D751CFC5F446462FA4F442422D4225B24A5466255262255C4445FC22222B66CB464B22A55AAAA54CD66E442D
+:80BB8000D28E5424AD46AFE5F56C626F22F224266F625224ED26AF82722AFA4A48CFC6E267F77276AFA3F33A3A2FC301522E24FEBC3E34FEB44F42F2343CCD28CF8353C8FF574AF246444F41F51C1E3721E7C15751CFC5F442422F847444F24C4CA18F2456E625526225584C45FC2A262FC4B46E56841A518A8FC87842FA4E86A7A4E7C463
+:80BC0000E764B736EFE3F76C676D2E67626F6276249A2CCF42F22E2EAF84F6444C7E362F65F71A3E2FA3F3323889A1544F42F2F4FCCF43F2D4F44F42E2A3F32E28CF83D3CCF11317F042426F41C51ABB11774183F14C4E6764EF64F44A462D46A7A4AF845664A548548A4554E42FE2B222F26E4C4F42D2A851AAAD8624ED4C246D4A45D60E
+:80BC8000FAF65A7EEFA6F6262C2E226F62562EEF62F22A2C6FC2F24A488F86F6787A6F67F72A1C8F83F11828305CCF42F6F8BC4F43E74EFB2444CFC3F32E2CCFC3D3C4F1F2E4F056564F61F1181AB3711FFC1919EFC4F54646EFC4F44E4EAFC4744AF24A4A655EAA25548A8554C6AFE2F2626CCFC6F6242C8D1AA5DA68F8424AEFECF442AD
+:80BD00004A6FA4F44E4EEFF6F47E7EDFA6F626262F62F22226C7E2CF62F22A2CEFE2F24A6C6E6CCFE7F77674AFA1F33A3AAF81F21C14CB55CF42F6F8DCCF43E7CFFF2468CF83F32E2C8F83F32C2CD76280014110048004480000404842480442400400420020048100000000228C048C04120000000000007FB50543084184496181611079
+:80BD80000842844008400481431288D4480281414018880426088C040083022484400880C128A921118814A8424A41180840F8CD38C0521F4152281FC132481F41324E1D24AB141D24AB9419B64A19B54AF92448AF147924F84A914F82D41AF924488DB14FA2C4814FA27458F1244AD6E1A2645D2E4A8F49C24A1F4DC2421F497228F29154
+:80BE00002C87241F49326A1F48B24AF11124AB941B21AB945781AB944F82B44AF934482BB44F8294924F8A84F9244AFFE4042D5A1F4196521FC1324A1FC17242D2C1F24E121D2C8D961D68ADB61D682F64F924482F147924D83AF92448AF145B86ADB14F82C5916F82FC588127A2D67526681D67B286F52652178D6F22F4914CEF22749126
+:80BE8000386E1F49326E1749E72617418F44F81124ABA45F81F242849AF44AA49E482F44E283D442FAB6484CFA825A1BB700000000000000000000001002188008008044010000004400004004000000004041F1FD66108192284441248110441258180048A8C44921921284224100101648A241604424004422851462822062424440A8F8
+:80BF0000213044822AC128414B21103448C301CF540730862001290158A12100105281841028542844C4002400104C5A2C2638248D4465020045024443811198261882309829414424024C82982414CCF2243B1031428932140025884106418122704831288116CC2212653A2441122018042489417C4374241218084A52846502441844A1
+:80BF8000459824C120C214924933244443C124244D48471187439F2B02C0240045220148A1101A4102204804428440080025028485C4426082D02444140600830243A2212480A129E0881402812228C0842281F0FA24400221104414843224000012008502A524024904260824448400B0221588040000410010CC6842001002008962825E
+:80C000004A01A042CF8D43A224E0C2012CE112612218247012224108842321C21848844483810344284A92124E2E46B4465248701C02690100288D12831104241A22CC12856481848934280090488504FF46062724702804443F4241244104212311881108248014081E4C122608202631683064A9014D1A20010000214181482983485277
+:80C0800028816084842222188C442472220A22241880012682C2228001002418897218122C12042210C422412558246C044C4688042504004C32188301448322242411841108288184481088F43361004224450218004110542820028112200210C238128CC22C4844002E1810721244A43844411A0443C4420062B024084181A8282821E9
+:80C1000000521225F461F330184212184C4808859112814140288204414284448C5482448F411206122C0244902884008180924889342241405884901C30181E228024044C82528200CF3F063024009E2820A412818001C04800106841282149060000A122890180148842220200402802C04810084048D8481104450822709F04182684DF
+:80C1800031161E288C0119931200106284004981C4284D2248688D344522922458A74228181289D282941A438238264C9218482746E4006614E8821148C4182DA846C8361044A41412F0E518000010064284C184188481204408844C018145082658488440024598280041A012001008422881844282608100288C442492288428412F1FA7
+:80C200000C29111182118A21942C00000080410460A141801142C42400124118490143229114301845F82418301441478220022901444418C024184C0244419F18031054241014021062814088110284701A040010644224401C582840224202286042441290282002206142821200108801003018EF150E4C1212314949131C12684264B4
+:80C28000301844106841448140C41812428400214100260248100221181002898131240021818482180020921218434472AF09180044108211420838508216941221230129B122014421466282211642924816022C818201221824C054182A84048312E8412402124888380026082168CFCF0B8248811100834424514281004421104884B4
+:80C3000012880280420418450244182694122604210042265848004A41840241808818141454486954841889F4152B00C06400242006801102800320D148110427C421412189810412904484400812244088040000400449188C820822480040F218C3000040981420018301442481451808210049058514888432241A1494428448268A38
+:80C380008404280020144818A8248181841212841266988800228428CFEE0B44519014002606A744250225321840546212704A5422811258424668412D22008481102CE122612289012761A01220068441222941084548081828804141F1637F6082322A648232262821212222E242011E2848002828224210022A21A4848921A4212B24C0
+:80C400006014244C6484248C240248228301481216448406122011088324141AD2470867437759E3725DFC22129048CB246F2651468F23528A242F417114D2425128A14F254252A84961448544F226341E3467815863722818D64892262867224F82321A4F2492564A361C8C9714F014188D228CB214CC1447C489E8844224624418DC95CB
+:80C48000583F2209184A0229A3216FA1323416149838213883512822C5D8446163837224AC511A94544D6AAD68126B428D42E11E582D342E4227812AA552121260C12A62812E68C331286E288B22728B188C212821B818F12C38F02A288C4461644FC24381021D2414C5DC48F142122FA2C12C168A61216D1845F84A1C1632124D182D1C82
+:80C50000AB316746C41638624746AC7448C214564AE625E4C1E32664E12765782D124D1AA97158FC281418624E2C8D449012674181CB818B924B1143A2814FA5B2143434C12F82B2DB0730228463022A4128222142280200408802008304004220044A1234484B1283342442430200430243A24143026220442844E844028D24704824E1D5
+:80C5800044F29CB81435F13311E57833718BFF381EAF85F52436EFC4752C5EAA26F2181A85FA48488F81F1181E24CF84041A45D8CCD4CE52CA6FC4F21E54ED1CEF41D562F136542F82B33653C24F437144F214328F81F13C3C5E5C7E584B114912A8358FA1F13A1A2B511E548BDD4F43B358A5754F29F95E56EF83F168284B1187E27FB4C8
+:80C600004D51133F51157A1351FB8FE1F118124F63F35E5CC5DE6A5122AFE152AAAF84F71A18AF61D166F24E5E2F43A311E5F84C4CCFE6772AFE8AB8AF61F11E9E6F61512261BFB2F22662A5FB2E3A67224FA1F7181ACFE3F65C5CCF87B7349134C9B134F3585EAFA7F73A68CFC1F55C584F4F3F188F43F1F4CEAFE3B13AF12A244F44F58A
+:80C680007276AF1747D322F33373BD2BBFB2F21EBE8FE3F25E4AEFE4F75E74EFC2D2EAF23A3A8F2153ECEF24741A58E8CFE2F26E6C212F81F542488D58CFE6F72A6C6FE6FC3E5EEFE5F51E542F47F7365C2FB5F756782FE4F6365E4F65F5267485FC282E2FC4E646F454244F45A3465E348FE4F67A588B21DE848B99CF4FFF98884B314FBB
+:80C7000089F85C6EEF83F47E784B114FE2F15E53342F62F33337AF22F23B33AF23F33A3EEF25F45E76EFE7F72E2AAF22F23A32EFA151A8AFA6548AA5F22C26EF667412F45A5CCF84F44C484F26F66A68EFE7FE7E7EAFADF556542F66F66E6EAFF4F62E7CBFE4F7767E4F67F52E26A5EEE7F21E7C4F46F62C244F41B36CF574742CF23A2AF0
+:80C78000AD38CFCDF9DCD8CFCBFA8C9CCFC7F6E4FCCFE3F27E48CF46D764F1647647F61004148041188414042001402441044412281283044C02440018800122800118841848184820216281200892441220810281F0C5B280014501411222484008100881001008445048102812180484200200800284428C2642284208008498822002E7
+:80C800000000482F440D2D521F41522E1F41324A1F41B26AF11124AB141D24AB9419B24A19B54A3924AF1439242F147924D812F924481CF9244A1CF8244A16F1244A96E1A264592E4A9E242E5A1F49F224421F4952281F4932681F49326E1F48B26AD141B26AB981B24A19B54A3924AB9443B2427B2498B24F82A4944FA2742A0B2F92D549
+:80C8800041B42675117C6A53416E121FC1766AF211442F665981AF64BB15D228B924F4429347813CFB24482F1439262D914F82E514F9268A4E816F82611D65E81D7226611C6F2271D17826F29148EF227491346E13396E13392E19F46A961F48B448BB85F642144B482B348AF442B6482F443B122F44CA5AFF9B01848200000000000000DD
+:80C900000000002180018800004001400848000000004400000000002541F19BC430442400128902481391426012001008203122444054248352280012388904100A80214A244202184280322881C648EA4801C1A8280044E0DF0424824C412314C2183C018512C8128464604446F818244816E2848182813444442C415C864829D224C91C
+:80C980001828444722491224A14165E841C2428427228A011002893248000084144D485FB20F2C642C44144A41688156911123148472224806464488E22441F214424074147224E8C891122574120829348127812D2885D42462474C62414E32C5A2124E12422C229228261648E242098122404248E5C1D475044180012582021042183AC8
+:80CA0000110040287414083281221848420084442A9528490100008800100485029810A8488184831484280200F021440044344C621220820600400118C03410084484000081221218122A011860224421C421844008124220041884460420088420F2499C604222430223E162C1182C41CA1200122C45280C1662428B141A22332881E37F
+:80CA80006284F0184467266082422B1281124240068C9444126A01C9025280289C848483839118424281F0E6FB200215C6241B211A922252A522110220D582218C2131224812288484444884ACE1421582C21212841222101218D24804890389024A0188484C48C828E088210484223F940D414C2242024483810200C011009024109C18F8
+:80CB00004C628128902A8460468061812A2422012C4444544246081242C014422004988443248101608400CF33028442301216048128102881024424284A89823144003A0420348420828104412810088045042443440880028828800818448C8402213F410C8D124A1168822C04224E128904C91208221200248C8202C18427814344249F
+:80CB80000800814E280028C1412E8C484284488043C24484008C824888440821C014AD426F54050012804238140000400810088100220080420821E04482218124888101124110040080088440C21810042800001DE1801112F82218461468C1666284902828408411A281843638241044488856844121224E14844A428482C314444F8216
+:80CC0000886144842C14E48102C881815028188C0816481482C21485F27826001218E022012212408841180860824222214828844A034448002022C518428800804104448004108202826088904420324800481FD4040044422042F4441881002418842180024846228301450810082A012001814004400C20012243248288024122001075
+:80CC800084A18400DF1F0B18009012000041188D214001188091880000401C288201404488010041229014824044148228044440286A82281822444914F4EEC5501400128504200210880118004361431881841A04422004482304238144C8421800121A024C21051008A048818A01208101102828B2AC042416C16228102C24A11400101D
+:80CD000004CC01008100200100182A21424828614A8082820360818C42E8888282C2282800A441A441800228211235058200181130641100288400180060422084440840A8148A1408584242482001000048420000A84A284188120862824280F2F2E510522449C42284414004128422124481163C48CC22410410321818888D8426483499
+:80CD800028001200101448182404001218442412008911349820141806F75FA021290225214131184249C22D401408202202426638242222228742222220C154414D28902458448443C27442218504852404C608E048644420346449E1C132842AC444BF4807492204411028022A01282C012426044C08C0124425C8264304434404A50496
+:80CE000021448110A2521608008941021058848084011024020021008B377042C9114840844301456881164125C4210000260458442D48A052804C24644181222E45604684224830282E44262486E4428174220C4B848168421A44D828944C282FA812B8E40319A71841D0C52131385F85F1146417812E2885334484853818CBA2814B5BD6
+:80CE80001668A24E482267448B2283B428B34464844D18AF81346C8FC3E144E646E14264821AF2142885F822C44F433468628FC2E18EB128A848CB81439542C6F42844124B42CD96282E64218E567026745146E4623112D9C2252E448C911C1E111B31839115499114124B328784C9E44495148D2C4845A8484FC4E481D24EF7384449E10C
+:80CF000081B6440C68414B318187464AB158734898E4CD244A9624CA2624A4884283B256B164A82123778C34444CF271842416D312C2223B618126BC440483C22481269812342F4122624416C42466B216222375386844478212AE123224444C81522823A13185644218474345C8124032148542A8A22F48D5C8F12C2C8CC3288D384E1C4B
+:80CF80008CE686BC88F824584F860930245014008C04122240628164124C02A0416C22D1482281024C8251482142290149012142188449811406218C148614628821482148258414022028F46E2AE0347422F613133F71F1212195D95CF615358B1197128D23AD289F34B416F111114B318F8D7D2CFC641E6F83A151CF840628B044B258F9
+:80D00000B534E7A37156FC6466EFC4F4545C5E584F637326B434F3141C45C4626F23F24E68EFA6F62A222E328B322F2272CAFA1E1AEF8159646F61F13616EFC8FF283AAF8EDFCCD48CF868224FAD4DF353562D463F31F11616AF83F319198F12F675358F815151CD17AD289F76B616F11D394B114BDDCFC2F144126B514F25B55624B11845
+:80D0800041F84C88CF85F57C784FA3F116144F66F64F4DCFC5F53C7D4FE7B336F3347CCFC3F32C6CCD2C8FC3F25C6CEFE6F622264F22F73C3C2FA2BEE2E444F414126F62F43E5C3AF1AC9C8F22F3CEF8EF8CD4CCF83C36AE42F052637F73F713173F73B3125119CFD6F635351AF321217CD333F24B6B7F71F11B19CFC3F3F8D8C7C24F2795
+:80D10000F53E3EAF84F76664226AB368F46CE48F87F5745E2FA3F5565E6FE77736F544485E5A6FE1B466F43454CFC311F848685AF34C6ECFC4F26268AF86F168768B242BAC4B54CFA47D4AF454144F46F4ECCEEFC6F2FCECEFC6F6ACEC8F26F7EEDD345F47F735377F71F11717A3F11915CF96F671358F83F229298F72D3BBF24F7B7F7159
+:80D18000712FFD3C2C4F4FFE3C1CCFA7F73E7E6F46F776743AB364E386F66C6CCFC7F77C6E6F67F7565E2FE7F75E594FC4F4757E6F67B676F62C24CFC1F37C2CCF64F65E744F65F74C6C2F46F642548F67B768FEC2E26BC44BD46E66EFE7F57E54CFEEFD6E748FCDFDCC64CFCEFE6C76EFE30714B022016184414800400812608160818580
+:80D2000024011283040000890283A412833424800143022642A8122022018648A241248424164826018289028F6C0923082C01221222901C1222120081128122421280048485842481250144484CA252302480014B1220461C62412502004C0844004782812A4444F974D8C0421F4152281F4132481F41324A1F41B64AD141F64A921B21D8
+:80D28000AF243915AB9443F24A9143FB42934F83D412F934481CF9244A1CF8244A16F1245A96F1224A96D5A6E549C2DA1F49D222F49124CD121F49B24CF19124AB841F48B24EF98124AB941B28AB9451AB9443BA4A39242F447B2498924F8A84F9244A6FD2092E1A19D438A5218F14F1112425E1C1766AD141F44A971B214EA71F81F4482C
+:80D30000A182AD314B4B25E381D418FA12482DA14D5A4EB1ACCCA12A651D2568586D5B8E218CFDD12C25F2816C4D521B28C9B191B64AD841929E1F88F62A941F48B44AD385929A4B49A9A34A2DB44F8894326F8AB442F1A41ADFF90784000000000044800200210000210000000040014008480000000000280000000021F019FB20018C38
+:80D380000218206441174112848021118C22018812188C0246084823011608128418222216C21230184963482C01248428890884840044586088284988F4AC8D403285441682041189824214E12102259441100C16084144842C129C24848D26E04441A42548442448418480B41A8484112218A81288009048608A8118401174C70D166296
+:80D40000548418480083F3211418C12823D242118CC2181008124C022315E828227128548248121B434A0189A241464698184696542C042489782438A8A28184004138818E1A908416F4167E00302490126014444044218101460144802941441868A24449140812494144084302252201A01286882111022001003048B04808200248CF06
+:80D480002502218001803224191208000014412140A441184142484604280021128CA12122124116140440044481822180618944484C0810544820045F170A4942024522D242512187452C6287A05290129052709844D84A4284311481A42CE284B11E9478202204412042028991665238896262C12A7842180210C2686E88CB42002A05B7
+:80D5000042475350429012902238284C84C258800212245821C48594121843C11460C4245E2A16C82821284A81420460414018E24421436C828D8429C24A400829E4CCB2A8D4481444A44220F416A4200240042554143D388582021A44021441A081306C4480C4483022604452201128212261421086E14204804206882118984400200247
+:80D58000811842F0B198B0582246816241818C42410C44421002A554422420164224B21414028B1A00C1848485328849A26120A1C16042842110C448411261502252428144A28061249FBE455248274412612042D2240218654182A18218284A9114821004581245028A7428042480441484118811B822E481220844004128209424895804
+:80D6000084A82200444183F213670080C2182C02004A2244081001008126140888848140480241901428004022C2A484008A02128140181208804804281668842260783446062E1349426682AC922427C44612092131122522341C828312028C518410829128101806C46122A0128F628849B884E2884224018CC42A128914046B814EA440
+:80D6800084443668444468CFFE092AC12460812A01102122014818827024C814D042824434844AC24244848B2461444183E182048C68412E5280C1282A012400C400244124863848802282488843D8B50B104222B2261421321123C31266022800244D28608227442818188042888211224408212608224100188004D02812081812210009
+:80D70000611820850228AD22A0244144004A218112141B81042D1242A0414A01800184002C81041E461280C2444224A01228108832188904214210042084016242800888DF5A0880040000181480512116828121018B211883010000824048D42201C4220080D42822018741C0268141000089042548820A00002F4E07F01822414149520C
+:80D780002400284480030026044483042F42280326A8144C242304A0182218241A2203A04220088242004C82089014902890144820B81874760B40014870129724242C0500174460215026C02284120050C20088890181814912922242101202604481228480012400800100222074AC04CC0211181162124942A4121A22062880A2824202
+:80D80000214A42883628CCE222C12C8001A444218422400818AA311820314244A024892492221284404244048B846889F87461402A814194424002002D4121401414243424421042341400304C252884242121244102008542048400212100004E2485048162814088F1968D20684821230260A411408448F31428002100184400221270AC
+:80D8800042122404004634824284100284463414100428828936588148256A4C85240189081C44D19E0F46889241118602001414C014C02825846121001244842584E484018F214846082412164108841E248C44028141702A4414480429C2880022C914480423081F690D4C32A345D224E246BE11227723F632261AF323412E7123A711C6
+:80D900006D522E326C23F1285826BA262282F124224E684B562E68AFA9C518242F81A8226CA1662682C4228416C21C4CC8584644F22A26428C0484AF846C2646842248E48484E61A6884EF4B0766B294416444F04614441A5215144E92372564250A45F45488CF4615B248E1C8A1418F82821444FE1E12D062F412488D144D5427898391E4
+:80D9800022224F41012F8C311A12418D82894618B248E2462181419C8EC7626F8445B818E88AE894B498EC7703488D6637113353273CD42AC3114A51E71A02D913644123B12294225E226F4124D184731474187828928A463444C3A51424A7A14B66A489F112222AF438228B2243F42C1887456F8274261CD488AE1287292542925C16CAB5
+:80DA0000188F43B264450480F3383820840180844108844148204104800448004400208461441842188021A412A012200200000022001A04808214088182707B014D641F13A3111F73F3A1633D236F44F631214F57F52624EA2AF248484588A133FEB22724ED4C8F82F228388F8414FC6C666F62F626266F42F2441A1A6184C5FC48488EBE
+:80DA8000A44652226E626F62F222222BBB5A65418784508885A8CC5AE58555888B89AB262BCC25B212F5343C8BDD4AD888D888E8FA0F4F46F235751F61F132341F36F263276F44F635356F67F72734FEF43F32F27B4D45B814F136222F2BCF12EFE5F16A38AFA2B146D48CF16A7A4F42F264E6AD6C47C48F81D588D4C4F149494F4AFE58EF
+:80DB0000198D286AF62466AF23B3B8AB551E148145568A85F8C2C46AE6C7578A8BC9EF47B3D6FD12122F85F1743C8F2DBD4224785AF8F777F024665F53A7331F33F3E1613F54F24F6D1F13F27855EF42F3F2B41F16F648684D1C29F132322F2FF94616EFE5B56EF32A38AF845644CF64F726666FE2FA2636CFA4B514E18551CC8FD4F68829
+:80DB8000AC8FA6F6222A4F66F62666AFA2F2B2BAEF4524715C5E622D2885FCC8C48B625E788781DE882F67F3DAD6EFA3B112F52C28CF8CFC4A888D888F84F9CD3FF064667F52F231362F63F363233F57F24F4F7771AF77F72B372F2FFF2323FFB5F7161E6F41F13632EFAFFF6C1EEFE5F16E3CAF82F146644FE1F3686ACFC6F66C6C6D64E5
+:80DC0000CFE4F45C5C8FA5F41C1CCFF7F6BEFC9FA7F7323A4F47F71436AFA3E3ABF95C5CCFC1F15C5E25D68AD2ECF2CAC88B664F85771AF8DAC8EF67F3D6D26F63F17A58CF87B7DCBD62FE888A8F84F9CEEA1004250165014522412201402141026412441008008514624429314818103448218001219016844D128441008C0484248C448B
+:80DC800044C8241220384820092A24818122962129912149816216901A1022B148024E243618220380A242400A002D18281828214CB228010042204238620010021830424321A442005F7A0D2E521F41D228F1112483F41164AB141D24EB141D24AB941B61AB9451AB944B42AF14B924F442914F8AD412F924481CF9244A4E814FA26415E0
+:80DD00004FA2651D2E5A96C5DADE242E5A1F49E222F591248F22F1912483F69124AB861F48B24AD941B66AB981B24A3915AB944B42AB9443BA42FB244829F9A448984FAAF4D638E022D1C1D428952189D141961A1D64EB141F48D64AB111D64A9B61AB944B4AAD914B422D91AE482F14F92248AF14F924124E914FA2E815E8A2611C4FA284
+:80DD80006115BCE95DE2A279D1FC241A1F49F4285217418B861F49B46A5841A9F98164AF467191942A5B69A9B984943A4B4929BA8494326B4A29F1845ABF41042788820000000000800200000010020000000014008400000000004400000000002541E18F04224180412402C0144421001142800118812883211118020012842981618399
+:80DE0000382224406248C01C10240228800883849158418012442414F49F8D14428A5142204812649183880226092135448804AD44A041418748412489F228140043141828889412204368A12822C33518008CC8284824400824D08401501C81F72C1468434C849184001C31144912C42122140042204548D2482131186088122011183230
+:80DE80001189A12189022B258129296281124128B08C82224A8284114806835124414661815F430820110280124638881042480227548418504AA034D048582430228D2400493418848AC2421200401CC224C364810040280481844A013024008514F477E780810200104C5422114008150810020000502440020024002825020024102223
+:80DF0000010000122100222400410044F0F8760024008126020000701203180044002100002508410000004C025048400200808181020012880020314800BF8109182200812C12480400243C0112004100210044000000002821260410440212008001280020210800188C4404AF780C400A0010042512018144150810020010022424852C
+:80DF8000024440020024008485022400003014122100282400411002D01208114002842144254241082410022150240000002441004004446184442416140400100224202101432408450A58844400BD4A0000401404159418228280C18145C81A8021022140C4280081844112254228011844221221444440E2886182A8840081808121B7
+:80E00000110400C0C22400114100002004110000120000810010480200002602248200002283A8410000252241020000449084F0118C100300444144248D11662848810184258A4106241018C4282484848441412502222149415442160444288229719268A2A284168251A48218450243440886043FE80600344485022415040050221369
+:80E0800048240112280000004110021850A416440829A8212400448148002011024200168821411404F0BCA8004001250214004001141008850200000010040021400200214421100224100800248001000000005FEC0D1004100410020011401102008410184418044004848544184242020040444402602100210000181241128410089E
+:80E100001FBF01401841022124004041411501000000618144004110480C1002250284400210021810041002808101101842089FCF0F85784804400411005044453424248440181208A4255222123084001012184302855888C31412440424400A45544643021200108441522225A2118FD1070000000000008481002100000000000000AA
+:80E1800000000000000024400281000000000041FDC210C84842484002400244414C2282020000101292121684298848042114111484818C24840424000044414C62222810120800212129F1934B400A4824104408210025042C0200000024214418418800810014008480044004240021442489021008000021F021E400000000210065D9
+:80E2000004244008100800210000000000008508000000005044000000800110021AF1322F1002002400000000240000000000000000000000000010020000004042080000003F17051028240400005044102E220281004002454224614183281804001131850881462444020000454412342826880181002440B214F1CDFF5082858884E6
+:80E28000441244022502405444282800000010128281818808004041018485888404442400008554442828000000109212AEA300101403240014244008100821810000004400411008000000000000001012080000000044F0668440020021000000211008000000000000000000000000004002000010020000000057D22410421241122A
+:80E30000424812421212184A1208400800004441004144812100000000400440021048120800000000F02F62502200105224001042120281250810080000410084100400000000002121250224104248022C518A81120000419F4C0C00442440542221150200A48440120A0000414054440040084002004004502400214002A184A10084D8
+:80E3800000004144CF1B0E672225A2122B119012C0123582F8121317319B88179985F888414E48D09114815489814F84744854444B242E24C024805264412E24672225E222B11281B882092C5922882F317111B388699985B888E484048C04488518F84448BF83076F22522418122311021C512229D832B11191811F8818D8182464849494
+:80E400001581445888488F44149C242226440428255444286F2252242C21A181232888512229D832B11191819E888391484246480848848588F48179000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000043
+:80E480000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000BE
+:80E5000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000003D
+:80E58000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00BD
+:80E600000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04F3A
+:80E68000FE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000FB
+:80E70000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000003B
+:80E780000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000000000000000000000000BB
+:80E8000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000000000000000000003A
+:80E88000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000000000000BA
+:80E900000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000039
+:80E9800000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000B9
+:80EA0000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000038
+:80EA80000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000B8
+:80EB000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000037
+:80EB8000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000B7
+:80EC00000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000036
+:80EC800000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000B6
+:80ED0000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000035
+:80ED80000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00B5
+:80EE000000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE443
+:80EE80000F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000000000000000000000000000000097
+:80EF0000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000000000000000000000000000033
+:80EF80000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000000000000000000000000B3
+:80F0000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000000000000000000032
+:80F08000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000000000000000B2
+:80F100000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000031
+:80F1800000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000B1
+:80F20000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000030
+:80F280000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000B0
+:80F3000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000002F
+:80F38000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000AF
+:80F400000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE14218414942518048C
+:80F48000001004002444444424240010041002A1C1001018080084100440321441100800241644060012F08C184041110815465868C542160440548444812502A504A481101212420641218181C12444218481248514582C8D14612480911441446512149812122D1289418AE1C80621104802A100612141004100214008240000504200B7
+:80F500004100418464008150424400101224010040941200218481F03DE24051811440014425084100100881440050828140140200448400401208004008C1276130142190180000814112184042B2BA09001018141408000000444124100400240040022100818400004008008400004014140460214002009FD104001011084004004069
+:80F580000410024542020000240010184208000084004008400400414002214421001812121F5E070000000000000000000000000000000000000000000000000000000000F04FFE4002841181000041840044100400A4400C1002100884100889022C012821441008008400100422101298284144413F394F0111004044484C480824C0B1
+:80F6000042800424800400415084211024110C0000004481641224122418001606644084410200B02A46410284104804448144810041210000812144502450A440489418C18190288011821256482481240084006C1144264204902800441F550E100111008184400810820449041082048400000000000000000044188001290100000088
+:80F68000294118124404DFC5090010019012009012800100008100000010080012221042A41210224122080010021810022C01004200707E06902226140219114882921880011042420C1224478160818484842902105882844B128D24210018A1408A626284C10000182284848480C2148D44441FE80120121402182901294218024002A4
+:80F7000050C2301850860084812422002481222424410029110A86084425181802002321421A1808621845089FFC0C2480120114840018121218000000800189011048084028113834C3022A0120414222820244001200800100108414F44BB21045040000A021127018043212184341020021200181004004122400221618040010021832
+:80F780004004D084121A244288411842086F6B030042124001D41008448126054012040025041200902410084400C0484664822B214912022200C024002880028002214489F5B114241A2211210200004100001004810000848441005024100841814112001002810024404808120024440044005DCAB0239114111A0200C11A9214401810
+:80F80000981412492151680010441848048012144A6841101AA41441833212274240280224608281105C82222C02124014C4482F2204450800100111400812100140060000004008411004400420221184420224001200001840048524120881F0C18B00002001000000008001400410CC288184818483010084848C0100187014184828AE
+:80F880000140280110880200440020F1C73E0044486400284138002021018041222321822401001844184D288C82024180018D24422441702448B284821248220884832281012002225F9805000046044220042F24014220243146414A0200842400800100C0280010021800400880288208888008840000F0CF3B6014890240C8680000B3
+:80F900008006808304210018222432204128021800800112002D24128B2141001216849424E04112080000862CAA48AFAF0A4C11142454824122001840228101004400D0480200002800200200004110281208260832840012A0211200261408A7113FFC0800200100442A0118002818008091488C0222228100200200000018100400002B
+:80F98000504800000024604200003B7C6082006122108411082118830200214A418601D0424102211221C127821E28440000441285421484932200F012840040824848048110081F4B0E1200002441001810020080014002000081218421122001841224000020011A02001A0228008001002C02C731704418D21404454248A842242A245A
+:80FA000062418006002880321812618418218844182140480140088C8401184312840400801408C44014482838CA86F4AF638022522447412183722294343A81A211222383A411521266F414343AF122388F41F234148F824258288CD1286323C12042A81180014D1881AC2161814932284B1A2688014880D28AA2116341440826A9241F2D
+:80FA8000310E4F21114844D2C8429824442C824532428981210249512250821250A81885721218088CE18291288D3422C52861212187434321F12C1CCB12A7814E32F018348B874923F81818A012400C43A288422B98FFC20E1F44544414424D52469448488964212B421A812481C4122994142A24147864884212021672341CB4126283EE
+:80FB00008481006041F02256C584C2242604308425682AB0A452888E8481184782818D2C8F287A14F8A8BA1001100247242006626024200446044E22C02200000021104204441844408401002110022B84B04208291894824120110800F0176D141F3555431416B64AE4A4F448486AD2A8F432726B64388D58484E4225B252B564068F870D
+:80FB8000A7114FC3E38141A822A4212A12528C4B118F83F2242C45B81421F11416AF81A111CF41D16E512E6F61F17A682F23FBEAE2AF2EFEC2946F61FD8A822F4BFB282C45B6160180F888C8EFEBBEF30F7E663F4646E541B42AF228268FC4E446F2185A2F23F756744AD7CA87E524F556466F61F122226F64F43A3883F13E183E1825FACD
+:80FC000022222FA859822EA86F42528C4F81F1152D4D24C5F91C181AF1444EAFE1F11252EF41F11E16E5FC141C8F85D622FA9EB81AA3156F61FD8E8E2FCB79285C2425F42828C5FC82A88F88FEBED4EF1C0D4F27F723644561418B22AF22F24E2C4F42D6A8E227F232246AD7882384E125F512126F2333228F8666826FC121B128B328D227
+:80FC800028B81AF11C1C2341A4114F53A2331E141E1847612F21F516366F61731EF62424E5F41C14CFE3F2E4642F42AA224E328AF41E948F21B186D864B1160145F48EACCFCCFEECFCBD97F075373F42565456F42C24EF26F66A284F43F7383A7E322F47B732D38EA1144AE521F112126F67F77676AFA2F222284F817114FE282AAF82F26B
+:80FD00001A8AAF21719EFE1E1EA7C28F81F13829CFC37219EC81F11416AF21F41E3EEFE5F31E1A4FC2526EEF41F33C2E4F4FF73ABEAF8FEF25F18444AB918F21F18E88CD1AA5AC22C5FC84ACCFECFEECF4EFA50D411004400800122001402201124410088D2490281088810281188100000041844961812001842001842800400428F024A8
+:80FD800095200800004100000000C012008001180000002200000050261004A0210000180012288001818260984F21012CF4112485F211248B141F41364A1F41B64AD141B64A9961AB945B41AB944B42AF34B924F442914F82F442914F82C4914FA2C4814FA264114FA264194FA264594D4A9E244D5A1F49D224F4912487221F4932681F8D
+:80FE000049324A1F48B24AF18124AB941B28AB9453F84A9443FA4A9443F34294478229FB2448984FA23498F022421FC1D42AD441B22CF1114483F21164A3D241F628941D4489BB15968A4B42AD954B428DB14F82E4147B26C8916FA2C5916F82EC11E8827498F5245296D1B4E418D2A4F581284D5A1B682E1217C88B161749A3F48124E941
+:80FE8000F1812CAD141B28AD3413F84A34A22F6461838F44588429FB26484E946FA271620D0048000000004480020000000080018800004001400800000000400428000000002170FD010000000010010000844448800400000000008400002821202101100881008220110812812008D09B0EA01890140080A1144484281200804202415A
+:80FF00000012A41002855442840040981220110800800141204208802241388880A1211601DF9109A014C05400001815148C22020044460243440212164A2208451806100984A30166120812001881414122220028126089C012A812127FFF0400000020210400180084280000000000008400000012002001001008818220114808842014
+:80FF800001F0B16A001141440020010000001200004210081002001008C0120010421404002302201802000010045048F0FA6100444002004400104208004142840000C100446444808622021880429412000084890822800889E121440A8800008F9D054044440600180010420820112414080084C10040068084022C01404214460400F4
+:020000040001F9
+:800000008982088880088901A130840084D0C6071001000041000000000000420040024140048302282001222001001012082821008005210010047FC1050042100810042011148801400810082149220144004088018012084245081840480440240180021224004004849DA8E0814424044400004410240210024100100A1602810021A0
+:8000800000008481A014804208800124C024002833020000A100EFDB49024004000000000000002001C018000000180000A0120024004100801488088111802121420820F4B3DA90420000000041184088014048048110884202001012080083022A01C46081409C1400488C22088422122C012884C1003F6C0E8C411404C10044000000D3
+:8001000024000012008D1400450800181200002001282100001022014002001800008CF43BAF000000410000004901001A8404608228004100002200000040080000400440080000100C8282844FCE0E624441402201181602002400854208484E2E44004428002800212100188C019022258A12A8212CA2828A224102841883223118A0FE
+:8001800024848118DFC10D84810010084110942420020010040040020000008400000020040080044200000000180024F0EF9E400116440C2904002588810445C81C444C0200448129818213420216121414180200A121100200811008824C222228294108926084F0BE2F208C0400000020010010044884890441000000000000818004E9
+:8002000081100881B088849228428110088188008228146B45000080010020021004004E12400281000000810000100284800400004C04414C040000884A02109292F0FFE1C01C80829424B024311241123012A01484A901244A3234288429634241008042C2222A01282D1220C2222AA1122013228281388280C2121812241840082188E5
+:800280006783000000400212400218800144800118008410022001120000000020010084001008816088000080F8FA85508400100449C148411A2462C38046741242421474120228291282818198222829922885420324849042812A412842084848862C88222228082031981002DFDF09433584004F6182D12492144118248C43D448C594
+:800300001845E444042FC4A1142E1487823026282140A82122A321110224188184A3433238228323B228ACC68DA85088106A8187888B81818F24098E81F0E258A042836441004054821E12CB412624B5140387411E186901246F411212E4214268420022182D242CD28A42122201242C22F43218405882ACE4849124124A48041A8829D1FE
+:8003800082216189D0A885F833A450419024C304E3A4111A4494221A1342225424A562A36F44A4428FA2D48C82A2124C5224182429622224478224C0228911B24212C22A28841A024E24436888236CA8E082E388A12898624C81B28828B288F15ECFE041021E24818E24A3C424A3C424A304A3062100226081200100244002004981022857
+:8004000021280081100AA901A901AB12901A102A126A8A142E48E082042F56095F14E643F3383CCFC2F61C1A3E363E7C4FE2F74E5A6E264E484E5A2F24D1ACF4181C8B226AA6556AF66A2A2B221AF114148FA2B2220221A50A2552222E222B22B022F23222248B221E188FA3F338328B332E3AEFE7F33CB68B99CEDAAFADFD181281BEBA2D
+:80048000AFABB9AAE38FFFA8B88B536EE8FEF88F8FFE7EEB145E744FC212B454F5E86ECFC7F6164A6D4AAFE4F47C2C2FE3F3222AAFA6F75416CF81D188A1557AF74A4A2F26B722B212F11434AFA2F322222F2809AD882952666D263F3151222F12F22A282F23D222F42A288B321E3A1E3A8D2AAD322FA1E3A8FAACAEAF2AFBD2FA1E1A8D1F
+:800500002AAF2BFBB29A2F89B1D8BDB8EBA3F5CAC88B998F2BFBBC79F031556841417E74AF85F51412E3F47234AD582E16A9B142F31E58AFC17118A8454B448FA6F672722B222B334F42F2283A2C9282248FA2A2226F63F326262F31012F22F2121827212F22B622B238E383F332383E32AB234FC2F3262C6CB2BAEA845F821E12AB1A9E33
+:80058000389E1AABDD8B9BDEB82BC88B9989F1FCD5144B428D243E348F85518C2F43E343F35812CF87F312443AF378628F85F75614EFA1D18CA1734B662F24F47E4A2B223E384F62F22C282B221A48F2A8282B226F63F326262FB24252212FA37312F22222AF22E282A333AB338B223E2A6F42F33E348D24BEAA2BDCA18B13BE1A2B318FFD
+:8006000029F9F2F8BE918BBD2F88EC8FEF2AFBE2D9800100220012200112002412444824C02400C024000018302230220010022901002008820020088022890220F8C7460012200100200200004048042B240016880100000085040012220012001800008200200A8001200A489FFB084D421F41522C1F41324C1F41364E1D64EB141D64FD
+:80068000AB9419B64A9945AF443924AF147924F84A9147822D914F82C4914FA2C4814FA264114FA264194FA26459ACE449C24A1F49C2421F4952281FC932481FC9324A1FC8B24AD1C1B24AD981B24A5985AF447924B84A7924B84A7924D84AF9244889F9244A7F390F4F22F411484F22741138441F8136661D486B141D682F46D9C1B44258
+:80070000FB1168AF4418F442B14783AF5439342D916D488DB56FA2C5914FA2FC18814D4A9E214D4A9E25BCE559C2481FC9C24A1F49C6421FC922F4912C421FC912F411684CF8114C4AFA15484EA447834A78A4B848A142AF44392689B926F5F9E7202888040000004004280000000021800188000040014008480000000000280000000082
+:8007800025018F270D000010452802000044004444282860822200000000002002326081424284480000860884840000100870840A42828008001008004800442230184C21020020048440020000422001002200C24608002001809448008E41844FE10442C22008000000E04244044141448CC314260220018A048400100100424E1830F1
+:800800001848422848201404A608848100428124818E4183F18162000000151488120800000028002260822800000024000028808201008100828304002001004800007FCE06400420022200000000000048000000002800000000000041000082210000000082008F1A012880020010392884210000004222442A0432440000412422009E
+:8008800080040028809128248142838102002C488888828C0400BF3D0F284128008052182608210000002062444A022A41040060423022000000800212C15082488CA182210088258808808408E03B03000028000084000000200400000000000000200400008002000000000022C20000BFC60200840000000000608100004400004800CE
+:8009000000420048800442280000001882800200800100008CF1C779002004002800004922020000800244001200004008002024044008001200C0641880820182001180F1AA1800000040080012008A440116081800002200000022420000004110020090480000804808204801F02FE20040080022002081024813018480C12440042223
+:8009800000002064820080240422400800008E4800182022981882200810F84498000000100800002018081800000020040000802404000044240080210120040018000000F01E9D00260400200400000000000068000020020022000000180042200400000048000000C8F0B6178004000000422220218402120042444400128084042238
+:800A000048480048181218800100008A0442A048000088428200F0254E000020110800008100000000002200808221220100000000000000A02100008004001842F095A8004800800483040000608284000000000000002004180000808101000080010000008088019F920E00000000000000000080614420042848800448000000004AF7
+:800A8000014818488004488004480048420018D0430B12220000006842484248002002684228200100000000004280010041000028002800C0848282C80082CEA9004824004180011800800541200100004800480028430200121A1484018001441004882800188800810020F25FCF202808008024243228000000280000800228000000B6
+:800B000000000080040000001212000000808428086F5407461812282101009044C0448042480820820410024A018820048061140084800418800100C024800244128200C01421F06D3D00A220012084A142481028040028184A62442E648004002A02420000001A0112181AA154184604C6044A2321044B14184328480880A8824F8C08C6
+:800B8000428A0600004A24A432A0454842508822A0421841A022184280A4412022A21420A11140045200124880041A0C828004428842884B8858F08598E021344485021A714884148862C4420018878243010048428081A4224A24042AA2454E2420248484A41118486041000028222A810480882884AC4C1A210DB75400008901819018D1
+:800C0000901880011880218221C2142A84A14220022252A0212001000000200442A084A084A084A08412804481044870840A7E722B22859A128F88F14C4C8F8424E483F3343C1AD588A1551AF11818CD3C3AA3317AF744244F47A3372AA2666A26A2373AA3336AF664344AA1445AA5555AF514141A014AF55414584D444A74C4A46A2AA7B9
+:800C8000DFC2CA7244A4DD4F44A4448D48CAFCC494DA29F52BD9E027F7622885BA42A1C445F448488F85E583D1C4F44C4C4AE547A7448CF22C3C3AA3226AF674744F63B772A5662B136AA6AA6A86AA335AF544141F14A1554E418F85A5114FC1A51148424F41A5444744424F48F4C444DAE94FAB48CAD444A4884F44048F88E82CFCD6D40E
+:800D0000DABDF2FF6667E027974224AF81A1114F44A4448F85A522CF42C24487814AA74485781CAC32A0665E542E6423A2772AA162C86AA2662AA6734F46E61584A4514E585AF514541AA1115AF11454704424D4444CA4BF5A830C4F49AD444F4CA4448D49CAFC96949AA9981FC3067E72A944F21A184A54CC8F84A4443AF13C148FC4A48D
+:800D8000454B745A7528F81C2C2AA3316AB644B67433423E324AA5622AAC66DAA773684F44E415A45119E485A511CF4121A1151AF15414484D44F044844CA4514BB94A28F4D4941AF144444AF44848CAFCD694DE12EADBA70722008440081E48228C048C04484008004820210400000000008001180000488024820448002008008242823F
+:800E00008FEC0B48000000000020040000B0140448000080011800008005180048000022800180040082208128E8130A4D421F4152281F4132481F41364A1D24AB141D24AB9419B24A19B54A3924AF1439242F147924D852F924481CF9244A1CF8244A16F1244A96E1A2E459C24A9E24ACF491242CF4912485F2912483F49124A3F4812463
+:800E8000AB141F48B24AB981B24A3985AB9443BA4A39242B94478229F92448984FA2F46183D084B51196421FC192161F8136421D2C6B141F81F24A841F41B24ABA15B24A28F34A8543F3428126D852F926482D914FA2C5914FA2EC1178246A194D4A8E21BCE558C25A1FC9D2A4B49156281F48B64CB181B24EB181B24EB181F24A141F49C2
+:800F0000B24AB385B24A217B4A24D24A392429F922482D944D5A9F290B848248000000000028000000211002188008000014008480040000004004280000000025012F9407000081C02800400800204228022200200200004820040000000000002028010080040000F074710082008008004100128004000020260120840100380048005A
+:800F80000080040000000000002002481C04EFDC0A200C40082200414120024A820222804222242101821800482A1101100842004800001084280300000024C041125FFF020000801808008180010081000022200248000080044800000000000000000048200248003FB90A22000000000080010000200100008002800118000000000096
+:801000000000820040084881828100F0A2190020020012221008000080020062200284800400220012200412000048200C008890814008003028F0BFAF00000080210281000000008081040081000012281220010012000048A08480088880088180081008AF5707288002000000001800200200222002006800000000480000000000000B
+:801080000015084281100822708306002008004902004100680000004A220112002002800490482004008004000028000000008820F1D987A0412004428004001004220010044A0200A04120010081004028A12400420020842188828208202404400118183F230700201812040000002001000020018002200242180020220420024212E3
+:801100004004420081200400100100BB4480044022044800000080050020064A230128202102422004802404802284240146048002002024040080016FFE0918000044C0240000000010040000200400283018008082810200200420A1840086084800002008F077930000000000002800440028200422000080020022000028008110080D
+:80118000000082000081000048F0C99110A4244120028081420448801188C444D048040081482095485200301800282200002001008428002200820048830242DE8F00000000000080021A0200000000001800485800488148000018000000000000208404008FC402224190248002002800808104444014041812444C0120210220850239
+:801200000000002001208422042882008004814840F8693710044100002800000044008004442004004280042004004200800400001008880000480010086F97072084042200200300001A0442004100000020040000420000000000840000000000004284FF4D064200408414844484942822414B24200410A8248C842442240400200404
+:80128000260800002014484848080088008048088493088A02F02BC420280A288222002002004008800210A421120000000020022200800400400800204408800400429442A7146082414841414110141484420428400C4C2402002382D448A1241A0842818305460140084800000040482CA82888420081488110023F4E08308430248857
+:8013000040240142892202C0148C344428C1430220120418802284B4181408422222000000818142B02828A84881488004194C88621446F8566C9024A61444E442E242024E244F423224222890148334444CA442CC82C448128966444822485A8464844256A826C0284800201438180081890280280881C04846B848B448CC4148BF2709DF
+:801380002E444A468412240480C124809424524F830410A4444654442AA71148C5A4448B15182280A17280044222A0448588C1180040688488808A0886384800228518F881F900002038442024210442400444400440A8248440088440080000000080042044A884200442844284889088802881F8D62DA0662A52444F42B264A6224AA43D
+:801400006745F444448D4848F05444CF45D5C4D4448452C48F8256888F83E181518885B428E281F168788F8222F458188D386A86A4224A8602F0484887811285A844F048488F8424A6488AAEC8428B48CA94498AA8BB9A099F9D064F46F6442C45F464244F44FC6464F034244A048D4C686E64448B554FC4D444C424CD444FC2F644462B8D
+:80148000321E18AFC415B8E8EF81F568E88F82028F81F529296AC6418B224AC66880F448481AF1181885A8448F84F42C2C8F8AEA44A2C88A8EA48C8B48CAA4CC8F28B83AE385F112185F72072A82564445C4244F46062AF314144554C842284F44F41C5489A4444F42C6688F86062B558B554E5845A8E68B116E682AD288F418186E292A7A
+:80150000A6222E282AA2620085A8115AA544A0CC8FCAFAA8A8284285A88C8394C88D488F98082B626AA2985D5E40944C44414F44D444024F46B714A1648528B44446F45C54C9E444F42464CB646E6CCFC4B472F518124F8444A8E78B11CE4850888F81E192A6621B222E282AB228024285A8118F85F548488F84F488888FCABAE8BE842820
+:80158000FCA888428B8C89AC44E088FCE2E86E2ACAF9C6B230240000484148224880044840084828002004874420048B24304820040000008081048A048E48A048000080344800D09C020041200200002200200400800480030080040000002200000000000000484200003048F0A52AC0421F4152281F4132481F41324A1D24AB141D24D6
+:80160000AB9419B24A19B54A3924AF1439242F147924D812F924481CFB244A1CF8244A16F1244A96E1A26459ACE449C24A1F49C2421F4952281F4932481F49324A1F48B24AD141B24A9921AB9451AB94478AAB9443BA4279A498924F8A84F9A44A3FD10DA41F41F628421741C3B411326A1741E394212F44D9C1B24A3B11AF442BF24A9502
+:8016800022AF545984ADB56782AD914FA2C5914DCA8F11FA245A96E1A264592E5B96E5A2F4912CACF4916485F2916483F4912CA3F4812C2B141D2CAF46D941B24A9B252B94478AAB14478AAB14439A126F8B943A4FAAD51E0D848248000000004400000000002180018800004001400848000000004480020000005012F0723F000000000B
+:80170000000000000000008D24800200000000004200000000200400820000802804F048C800A20000880000000000000000004200000000000000006084000000200442004001BF6F0AA02C00000000412002000000244C0232A048000010011028240400002004412002820000C082481412FDA100000080080000000000004008000020
+:801780000000000000000000812004000042200400008F870280020040010000000000000000800400000000001800000000000000000000F09D4500004120020000000000000028000000000000802402008800002002000020040010E83F028002448012010000000000002002004200000000808482010000000000000042000084DF74
+:801800003306000000000000000000000000000000000000000082000080020000000000F0EADC0000000000180000000000218002000000000000001800000000000012000000F0FB3500000000002210080000004200008004200200004002200200006081000000C048008081F87621000000000000002400000000000000410000000C
+:801880000000000000001288840020080089047FD804000000002003000000004602800280043024000000240038000000122021180818608800C05888DFAC0400000000004008100200000000000000000000000000001008000000420000F07F1A00000000810000000000000000000000000080020000000000000000000000BED60023
+:801900000000000000000000400200000000000000000000000000000000000000F0C66E000000000000000000001008000000000000000000000000000000000000F045FA000000000000000000002181000000000000000000000000000000000000004F280B000000000000000000000000000000000000000000000000000000000096
+:80198000F04FFE00000040080000000000002100000000000000000000000000810000000000F04E9800008100000000000000000000000080010010020000840000000000002A010000CFC1010000000000000000000000000000000000000000000000000000000000F04FFE000000000014000000000000000000000000000000000045
+:801A000000000000000000F084D3000000000000000000000000000000000000200100000000000000000000F04737000000000000000000000000004002000000000000000000000000000000F02E9E000000000000000000000000000000000000000000000000000000000000FFE40F0000000040010000000000000000001800002126
+:801A800020010084000000000000220000F0398B0000840084000000000000100200001002000000000000000000840000800100001F6A080000000000000000000000000000000000000000000000000000000000F04FFE0040010080045400004800001002400400218001882810021880088400008042080000280000F07DFF0040018E
+:801B0000008004548588022148400428100240042810828401882810828441848842188204441828842148E041012810A21140C43500000000000000000000440000000000000080020000880000008002000000004F11020014001480045448400448004800210044004421800188289082800188400800002884000080020000FF360C4F
+:801B80000000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0021000000000080022100448002000080028004000080044480022148400400214840040021CF9E0A00000000000000000000000000000000000000000000EA
+:801C000000000000000000F04FFE00000000000000000000000000000000000028008800000000002800000000C037000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000088000000000000000000008FD10300000000000000000000000000000000008002F9
+:3E1C80000000000000002800000000F057F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFB3
+:00000001FF
diff --git a/xpp/utils/FPGA_FXS.hex b/xpp/firmwares/FPGA_FXS.hex
index d3b6c8d..d3b6c8d 100644
--- a/xpp/utils/FPGA_FXS.hex
+++ b/xpp/firmwares/FPGA_FXS.hex
diff --git a/xpp/LICENSE.firmware b/xpp/firmwares/LICENSE.firmware
index b9bb89f..b9bb89f 100644
--- a/xpp/LICENSE.firmware
+++ b/xpp/firmwares/LICENSE.firmware
diff --git a/xpp/firmwares/README b/xpp/firmwares/README
new file mode 100644
index 0000000..e423aa6
--- /dev/null
+++ b/xpp/firmwares/README
@@ -0,0 +1,19 @@
+This distribution includes the firmware files required by the Xorcom[tm]
+Astribank[tm].
+
+This distribution inlcudes just the firmware files. Be sure to use a
+zaptel distribution/package of a matching version.
+
+INSTALLATION
+""""""""""""
+run "make install" as root. (which will simply copy all the *.hex files
+to /usr/share/zaptel )
+
+USAGE
+"""""
+When the firmware files are in place everything should work
+automagically. Consult the xpp documentation included in the package
+zaptel (or the debian package zaptel) that you use for further information.
+
+
+For further information contact support@xorcom.com http://xorcom.com
diff --git a/xpp/utils/USB_1130.hex b/xpp/firmwares/USB_1130.hex
index 5f97b5f..5f97b5f 100644
--- a/xpp/utils/USB_1130.hex
+++ b/xpp/firmwares/USB_1130.hex
diff --git a/xpp/firmwares/USB_1150.hex b/xpp/firmwares/USB_1150.hex
new file mode 100644
index 0000000..da0c541
--- /dev/null
+++ b/xpp/firmwares/USB_1150.hex
@@ -0,0 +1,308 @@
+#
+# $Id: USB_1150.hex 2135 2006-09-05 09:16:11Z oron $
+#
+:100E2800000102030405060708090A0B0C0D0E0F42
+:080E380041001000410011000F
+:1009B80090E600E054E74410F000000090E604746C
+:1009C80080F00000007406F0000000E4F000000071
+:1009D80090E6107420F000000090E611F00000008E
+:1009E80090E61274A2F000000090E61374A0F000E4
+:1009F800000090E61474E2F000000090E61574E040
+:100A0800F000000090E6047480F00000007404F028
+:100A1800000000E4F000000090E6497482F0000055
+:100A280000F000000090E6187410F000000090E656
+:100A38001A740CF000000090E619E054FEF0000073
+:100A48000090E61BE054FEF000000090E6917480F0
+:100A5800F0000000F000000090E695F0000000F0C3
+:070A680000000043AF012272
+:1005A10078007C007D017BFF7A0E79287E007F1028
+:1005B1001204FBC205E5AA30E2030206E2E5AA3015
+:1005C100E7030206E275310075320490F400E0247D
+:1005D100FE700302067524FA700302069124F87076
+:1005E100030206BA240F60030206BE90FC007401E8
+:1005F100F090F401E090FC01F090F402E090FC0234
+:10060100F0D2B690F401E0701AA3E0701630B01386
+:1006110074C0120D44C2B67F08120D4AD2B67F08CB
+:10062100120D4A30B04690E694E0FE90E695E07CEB
+:10063100002400FFEC3ECF24FCCF34FFFE7B017A87
+:10064100F47904120AFB501C90FC0330B4117408B5
+:10065100F07FE87E03120D4C7403120D44806A741E
+:1006610004F0806590FC037402F0805D90FC0374DB
+:1006710001F0805590FC007402F0E4A3F0A3F03087
+:10068100B406A37410F0804190FC037420F080390B
+:1006910075310075321190FC007408F07A007B000E
+:1006A1007D017F50120D9E7F50120BCC7AFC7B0195
+:1006B1007D107F50120D828010D202800C753100A6
+:1006C10075320190FC0074AAF0E53190E69CF000CF
+:1006D1000000E53290E69DF000000090E695748000
+:0106E100F028
+:0106E20022F5
+:0C0D440090E601F07F147E007D007C0032
+:100D50008F368E358D348C33783374FF120583ECE7
+:060D60004D4E4F70F3221E
+:0A0AFB008E338F348B358A3689372D
+:100B0500E4F538F539C3E5399534E538953350338F
+:100B1500AB35AA36A937853982853883120521FF79
+:100B2500E4FEC2B2EF1392B7EFC313FFD2B20EBE0B
+:100B350008F0C2B220B002C3220539E53970C605F6
+:040B45003880C2D35F
+:010B49002289
+:02004100D322C8
+:02004E00D322BB
+:02005000D322B9
+:080E460090E6BAE0F53BD3226F
+:1007EB0090E740E53BF0E490E68AF090E68B04F06E
+:0207FB00D32207
+:080E4E0090E6BAE0F53AD32268
+:100E160090E740E53AF0E490E68AF090E68B04F03D
+:020E2600D322D5
+:0207FD00D32205
+:0208FB00D32206
+:0208FD00D32204
+:100CF70090E6B9E0242F600D04701990E604E0FF38
+:100D0700430780800890E604E0FF53077F00000058
+:070D1700EFF08002D322C3BC
+:010D1E0022B2
+:100DBA00C0E0C083C082D2015391EF90E65D740116
+:080DCA00F0D082D083D0E032AA
+:100DEA00C0E0C083C0825391EF90E65D7404F0D0F6
+:060DFA0082D083D0E0323C
+:100E0000C0E0C083C0825391EF90E65D7402F0D0E1
+:060E100082D083D0E03225
+:100C0400C0E0C083C08285130F85141085108285CF
+:100C14000F83A37402F0850B11850C128512828553
+:100C24001183A37407F05391EF90E65D7410F0D034
+:060C340082D083D0E03203
+:100DD200C0E0C083C082D2045391EF90E65D7408F4
+:080DE200F0D082D083D0E03292
+:1008BE00C0E0C083C08290E680E030E720850B0F59
+:1008CE00850C10851082850F83A37402F085131199
+:1008DE00851412851282851183A37407F05391EF4C
+:0D08EE0090E65D7420F0D082D083D0E0321F
+:01003200329B
+:01004A003283
+:01005200327B
+:0107FF0032C7
+:0108FF0032C6
+:010E5E003261
+:010E5F003260
+:010E6000325F
+:010E6100325E
+:010E6200325D
+:010E6300325C
+:010E6400325B
+:010E6500325A
+:010E66003259
+:010E67003258
+:010E68003257
+:010E69003256
+:010E6A003255
+:010E6B003254
+:010E6C003253
+:010E6D003252
+:010E6E003251
+:010E6F003250
+:010E7000324F
+:010E7100324E
+:010E7200324D
+:010E7300324C
+:010E7400324B
+:010E7500324A
+:010E76003249
+:010E77003248
+:010E78003247
+:010E79003246
+:010E7A003245
+:100B9000C0E0C083C08290E6D1E0900010F090E603
+:100BA000D0E4F000000090E6D17402F000000053A1
+:100BB00091BF00000090E66104F000000090E6990B
+:0C0BC00004F075BB06D082D083D0E03278
+:010E7B003244
+:100D66001201000200000040E4E45211000001021A
+:0C0D760000010001020203030404050553
+:050E40000308FF0D6630
+:10028D00E4F52CF52BF52AF529C204C200C203C2F0
+:10029D0001C202D2B675B5C4D2B61209B8120E5645
+:1002AD007E087F008E0D8F0E751508751612750B55
+:1002BD0008750C1C75130875144A75170875187890
+:1002CD00EE54C07003020398752D00752E808E2F8D
+:1002DD008F30C374BC9FFF74089ECF2402CF3400AF
+:1002ED00FEE48F288E27F526F525F524F523F52236
+:1002FD00F521AF28AE27AD26AC25AB24AA23A92224
+:10030D00A821C31205705031AE23AF24E5302FF56F
+:10031D0082E52F3EF583E0FDE52E2FF582E52D3E9E
+:10032D00F583EDF0EF2401F524E43EF523E43522C9
+:10033D00F522E43521F52180B9852D0D852E0E741C
+:10034D00002480FF740834FFFEC3E5169FF516E503
+:10035D00159EF515C3E5109FF510E50F9EF50FC31E
+:10036D00E5129FF512E5119EF511C3E50C9FF50CF5
+:10037D00E50B9EF50BC3E5149FF514E5139EF513E0
+:10038D00C3E5189FF518E5179EF517D2E843D82059
+:10039D0090E668E0440BF090E65CE0443DF0000030
+:1003AD0000E4F5A2000000D2AF90E680E020E10568
+:1003BD00D20512000390E680E054F7F0538EF8C298
+:1003CD00041205A130022190E680E054FDF0E054C6
+:1003DD00F7F0750D0D750E66D20512000390E680CF
+:1003ED00E04402F0C204C202300105120056C201FF
+:1003FD003004CE12004150C9C204120D1F20001648
+:10040D0090E682E030E704E020E1EF90E682E03014
+:0E041D00E604E020E0E4120CA012004E80A3E2
+:0B00360090E50DE030E402C322D3226D
+:1000560090E6B9E0700302011514700302019224C0
+:10006600FE700302021524FB700302010F147003D5
+:100076000201091470030200FD1470030201032437
+:10008600056003020279120050400302028590E6E1
+:10009600BBE024FE602A14603B24FD601114602A34
+:1000A60024067050E50D90E6B3F0E50E803C120094
+:1000B60036503EE51590E6B3F0E516802D02027443
+:1000C600E50F90E6B3F0E5108020E51190E6B3F079
+:1000D600E512801690E6BAE0FF120CCCAA06A90734
+:1000E600EA49600DEE90E6B3F0EF90E6B4F0020256
+:1000F60085020274020274120E16020285120E4E58
+:10010600020285120E460202851207EB02028512D2
+:1001160007FD400302028590E6B8E0247F601514CF
+:10012600601924027063A200E43325E0FFA203E411
+:10013600334F8041E490E740F0803F90E6BCE054C6
+:100146007EFF7E00E0D394807C0040047D01800227
+:100156007D00EC4EFEED4F2478F582740D3EF5835E
+:10016600E493FF3395E0FEEF24A1FFEE34E68F82A1
+:10017600F583E0540190E740F0E4A3F090E68AF0BE
+:1001860090E68B7402F00202850202741208FB40AC
+:100196000302028590E6B8E024FE6016240260039E
+:1001A60002028590E6BAE0B40105C20002028502A9
+:1001B600027490E6BAE0705590E6BCE0547EFF7E8D
+:1001C60000E0D394807C0040047D0180027D00EC39
+:1001D6004EFEED4F2478F582740D3EF583E493FFD1
+:1001E6003395E0FEEF24A1FFEE34E68F82F583E03F
+:1001F60054FEF090E6BCE05480131313541FFFE046
+:10020600540F2F90E683F0E04420F08072805F1256
+:1002160008FD506B90E6B8E024FE60192402704E8B
+:1002260090E6BAE0B40104D200805490E6BAE064E5
+:1002360002604C803990E6BCE0547EFF7E00E0D33D
+:1002460094807C0040047D0180027D00EC4EFEED32
+:100256004F2478F582740D3EF583E493FF3395E0E1
+:10026600FEEF24A1FFEE34E68F82F583800D90E643
+:10027600A08008120CF7500790E6A0E04401F09029
+:06028600E6A0E04480F058
+:01028C00224F
+:0300330002004682
+:0400460053D8EF326A
+:100CA00090E682E030E004E020E60B90E682E0305F
+:100CB000E119E030E71590E680E04401F07F147E12
+:0C0CC00000120B4A90E680E054FEF02287
+:1000030030050990E680E0440AF0800790E680E03E
+:100013004408F07FDC7E05120B4A90E65D74FFF026
+:0F00230090E65FF05391EF90E680E054F7F02203
+:080E5600E4F51ED2E9D2AF223F
+:100BCC00AD0790E678E020E6F9C2E990E678E044DB
+:100BDC0080F0ED25E090E679F090E678E030E0F9F1
+:100BEC0090E678E04440F090E678E020E6F990E674
+:080BFC0078E030E1D6D2E922D5
+:100C6E00AC0790E678E020E6F9E51E702390E67872
+:100C7E00E04480F0EC25E090E679F08D19AF03A901
+:100C8E0007751A018A1B891CE4F51D751E01D322F6
+:020C9E00C3226F
+:100C3A00AC0790E678E020E6F9E51E702590E678A4
+:100C4A00E04480F0EC25E0440190E679F08D19AF9C
+:100C5A0003A907751A018A1B891CE4F51D751E0371
+:040C6A00D322C322AC
+:03004B000206E3C7
+:1006E300C0E0C083C082C085C084C086758600C058
+:1006F300D075D000C000C001C002C003C006C0074F
+:1007030090E678E030E206751E060207CD90E678A3
+:10071300E020E10CE51E64026006751E070207CDAA
+:10072300E51E24FE605F14603624FE70030207BEDC
+:1007330024FC70030207CA240860030207CDAB1A26
+:10074300AA1BA91CAF1D051D8F82758300120521ED
+:1007530090E679F0E51D65197070751E05806B9044
+:10076300E679E0AB1AAA1BA91CAE1D8E8275830025
+:1007730012054E751E02E5196401704E90E678E08D
+:100783004420F08045E51924FEB51D0790E678E086
+:100793004420F0E51914B51D0A90E678E04440F0D2
+:1007A300751E0090E679E0AB1AAA1BA91CAE1D8E3C
+:1007B3008275830012054E051D800F90E678E04494
+:1007C30040F0751E008003751E005391DFD007D0E3
+:1007D30006D003D002D001D000D0D0D086D084D0B0
+:0807E30085D082D083D0E03202
+:020CCC00A90776
+:100CCE00AE17AF188F828E83A3E064037017AD0149
+:100CDE0019ED7001228F828E83E07C002FFDEC3E99
+:080CEE00FEAF0580DFE4FEFF0C
+:010CF60022DB
+:100D8200120C3AE51E24FA600E146006240770F372
+:0C0D9200D322E4F51ED322E4F51ED32288
+:100D9E00120C6EE51E24FA600E146006240770F322
+:0C0DAE00D322E4F51ED322E4F51ED3226C
+:100D1F0090E682E044C0F090E681F0438701000046
+:040D2F00000000229E
+:100B4A008E318F3290E600E054187012E53224019B
+:100B5A00FFE43531C313F531EF13F532801590E612
+:100B6A0000E05418FFBF100BE53225E0F532E531FD
+:100B7A0033F531E5321532AE31700215314E60056A
+:060B8A00120D3380EE2283
+:100D33007400F58690FDA57C05A3E582458370F9D3
+:010D4300228D
+:100800001201000200000040E4E451110000010286
+:1008100000010A06000200000040010009022E004B
+:1008200001010080320904000004FF0000000705F8
+:10083000020200020007050402000200070586020A
+:100840000002000705880200020009022E000101D3
+:100850000080320904000004FF00000007050202C6
+:100860004000000705040240000007058602400022
+:10087000000705880240000004030904180358001B
+:100880006F00720063006F006D0020004C00740068
+:1008900064002E0028035800500044002800420045
+:1008A000610073006500640020006F006E0020008E
+:0E08B000410058005500500050002900000083
+:03004300020900AF
+:030053000209009F
+:10090000020DBA00020E0000020DEA00020DD20034
+:10091000020C04000208BE000200320002004A007D
+:10092000020052000207FF000208FF00020E5E00F4
+:10093000020E5F00020E6000020E6100020E6200F5
+:10094000020E630002004A00020E6400020E6500FF
+:10095000020E6600020E6700020E6800020E6900B9
+:10096000020E6A0002004A0002004A0002004A0029
+:10097000020E6B00020E6C00020E6D00020E6E0085
+:10098000020E6F00020E7000020E7100020E720065
+:10099000020E7300020E7400020E7500020E760045
+:1009A000020E7700020E7800020E7900020E7A0025
+:0809B000020B9000020E7B0017
+:03000000020A6F82
+:0C0A6F00787FE4F6D8FD75813B020AB6E2
+:10042B00E709F608DFFA8046E709F208DFFA803EB3
+:10043B0088828C83E709F0A3DFFA8032E309F608A0
+:10044B00DFFA8078E309F208DFFA807088828C8308
+:10045B00E309F0A3DFFA806489828A83E0A3F608BC
+:10046B00DFFA805889828A83E0A3F208DFFA804C96
+:10047B0080D280FA80C680D4806980F2803380106D
+:10048B0080A680EA809A80A880DA80E280CA8033D6
+:10049B0089828A83ECFAE493A3C8C582C8CCC5834E
+:1004AB00CCF0A3C8C582C8CCC583CCDFE9DEE7801E
+:1004BB000D89828A83E493A3F608DFF9ECFAA9F09D
+:1004CB00EDFB2289828A83ECFAE0A3C8C582C8CCF3
+:1004DB00C583CCF0A3C8C582C8CCC583CCDFEADE0C
+:1004EB00E880DB89828A83E493A3F208DFF980CC6E
+:1004FB0088F0EF60010E4E60C388F0ED2402B40467
+:10050B000050B9F582EB2402B4040050AF2323450D
+:06051B00822390047B73B3
+:10052100BB010CE58229F582E5833AF583E022508F
+:1005310006E92582F8E622BBFE06E92582F8E222D9
+:0D054100E58229F582E5833AF583E49322F3
+:10054E00F8BB010DE58229F582E5833AF583E8F0E3
+:10055E00225006E92582C8F622BBFE05E92582C88F
+:02056E00F22277
+:10057000EB9FF5F0EA9E42F0E99D42F0E89C45F0E1
+:010580002258
+:100581007401FF3395E0FEFDFC080808E6CF2FF665
+:1005910018E6CE3EF618E6CD3DF618E6CC3CF6223E
+:100A7B0002028DE493A3F8E493A34003F68001F202
+:100A8B0008DFF48029E493A3F85407240CC8C3337C
+:100A9B00C4540F4420C8834004F456800146F6DF4B
+:100AAB00E4800B0102040810204080900E38E47E95
+:100ABB00019360BCA3FF543F30E509541FFEE49340
+:100ACB00A360010ECF54C025E060A840B8E493A307
+:100ADB00FAE493A3F8E493A3C8C582C8CAC583CA32
+:100AEB00F0A3C8C582C8CAC583CADFE9DEE780BEEA
+:010E450000AC
+:00000001FF
diff --git a/xpp/init_card_3_23 b/xpp/init_card_3_23
new file mode 100755
index 0000000..07b059a
--- /dev/null
+++ b/xpp/init_card_3_23
@@ -0,0 +1,165 @@
+#! /bin/sh
+#
+# Written by Oron Peled <oron@actcom.co.il>
+# Copyright (C) 2006, Xorcom
+#
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# See the file LICENSE in the top level of this tarball.
+#
+
+#
+# $Id$
+#
+# Data format:
+# - A comment start with ';' or '#' until the end of line
+# - Blank lines are ignored
+# - Fields are whitespace separated (spaces or tabs)
+#
+# The fields are (in command line order):
+# 1. SLIC select in decimal (range 0-7).
+# 31 is a special value which means ALL SLICS (only some registers
+# accept settings for ALL SLICS).
+# 2. Command word:
+# - RD Read Direct register.
+# - RI Read Indirect register.
+# - WD Write Direct register.
+# - WI Write Indirect register.
+# 3. Register number in hexadecimal.
+# 4. Low data byte in hexadecimal. (for WD and WI commands).
+# 5. High data byte in hexadecimal. (for WI command only).
+#
+#
+
+# ----------------------------------==== 8-channel FXS unit initialization ===-----------------------------------------
+
+set -e
+
+me=`basename $0`
+INIT_DIR=`dirname $0`
+export XPP_BASE=/proc/xpp
+LOGGER="logger -s -t $me"
+
+exec 2> /tmp/results
+exec 1> "$XPP_BASE/$XPD_BUS/$XPD_NAME/slics"
+
+$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Calibrating '$0'"
+
+"$INIT_DIR/calibrate_slics"
+
+$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Continue '$0'"
+
+sed -e 's/[;#].*$//' -e '/^[ ]*$/d' <<END_OF_FILE
+
+# Change SLICs states to "Open state"s (Off,all transfers tristated to avoid data collision), Voltage sense
+31 WD 40 00
+
+# Flush out energy accumulators
+31 WI 58 00 00
+31 WI 59 00 00
+31 WI 5A 00 00
+31 WI 5B 00 00
+31 WI 5C 00 00
+31 WI 5D 00 00
+31 WI 5E 00 00
+31 WI 5F 00 00
+31 WI 61 00 00
+31 WI 58 00 00
+31 WI C1 00 00
+31 WI C2 00 00
+31 WI C3 00 00
+31 WI C4 00 00
+31 WI C5 00 00
+31 WI C6 00 00
+31 WI C7 00 00
+31 WI C8 00 00
+31 WI C9 00 00
+31 WI CA 00 00
+31 WI CB 00 00
+31 WI CC 00 00
+31 WI CD 00 00
+31 WI CE 00 00
+31 WI CF 00 00
+31 WI D0 00 00
+31 WI D1 00 00
+31 WI D2 00 00
+31 WI D3 00 00
+
+# Setting of SLICs offsets
+# New card initialization
+0 WD 02 00
+0 WD 04 00
+1 WD 02 08
+1 WD 04 08
+2 WD 02 10
+2 WD 04 10
+3 WD 02 18
+3 WD 04 18
+4 WD 02 20
+4 WD 04 20
+5 WD 02 28
+5 WD 04 28
+6 WD 02 30
+6 WD 04 30
+7 WD 02 38
+7 WD 04 38
+31 WD 03 00
+31 WD 05 00
+
+# Audio path. (also initialize 0A and 0B here if necessary)
+31 WD 08 00
+31 WD 09 00
+
+31 WD 17 00
+
+# Automatic/Manual Control: defaults - Cancel Power Alarm
+31 WD 43 1E
+
+# Loop Closure Debounce Interval
+31 WD 45 0A
+
+# Ring Detect Debounce Interval
+31 WD 46 0B
+
+# Battery Feed Control: Battery low (DCSW low)
+31 WD 42 00
+
+# Loop Current Limit
+31 WD 47 00
+
+31 WD 6C 01
+
+31 WI 23 00 80
+31 WI 24 20 03
+31 WI 25 8C 08
+31 WI 26 00 01
+31 WI 27 10 00
+
+
+# ------------------------------------- Initialization of direct registers --------------------------------------------
+
+# Mode(8-bit,u-Law,1 PCLK ) setting, Loopbacks and Interrupts clear
+
+31 WD 01 29
+#31 WD 0E 00
+
+#31 WD 15 00
+#31 WD 16 03
+
+# Clear pending interrupts
+31 WD 12 FF
+31 WD 13 FF
+31 WD 14 FF
+
+#31 WD 4A 34
+#31 WD 4B 10
+
+END_OF_FILE
+
+$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Ending '$0'"
+exit 0
diff --git a/xpp/init_card_4_23 b/xpp/init_card_4_23
new file mode 100755
index 0000000..a0e17bd
--- /dev/null
+++ b/xpp/init_card_4_23
@@ -0,0 +1,143 @@
+#! /bin/sh
+#
+# Written by Oron Peled <oron@actcom.co.il>
+# Copyright (C) 2006, Xorcom
+#
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# See the file LICENSE in the top level of this tarball.
+#
+
+#
+# $Id$
+#
+# Data format:
+# - A comment start with ';' or '#' until the end of line
+# - Blank lines are ignored
+# - Fields are whitespace separated (spaces or tabs)
+#
+# The fields are (in command line order):
+# 1. DAA select in decimal (range 0-7).
+# 31 is a special value which means ALL DAAs (only some registers
+# accept settings for ALL DAAs).
+# 2. Command word:
+# - RD Read Direct register.
+# - WD Write Direct register.
+# 3. Register number in hexadecimal.
+# 4. Data byte in hexadecimal. (for WD command).
+#
+
+# ----------------------------------==== 8-channel FXO unit initialization ===-----------------------------------------
+
+set -e
+
+opermode='FCC'
+
+me=`basename $0`
+INIT_DIR=`dirname $0`
+XPP_BASE=/proc/xpp
+export XPP_BASE
+SLICS="$XPP_BASE/$XPD_BUS/$XPD_NAME/slics"
+LOGGER="logger -s -t $me"
+
+# set -x
+exec 2> /tmp/results #FIXME: temporary debugging file
+# redirect script output to the "slics" (registers command) file:
+exec 1> $SLICS
+
+$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Initializing '$0'"
+
+set_daa_country_params() {
+ # based on fxo_modes from wctdm.c . TODO: more decent calculation?
+ reg16=00; reg26=00; reg30=00; reg31=A3; ring_osc=; ring_x=;
+ mode="$1"
+ # TODO: a saner fall-back in case of an unknown mode
+ if [ "$mode" = '' ]; then mode='FCC'; fi
+ if [ -r $INIT_DIR/init_fxo_modes ]; then
+ . $INIT_DIR/init_fxo_modes
+ fi
+ # Our register numbers are HEXADECIMAL!
+ cat <<EOF >$SLICS
+31 WD 10 $reg16
+31 WD 1A $reg26
+31 WD 1E $reg30
+31 WD 1F $reg31
+EOF
+ # for the FXS:
+ #if [ "$ring_osc" != '' ]; then
+ # /bin/echo "31 WI __ $ring_osc"
+ #fi
+ #if [ "$ring_x" != '' ]; then
+ # /bin/echo "31 WI __ $ring_x"
+ #fi
+}
+
+# Remove empty lines and commets. Not strictly necessary
+# but works around some limitations of the proc interface:
+sed -e 's/[;#].*$//' -e '/^[ ]*$/d' <<END_OF_FILE
+
+
+31 WD 21 28
+31 WD 18 99
+31 WD 06 00
+
+# ----------- DAA PCM start offset ----------
+
+0 WD 22 00
+0 WD 23 00
+0 WD 24 00
+0 WD 25 00
+
+1 WD 22 08
+1 WD 23 00
+1 WD 24 08
+1 WD 25 00
+
+2 WD 22 10
+2 WD 23 00
+2 WD 24 10
+2 WD 25 00
+
+3 WD 22 18
+3 WD 23 00
+3 WD 24 18
+3 WD 25 00
+
+4 WD 22 20
+4 WD 23 00
+4 WD 24 20
+4 WD 25 00
+
+5 WD 22 28
+5 WD 23 00
+5 WD 24 28
+5 WD 25 00
+
+6 WD 22 30
+6 WD 23 00
+6 WD 24 30
+6 WD 25 00
+
+7 WD 22 38
+7 WD 23 00
+7 WD 24 38
+7 WD 25 00
+
+# ----------- DAA ONHOOK --------------------
+31 WD 05 00
+
+# Set tip to ring voltage to 3.5 volts while off-hook
+# instead of default of 3.1
+31 WD 1A C0
+
+END_OF_FILE
+
+set_daa_country_params "$opermode"
+
+$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Ending '$0'"
+exit 0
diff --git a/xpp/init_data_3_19.cmd b/xpp/init_data_3_19.cmd
deleted file mode 100644
index 3f57660..0000000
--- a/xpp/init_data_3_19.cmd
+++ /dev/null
@@ -1,170 +0,0 @@
-#
-# Written by Oron Peled <oron@actcom.co.il>
-# Copyright (C) 2006, Xorcom
-#
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# See the file LICENSE in the top level of this tarball.
-#
-
-;
-; $Id$
-;
-; SLICS CMD Reg High Low
-
-; -------------------------------------- 8-channel FXS unit initialization
-; INTERNAL PS
-; Change SLICs states to "Open state"s (Off,all transfers tristated to avoid
-; data collision), Voltage sense
-
-FF 00 00 00 WD 40 00
-FF 00 00 00 WD 6C 01
-
-; ------------------------------------- Initialization of indirect registers
-
-FF 00 00 00 WI 00 55 C2
-FF 00 00 00 WI 01 51 E6
-FF 00 00 00 WI 02 4B 85
-FF 00 00 00 WI 03 49 37
-
-FF 00 00 00 WI 04 33 33
-FF 00 00 00 WI 05 02 02
-FF 00 00 00 WI 06 02 02
-FF 00 00 00 WI 07 01 98
-
-FF 00 00 00 WI 08 01 98
-FF 00 00 00 WI 09 06 11
-FF 00 00 00 WI 0A 02 02
-FF 00 00 00 WI 0B 00 E5
-
-FF 00 00 00 WI 0C 0A 1C
-FF 00 00 00 WI 0D 7B 30
-FF 00 00 00 WI 0E 00 63
-FF 00 00 00 WI 0F 00 00
-
-FF 00 00 00 WI 10 78 70
-FF 00 00 00 WI 11 00 7D
-FF 00 00 00 WI 12 00 00
-FF 00 00 00 WI 13 00 00
-
-FF 00 00 00 WI 14 7E F0
-FF 00 00 00 WI 15 01 60
-FF 00 00 00 WI 16 00 00
-FF 00 00 00 WI 17 20 00
-
-FF 00 00 00 WI 18 20 00
-FF 00 00 00 WI 19 00 00
-FF 00 00 00 WI 1A 40 00
-FF 00 00 00 WI 1B 40 00
-
-FF 00 00 00 WI 1C 18 00
-FF 00 00 00 WI 1D 40 00
-FF 00 00 00 WI 1E 10 00
-FF 00 00 00 WI 1F 00 80
-
-FF 00 00 00 WI 20 0F F4
-FF 00 00 00 WI 21 6E 7E
-FF 00 00 00 WI 22 0F F4
-FF 00 00 00 WI 23 88 00
-
-FF 00 00 00 WI 24 03 20
-FF 00 00 00 WI 25 00 12
-FF 00 00 00 WI 26 00 12
-FF 00 00 00 WI 27 00 12
-
-FF 00 00 00 WI 28 0C 00
-FF 00 00 00 WI 29 0C 00
-FF 00 00 00 WI 2B 08 00
-
-FF 00 00 00 WI 63 00 DA
-FF 00 00 00 WI 64 6B 60
-FF 00 00 00 WI 65 00 74
-FF 00 00 00 WI 66 79 C0
-
-FF 00 00 00 WI 67 11 20
-FF 00 00 00 WI 68 3B E0
-
-; ------------------------------------- Initialization of direct registers
-
-; Mode(8-bit,u-Law,1 PCLK ) setting, Loopbacks and Interrupts clear
-
-FF 00 00 00 WD 01 29
-FF 00 00 00 WD 08 00
-FF 00 00 00 WD 09 00
-FF 00 00 00 WD 0E 00
-
-FF 00 00 00 WD 15 00
-FF 00 00 00 WD 16 03
-FF 00 00 00 WD 17 00
-FF 00 00 00 WD 12 FF
-FF 00 00 00 WD 13 FF
-FF 00 00 00 WD 14 FF
-
-; Automatic/Manual Control: defaults - Cancel Power Alarm
-FF 00 00 00 WD 43 1E
-
-FF 00 00 00 WD 4A 31
-FF 00 00 00 WD 4B 10
-
-; Battery Feed Control: Battery low (DCSW low)
-FF 00 00 00 WD 42 00
-
-; Slic Calibration
-FF 00 00 00 WD 61 1F
-FF 00 00 00 WD 60 5F
-
-; Loop Closure Debounce Interval
-FF 00 00 00 WD 45 0A
-
-; Ring Detect Debounce Interval
-FF 00 00 00 WD 46 0B
-
-; Loop Current Limit
-FF 00 00 00 WD 47 07
-
-; Setting of SLICs offsets
-
-01 00 00 00 WD 02 01
-01 00 00 00 WD 03 00
-01 00 00 00 WD 04 01
-01 00 00 00 WD 05 00
-
-02 00 00 00 WD 02 09
-02 00 00 00 WD 03 00
-02 00 00 00 WD 04 09
-02 00 00 00 WD 05 00
-
-04 00 00 00 WD 02 11
-04 00 00 00 WD 03 00
-04 00 00 00 WD 04 11
-04 00 00 00 WD 05 00
-
-08 00 00 00 WD 02 19
-08 00 00 00 WD 03 00
-08 00 00 00 WD 04 19
-08 00 00 00 WD 05 00
-
-10 00 00 00 WD 02 21
-10 00 00 00 WD 03 00
-10 00 00 00 WD 04 21
-10 00 00 00 WD 05 00
-
-20 00 00 00 WD 02 29
-20 00 00 00 WD 03 00
-20 00 00 00 WD 04 29
-20 00 00 00 WD 05 00
-
-40 00 00 00 WD 02 31
-40 00 00 00 WD 03 00
-40 00 00 00 WD 04 31
-40 00 00 00 WD 05 00
-
-80 00 00 00 WD 02 39
-80 00 00 00 WD 03 00
-80 00 00 00 WD 04 39
-80 00 00 00 WD 05 00
diff --git a/xpp/init_data_3_20.cmd b/xpp/init_data_3_20.cmd
deleted file mode 100644
index 01d801d..0000000
--- a/xpp/init_data_3_20.cmd
+++ /dev/null
@@ -1,173 +0,0 @@
-#
-# Written by Oron Peled <oron@actcom.co.il>
-# Copyright (C) 2006, Xorcom
-#
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# See the file LICENSE in the top level of this tarball.
-#
-
-;
-; $Id$
-;
-; SLICS CMD Reg High Low
-
-; -------------------------------------- 8-channel FXS unit initialization
-; INTERNAL PS
-; Change SLICs states to "Open state"s (Off,all transfers tristated to avoid
-; data collision), Voltage sense
-
-FF 00 00 00 WD 40 00
-FF 00 00 00 WD 6C 01
-
-; ------------------------------------- Initialization of indirect registers
-
-FF 00 00 00 WI 00 55 C2
-FF 00 00 00 WI 01 51 E6
-FF 00 00 00 WI 02 4B 85
-FF 00 00 00 WI 03 49 37
-
-FF 00 00 00 WI 04 33 33
-FF 00 00 00 WI 05 02 02
-FF 00 00 00 WI 06 02 02
-FF 00 00 00 WI 07 01 98
-
-FF 00 00 00 WI 08 01 98
-FF 00 00 00 WI 09 06 11
-FF 00 00 00 WI 0A 02 02
-FF 00 00 00 WI 0B 00 E5
-
-FF 00 00 00 WI 0C 0A 1C
-FF 00 00 00 WI 0D 7B 30
-FF 00 00 00 WI 0E 00 63
-FF 00 00 00 WI 0F 00 00
-
-FF 00 00 00 WI 10 78 70
-FF 00 00 00 WI 11 00 7D
-FF 00 00 00 WI 12 00 00
-FF 00 00 00 WI 13 00 00
-
-FF 00 00 00 WI 14 7E F0
-FF 00 00 00 WI 15 01 60
-FF 00 00 00 WI 16 00 00
-FF 00 00 00 WI 17 20 00
-
-FF 00 00 00 WI 18 20 00
-FF 00 00 00 WI 19 00 00
-FF 00 00 00 WI 1A 40 00
-FF 00 00 00 WI 1B 40 00
-
-FF 00 00 00 WI 1C 18 00
-FF 00 00 00 WI 1D 40 00
-FF 00 00 00 WI 1E 10 00
-FF 00 00 00 WI 1F 00 80
-
-FF 00 00 00 WI 20 0F F4
-FF 00 00 00 WI 21 6E 7E
-FF 00 00 00 WI 22 0F F4
-FF 00 00 00 WI 23 88 00
-
-FF 00 00 00 WI 24 03 20
-FF 00 00 00 WI 25 00 12
-FF 00 00 00 WI 26 00 12
-FF 00 00 00 WI 27 00 12
-
-FF 00 00 00 WI 28 0C 00
-FF 00 00 00 WI 29 0C 00
-FF 00 00 00 WI 2B 08 00
-
-FF 00 00 00 WI 63 00 DA
-FF 00 00 00 WI 64 6B 60
-FF 00 00 00 WI 65 00 74
-FF 00 00 00 WI 66 79 C0
-
-FF 00 00 00 WI 67 11 20
-FF 00 00 00 WI 68 3B E0
-
-; ------------------------------------- Initialization of direct registers
-
-; Mode(8-bit,u-Law,1 PCLK ) setting, Loopbacks and Interrupts clear
-
-FF 00 00 00 WD 01 29
-FF 00 00 00 WD 08 00
-FF 00 00 00 WD 09 00
-FF 00 00 00 WD 0E 00
-
-FF 00 00 00 WD 15 00
-FF 00 00 00 WD 16 03
-FF 00 00 00 WD 17 00
-FF 00 00 00 WD 12 FF
-FF 00 00 00 WD 13 FF
-FF 00 00 00 WD 14 FF
-
-; Automatic/Manual Control:
-; Manual BATL/BATH select. NOTE: bit 08 switches VBAT to Low AND to High!
-FF 00 00 00 WD 43 16
-
-FF 00 00 00 WD 4A 31
-FF 00 00 00 WD 4B 10
-
-; Battery Feed Control: Battery low (DCSW low)
-FF 00 00 00 WD 42 00
-
-; Slic Calibration
-FF 00 00 00 WD 61 1F
-FF 00 00 00 WD 60 5F
-
-; Loop Closure Debounce Interval
-FF 00 00 00 WD 45 0A
-
-; Ring Detect Debounce Interval
-FF 00 00 00 WD 46 0B
-
-; Loop Current Limit
-; 23 milliampere for line current
-FF 00 00 00 WD 47 01
-
-; Setting of SLICs offsets
-
-# New card initialization
-01 00 00 00 WD 02 00
-01 00 00 00 WD 03 00
-01 00 00 00 WD 04 00
-01 00 00 00 WD 05 00
-
-02 00 00 00 WD 02 08
-02 00 00 00 WD 03 00
-02 00 00 00 WD 04 08
-02 00 00 00 WD 05 00
-
-04 00 00 00 WD 02 10
-04 00 00 00 WD 03 00
-04 00 00 00 WD 04 10
-04 00 00 00 WD 05 00
-
-08 00 00 00 WD 02 18
-08 00 00 00 WD 03 00
-08 00 00 00 WD 04 18
-08 00 00 00 WD 05 00
-
-10 00 00 00 WD 02 20
-10 00 00 00 WD 03 00
-10 00 00 00 WD 04 20
-10 00 00 00 WD 05 00
-
-20 00 00 00 WD 02 28
-20 00 00 00 WD 03 00
-20 00 00 00 WD 04 28
-20 00 00 00 WD 05 00
-
-40 00 00 00 WD 02 30
-40 00 00 00 WD 03 00
-40 00 00 00 WD 04 30
-40 00 00 00 WD 05 00
-
-80 00 00 00 WD 02 38
-80 00 00 00 WD 03 00
-80 00 00 00 WD 04 38
-80 00 00 00 WD 05 00
diff --git a/xpp/init_data_4_19.cmd b/xpp/init_data_4_19.cmd
deleted file mode 100644
index ba439a3..0000000
--- a/xpp/init_data_4_19.cmd
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Written by Oron Peled <oron@actcom.co.il>
-# Copyright (C) 2006, Xorcom
-#
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# See the file LICENSE in the top level of this tarball.
-#
-
-;
-; $Id$
-;
-; DAA's CMD Reg High Low
-
-; -------------------------------------- 8-channel FXO unit initialization
-
-FF FF 00 00 WD 21 28
-FF FF 00 00 WD 18 99
-FF FF 00 00 WD 06 00
-
-; ----------- DAA PCM start offset ----------
-
-01 00 00 00 WD 22 01
-01 00 00 00 WD 23 00
-01 00 00 00 WD 24 01
-01 00 00 00 WD 25 00
-
-02 00 00 00 WD 22 09
-02 00 00 00 WD 23 00
-02 00 00 00 WD 24 09
-02 00 00 00 WD 25 00
-
-04 00 00 00 WD 22 11
-04 00 00 00 WD 23 00
-04 00 00 00 WD 24 11
-04 00 00 00 WD 25 00
-
-08 00 00 00 WD 22 19
-08 00 00 00 WD 23 00
-08 00 00 00 WD 24 19
-08 00 00 00 WD 25 00
-
-10 00 00 00 WD 22 21
-10 00 00 00 WD 23 00
-10 00 00 00 WD 24 21
-10 00 00 00 WD 25 00
-
-20 00 00 00 WD 22 29
-20 00 00 00 WD 23 00
-20 00 00 00 WD 24 29
-20 00 00 00 WD 25 00
-
-40 00 00 00 WD 22 31
-40 00 00 00 WD 23 00
-40 00 00 00 WD 24 31
-40 00 00 00 WD 25 00
-
-80 00 00 00 WD 22 39
-80 00 00 00 WD 23 00
-80 00 00 00 WD 24 39
-80 00 00 00 WD 25 00
-
-; ----------- DAA ONHOOK --------------------
-FF FF 00 00 WD 05 00
diff --git a/xpp/init_data_4_20.cmd b/xpp/init_data_4_20.cmd
deleted file mode 100644
index 3f809c2..0000000
--- a/xpp/init_data_4_20.cmd
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-# Written by Oron Peled <oron@actcom.co.il>
-# Copyright (C) 2006, Xorcom
-#
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# See the file LICENSE in the top level of this tarball.
-#
-
-;
-; $Id$
-;
-; DAA's CMD Reg High Low
-
-; Start with a software reset:
-FF FF 00 00 WD 01 80
-
-; -------------------------------------- 8-channel FXO unit initialization
-
-FF FF 00 00 WD 21 28
-; 99 also sets ring validation
-;FF FF 00 00 WD 18 99
-FF FF 00 00 WD 06 00
-
-; ----------- DAA PCM start offset ----------
-
-FF FF 00 00 WD 23 00
-FF FF 00 00 WD 25 00
-
-01 00 00 00 WD 22 00
-01 00 00 00 WD 24 00
-
-02 00 00 00 WD 22 08
-02 00 00 00 WD 24 08
-
-04 00 00 00 WD 22 10
-04 00 00 00 WD 24 10
-
-08 00 00 00 WD 22 18
-08 00 00 00 WD 24 18
-
-10 00 00 00 WD 22 20
-10 00 00 00 WD 24 20
-
-20 00 00 00 WD 22 28
-20 00 00 00 WD 24 28
-
-40 00 00 00 WD 22 30
-40 00 00 00 WD 24 30
-
-80 00 00 00 WD 22 38
-80 00 00 00 WD 24 38
-
-; ----------- DAA ONHOOK --------------------
-FF FF 00 00 WD 05 08
-
-; Set tip to ring voltage to 3.5 volts while off-hook
-; instead of default of 3.1
-FF FF 00 00 WD 1A C0
diff --git a/xpp/initialize_registers b/xpp/initialize_registers
deleted file mode 100755
index 6c07e94..0000000
--- a/xpp/initialize_registers
+++ /dev/null
@@ -1,77 +0,0 @@
-#! /bin/sh
-#
-# $Id$
-#
-# This script is run from the xpp kernel module upon detection
-# of a new XPD.
-#
-# Expects the following environment variables to be set:
-# XPD_BUS - bus name
-# XPD_NAME - xpd name
-# XPD_TYPE - xpd type number (from protocol reply):
-# 3 - FXS
-# 4 - FXO
-# XPD_REVISION - xpd revision number
-
-set -e
-
-LOGGER="logger -i -t `basename $0`"
-opermode='FCC'
-INIT_DIR=`dirname $0`
-XPP_BASE=/proc/xpp
-
-if [ -r /etc/default/zaptel ]
-then . /etc/default/zaptel
-fi
-
-export XPP_BASE
-
-SLICS="$XPP_BASE/$XPD_BUS/$XPD_NAME/slics"
-FILE="$INIT_DIR/init_data_${XPD_TYPE}_${XPD_REVISION}.cmd"
-set_daa_country_params() {
- # based on fxo_modes from wctdm.c . TODO: more decent calculation?
- reg16=00; reg26=00; reg30=00; reg31=A3; ring_osc=; ring_x=;
- mode="$1"
- # TODO: a saner fall-back in case of an unknown mode
- if [ "$mode" = '' ]; then mode='FCC'; fi
- if [ -r $INIT_DIR/init_fxo_modes ]; then
- . $INIT_DIR/init_fxo_modes
- fi
- cat <<EOF >$SLICS
-FF FF 00 00 WD 10 $reg16
-FF FF 00 00 WD 1A $reg26
-FF FF 00 00 WD 1E $reg30
-FF FF 00 00 WD 1F $reg31
-EOF
- # for the FXS:
- #if [ "$ring_osc" != '' ]; then
- # /bin/echo "31 WI __ $ring_osc" >$SLICS
- #fi
- #if [ "$ring_x" != '' ]; then
- # /bin/echo "31 WI __ $ring_x" >$SLICS
- #fi
-}
-
-if [ ! -f "$SLICS" ]; then
- $LOGGER "missing register file '$SLICS'"
- exit 1
-fi
-
-if [ ! -f "$FILE" ]; then
- $LOGGER "missing register initialization file '$FILE'"
- exit 1
-fi
-
-case "$XPD_TYPE" in
-3|4)
- if [ "$XPD_TYPE" = 3 ]; then "$INIT_DIR/calibrate_slics"; fi
- cat "$FILE" > "$SLICS"
- if [ "$XPD_TYPE" = 4 ]; then set_daa_country_params "$opermode"; fi
- ;;
-*)
- $LOGGER "Unknown type '$XPD_TYPE'"
- exit 2
-esac
-$LOGGER "Wrote '$FILE' into '$SLICS'"
-
-exit 0
diff --git a/xpp/slic.c b/xpp/slic.c
deleted file mode 100644
index b019766..0000000
--- a/xpp/slic.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Written by Oron Peled <oron@actcom.co.il>
- * Copyright (C) 2004-2006, Xorcom
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "xproto.h"
-#include "slic.h"
-
-static const char rcsid[] = "$Id$";
-
-#ifdef __KERNEL__
-#include <linux/module.h>
-
-extern int print_dbg;
-#include "zap_debug.h"
-
-DEF_PARM(charp,initialize_registers, "/usr/share/zaptel/initialize_registers", "The script to initialize detected cards slics");
-
-#else
-#include <stdio.h>
-#endif
-
-int slic_cmd_direct_write(slic_cmd_t *sc, xpp_line_t lines, byte reg, byte data)
-{
- struct slic_reg_d *p = (struct slic_reg_d *)&sc->content;
-
- sc->lines = lines;
- sc->bytes = sizeof(struct slic_reg_d);
- SLIC_REG_INIT(p, 0, reg, data);
- return sizeof(xpp_line_t) + 1 + sc->bytes;
-}
-
-int slic_cmd_direct_read(slic_cmd_t *sc, xpp_line_t lines, byte reg)
-{
- struct slic_reg_d *p = (struct slic_reg_d *)&sc->content;
-
- sc->lines = lines;
- sc->bytes = sizeof(struct slic_reg_d);
- SLIC_REG_INIT(p, 1, reg, 0);
- return sizeof(xpp_line_t) + 1 + sc->bytes;
-}
-
-int slic_cmd_indirect_write(slic_cmd_t *sc, xpp_line_t lines, byte reg, byte data_low, byte data_high)
-{
- struct slic_reg_iw *p = (struct slic_reg_iw *)&sc->content;
-
- sc->lines = lines;
- sc->bytes = sizeof(struct slic_reg_iw);
- SLIC_REG_INIT(&p->iw_data_low, 0, 0x1C, data_low);
- SLIC_REG_INIT(&p->iw_data_high, 0, 0x1D, data_high);
- SLIC_REG_INIT(&p->iw_reg, 0, 0x1E, reg);
- return sizeof(xpp_line_t) + 1 + sc->bytes;
-}
-
-int slic_cmd_indirect_read(slic_cmd_t *sc, xpp_line_t lines, byte reg)
-{
- struct slic_reg_ir *p = (struct slic_reg_ir *)&sc->content;
-
- sc->lines = lines;
- sc->bytes = sizeof(struct slic_reg_ir);
- SLIC_REG_INIT(&p->ir_reg, 0, 0x1E, reg);
- return sizeof(xpp_line_t) + 1 + sc->bytes;
-}
-
-void dump_slic_cmd(const char msg[], slic_cmd_t *sc)
-{
- int i;
- struct slic_reg_d *sr;
- int last_data_low = -1;
- int last_data_high = -1;
-
- sr = (struct slic_reg_d *)&sc->content;
- if(sc->bytes > sizeof(sc->content)) {
- NOTICE("%s: Bug: sc->bytes = %d\n", __FUNCTION__, sc->bytes);
- return;
- }
- if(sc->bytes % 2) {
- NOTICE("%s: Bug: ODD sc->bytes = %d\n", __FUNCTION__, sc->bytes);
- return;
- }
- for(i = 0; i < sc->bytes/2; i++, sr++) {
- if(sr->reg_num == 0x1C) {
- last_data_low = sr->reg_data;
- continue;
- }
- if(sr->reg_num == 0x1D) {
- last_data_high = sr->reg_data;
- continue;
- }
- if(sr->reg_num == 0x1E) {
- if(last_data_low == -1 && last_data_high == -1) // Indirect Read
- DBG("%s: LINES=0x%08X bytes=%d INDIRECT READ: register=0x%02X\n", msg, sc->lines, sc->bytes, sr->reg_data);
- else if(last_data_low == -1 || last_data_high == -1) {
- NOTICE("%s: BUG: PARTIAL INDIRECT: register=%d last_data_low=0x%X last_data_high=0x%X\n",
- msg, sr->reg_data, last_data_low, last_data_high);
- } else
- DBG("%s: LINES=0x%08X bytes=%d INDIRECT WRITE: register=%d data_low=0x%02x data_high=0x%02X\n",
- msg, sc->lines, sc->bytes, sr->reg_data, (byte)last_data_low, (byte)last_data_high);
- last_data_low = last_data_high = -1;
- } else {
- DBG("%s: LINES=0x%08X bytes=%d DIRECT %s: register=%d data=0x%02X\n",
- msg, sc->lines, sc->bytes, (sr->read) ? "READ" : "WRITE", sr->reg_num, sr->reg_data);
- }
- }
-}
-
-#ifdef __KERNEL__
-
-#define MAX_ENV_STR 20
-
-int run_initialize_registers(xpd_t *xpd)
-{
- int ret;
- xbus_t *xbus;
- char busstr[MAX_ENV_STR];
- char xpdstr[MAX_ENV_STR];
- char typestr[MAX_ENV_STR];
- char revstr[MAX_ENV_STR];
- char *argv[] = {
- initialize_registers,
- NULL
- };
- char *envp[] = {
- busstr,
- xpdstr,
- typestr,
- revstr,
- NULL
- };
-
- BUG_ON(!xpd);
- xbus = xpd->xbus;
- if(!initialize_registers || !initialize_registers[0]) {
- NOTICE("%s/%s: No runtime register initialization\n", xbus->busname, xpd->xpdname);
- return 0;
- }
- DBG("%s/%s: running: '%s'\n", xbus->busname, xpd->xpdname, initialize_registers);
- snprintf(busstr, MAX_ENV_STR, "XPD_BUS=%s", xbus->busname);
- snprintf(xpdstr, MAX_ENV_STR, "XPD_NAME=%s", xpd->xpdname);
- snprintf(typestr, MAX_ENV_STR, "XPD_TYPE=%d", xpd->type);
- snprintf(revstr, MAX_ENV_STR, "XPD_REVISION=%d", xpd->revision);
- DBG("%s/%s: type=%d revision=%d\n", xbus->busname, xpd->xpdname, xpd->type, xpd->revision);
- ret = call_usermodehelper(initialize_registers, argv, envp, 1);
- if(ret != 0) {
- ERR("%s/%s: Failed running '%s' (errno %d, sig=%d)\n",
- xbus->busname, xpd->xpdname, initialize_registers,
- ((unsigned)ret >> 8) & 0xFF, ret & 0xFF);
- ret = -EFAULT;
- }
- return ret;
-}
-
-EXPORT_SYMBOL(slic_cmd_direct_write);
-EXPORT_SYMBOL(slic_cmd_direct_read);
-EXPORT_SYMBOL(slic_cmd_indirect_write);
-EXPORT_SYMBOL(slic_cmd_indirect_read);
-EXPORT_SYMBOL(dump_slic_cmd);
-
-#endif
diff --git a/xpp/slic.h b/xpp/slic.h
deleted file mode 100644
index ea49441..0000000
--- a/xpp/slic.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef SLIC_H
-#define SLIC_H
-/*
- * Written by Oron Peled <oron@actcom.co.il>
- * Copyright (C) 2004-2006, Xorcom
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "xdefs.h"
-
-/*------------------------------ SLIC Data Structures ----------------------*/
-
-struct slic_reg_d { /* SLIC Register Direct Read/Write */
- byte reg_num:7;
- byte read:1;
- byte reg_data;
-} __attribute__((packed));
-
-struct slic_reg_iw { /* SLIC Register Indirect-Write */
- struct slic_reg_d iw_data_low;
- struct slic_reg_d iw_data_high;
- struct slic_reg_d iw_reg;
-} __attribute__((packed));
-
-struct slic_reg_ir { /* SLIC Register Indirect-Read */
- struct slic_reg_d ir_reg;
-} __attribute__((packed));
-
-typedef struct slic_cmd {
- xpp_line_t lines;
- byte bytes;
- union {
- struct slic_reg_d direct;
- struct slic_reg_iw indirect_write;
- struct slic_reg_ir indirect_read;
- } content;
-} __attribute__((packed)) slic_cmd_t;
-
-typedef struct slic_reply {
- byte size;
- byte reg_num:7;
- byte indirect:1;
- byte data_low;
- byte data_high;
-} __attribute__((packed)) slic_reply_t;
-
-#define SLIC_REG_INIT(slic_reg, reading, num, data) \
- do { \
- (slic_reg)->read = reading; \
- (slic_reg)->reg_num = num; \
- (slic_reg)->reg_data = data; \
- } while(0);
-
-
-/*------------------------------ SLIC Initializers -------------------------*/
-
-int slic_cmd_direct_write(slic_cmd_t *sc, xpp_line_t lines, byte reg, byte data);
-int slic_cmd_direct_read(slic_cmd_t *sc, xpp_line_t lines, byte reg);
-int slic_cmd_indirect_write(slic_cmd_t *sc, xpp_line_t lines, byte reg, byte data_low, byte data_high);
-int slic_cmd_indirect_read(slic_cmd_t *sc, xpp_line_t lines, byte reg);
-void dump_slic_cmd(const char msg[], slic_cmd_t *sc);
-int run_initialize_registers(xpd_t *xpd);
-
-
-#endif /* SLIC_H */
diff --git a/xpp/utils/Makefile b/xpp/utils/Makefile
index b7d77f3..a278a80 100644
--- a/xpp/utils/Makefile
+++ b/xpp/utils/Makefile
@@ -1,33 +1,51 @@
PEDANTIC = -ansi -pedantic -std=c99
-CC = gcc
RANLIB = ranlib
-INSTALL = install
-INSTALL_DATA = install -m 644
-BINDIR = /usr/sbin
-DATADIR = /usr/share/zaptel
-MANDIR = /usr/share/man/man8
+TOPDIR ?= ../..
+
+-include $(TOPDIR)/makeopts
+
+INSTALL_DATA = $(INSTALL) -m 644
+
+SBINDIR = $(prefix)/sbin
+DATADIR = $(datadir)/zaptel
+MANDIR = $(mandir)/man8
HOTPLUG_USB_DIR = /etc/hotplug/usb
-DATA_FILES = $(wildcard ../init_data_*.cmd *.hex) init_fxo_modes
+XPD_FIRMWARE = $(wildcard ../firmwares/*.hex)
+XPD_INIT_DATA = $(XPD_FIRMWARE) init_fxo_modes
+XPD_INIT = $(wildcard ../init_card_?_*) ../calibrate_slics
+
+# Variables that should be defined above, but need sane defaults:
+# FIXME: Are those values really sane?
+HOSTCC ?= $(CC)
+PBX_LIBUSB ?= 1
+DRIVER_DIR ?= $(TOPDIR)
-WCTDM=../../wctdm.c
+WCTDM=$(DRIVER_DIR)/wctdm.c
CFLAGS = -g -Wall $(EXTRA_CFLAGS)
-TARGETS = libhexfile.a fpga_load test_parse init_fxo_modes
+TARGETS = init_fxo_modes print_modes adj_clock
+PROG_INSTALL = genzaptelconf adj_clock
+MAN_INSTALL = genzaptelconf.8 adj_clock.8
+ifeq ($(PBX_LIBUSB),1)
+TARGETS += libhexfile.a fpga_load test_parse
+PROG_INSTALL += fpga_load
+MAN_INSTALL += fpga_load.8
+endif
all: $(TARGETS)
install: all
$(INSTALL) -d $(DESTDIR)$(BINDIR)
- $(INSTALL) genzaptelconf fpga_load $(DESTDIR)$(BINDIR)/
+ $(INSTALL) $(PROG_INSTALL) $(DESTDIR)$(BINDIR)/
$(INSTALL) -d $(DESTDIR)$(DATADIR)
- $(INSTALL_DATA) $(DATA_FILES) $(DESTDIR)$(DATADIR)/
- $(INSTALL) ../initialize_registers ../calibrate_slics $(DESTDIR)$(DATADIR)/
+ $(INSTALL_DATA) $(XPD_INIT_DATA) $(DESTDIR)$(DATADIR)/
+ $(INSTALL) $(XPD_INIT) $(DESTDIR)$(DATADIR)/
$(INSTALL) -d $(DESTDIR)$(MANDIR)
- $(INSTALL_DATA) fpga_load.8 genzaptelconf.8 $(DESTDIR)$(MANDIR)/
+ $(INSTALL_DATA) $(MAN_INSTALL) $(DESTDIR)$(MANDIR)/
$(INSTALL) -d $(DESTDIR)$(HOTPLUG_USB_DIR)
$(INSTALL_DATA) xpp_fxloader.usermap $(DESTDIR)$(HOTPLUG_USB_DIR)/
$(INSTALL) xpp_fxloader $(DESTDIR)$(HOTPLUG_USB_DIR)/
@@ -40,16 +58,16 @@ fpga_load: fpga_load.o libhexfile.a
$(CC) -L. -o $@ $@.o $(EXTRA_LIBS) -lhexfile -lusb
hexfile.o: hexfile.c hexfile.h
- $(CC) $(CFLAGS) $(PEDANTIC) -c $*.c
+ $(CC) $(CFLAGS) $(PEDANTIC) -c $<
test_parse.o: test_parse.c hexfile.h
- $(CC) $(CFLAGS) $(PEDANTIC) -c $*.c
+ $(CC) $(CFLAGS) $(PEDANTIC) -c $<
test_parse: test_parse.o libhexfile.a
$(CC) -L. -o $@ $@.o $(EXTRA_LIBS) -lhexfile -lusb
print_modes.o: print_modes.c wctdm_fxomodes.h
- $(HOSTCC) $(CFLAGS) -c $^
+ $(HOSTCC) $(CFLAGS) -c $<
wctdm_fxomodes.h: $(WCTDM)
perl -n -e 'print if (/^static struct fxo_mode {$$/ .. /};$$/)' $(WCTDM) >$@
diff --git a/xpp/utils/USB_8613.hex b/xpp/utils/USB_8613.hex
deleted file mode 100644
index 424c072..0000000
--- a/xpp/utils/USB_8613.hex
+++ /dev/null
@@ -1,301 +0,0 @@
-:100E0700000102030405060708090A0B0C0D0E0F63
-:080E1700410010004100110030
-:1009B80090E600E054E74410F000000090E604746C
-:1009C80080F00000007406F0000000E4F000000071
-:1009D80090E6107420F000000090E611F00000008E
-:1009E80090E61274A2F000000090E61374A0F000E4
-:1009F800000090E61474E2F000000090E61574E040
-:100A0800F000000090E6047480F00000007404F028
-:100A1800000000E4F000000090E6497482F0000055
-:100A280000F000000090E6187410F000000090E656
-:100A38001A7408F090E6917480F0000000F000004D
-:100A48000090E695F0000000F000000043AF01229E
-:1005B30078007C007D017BFF7A0E79077E007F1037
-:1005C30012050DC204E5AA30E2030206E9E5AA30EA
-:1005D300E7030206E975310075320490F400E02464
-:1005E300FE700302068024FA700302069C2407604F
-:1005F300030206C590FC007401F090F401E090FC46
-:1006030001F090F402E090FC02F0D2B690F401E025
-:10061300701AA3E0701630B01374C0120D2DC2B659
-:100623007F08120D33D2B67F08120D3330B04690D7
-:10063300E694E0FE90E695E07C002400FFEC3ECFDC
-:1006430024FCCF34FFFE7B017AF47904120AE450D0
-:100653001C90FC0330B4117408F07FE87E03120D84
-:10066300357403120D2D80667404F0806190FC03D1
-:100673007402F0805990FC037401F0805190FC00E7
-:100683007402F0E4A3F0A3F030B406A37410F08076
-:100693003D90FC037420F080357531007532119064
-:1006A300FC007408F07A007B007D017F50120D6B13
-:1006B3007F50120BB57AFC7B017D107F50120D4FDA
-:1006C300800C75310075320190FC0074AAF0E5319D
-:1006D30090E69CF0000000E53290E69DF0000000FB
-:0606E30090E6957480F022
-:0106E90022EE
-:0C0D2D0090E601F07F147E007D007C0049
-:100D39008F368E358D348C33783374FF120595ECEC
-:060D49004D4E4F70F32235
-:0A0AE4008E338F348B358A36893744
-:100AEE00E4F538F539C3E5399534E53895335033A7
-:100AFE00AB35AA36A937853982853883120533FF7F
-:100B0E00E4FEC2B2EF1392B7EFC313FFD2B20EBE22
-:100B1E0008F0C2B220B002C3220539E53970C6050D
-:040B2E003880C2D376
-:010B320022A0
-:02004100D322C8
-:02004E00D322BB
-:02005000D322B9
-:080E200090E6BAE0F51DD322B3
-:100DE30090E740E51DF0E490E68AF090E68B04F08E
-:020DF300D32209
-:080E280090E6BAE0F51CD322AC
-:100DF50090E740E51CF0E490E68AF090E68B04F07D
-:020E0500D322F6
-:0207FC00D32206
-:0207FE00D32204
-:0208FB00D32206
-:100CE00090E6B9E0242F600D04701990E604E0FF4F
-:100CF000430780800890E604E0FF53077F00000070
-:070D0000EFF08002D322C3D3
-:010D070022C9
-:100D8700C0E0C083C082D2015391EF90E65D740149
-:080D9700F0D082D083D0E032DD
-:100DB700C0E0C083C0825391EF90E65D7404F0D029
-:060DC70082D083D0E0326F
-:100DCD00C0E0C083C0825391EF90E65D7402F0D015
-:060DDD0082D083D0E03259
-:100BED00C0E0C083C08285100C85110D850D8285F6
-:100BFD000C83A37402F085080E85090F850F82857D
-:100C0D000E83A37407F05391EF90E65D7410F0D04E
-:060C1D0082D083D0E0321A
-:100D9F00C0E0C083C082D2035391EF90E65D740828
-:080DAF00F0D082D083D0E032C5
-:1008BE00C0E0C083C08290E680E030E72085080C5F
-:1008CE0085090D850D82850C83A37402F085100EAB
-:1008DE0085110F850F82850E83A37407F05391EF58
-:0D08EE0090E65D7420F0D082D083D0E0321F
-:01003200329B
-:01004A003283
-:01005200327B
-:0108FD0032C8
-:0108FE0032C7
-:0108FF0032C6
-:010E38003287
-:010E39003286
-:010E3A003285
-:010E3B003284
-:010E3C003283
-:010E3D003282
-:010E3E003281
-:010E3F003280
-:010E4000327F
-:010E4100327E
-:010E4200327D
-:010E4300327C
-:010E4400327B
-:010E4500327A
-:010E46003279
-:010E47003278
-:010E48003277
-:010E49003276
-:010E4A003275
-:010E4B003274
-:010E4C003273
-:010E4D003272
-:010E4E003271
-:010E4F003270
-:010E5000326F
-:010E5100326E
-:010E5200326D
-:010E5300326C
-:100B7900C0E0C083C08290E6D1E0900010F090E61A
-:100B8900D0E4F000000090E6D17402F000000053B8
-:100B990091BF00000090E66104F000000090E69922
-:0C0BA90004F075BB06D082D083D0E0328F
-:010E5400326B
-:0A07F20000010202030304040505E0
-:10028D00E4F52CF52BF52AF529C203C200C202C2F2
-:10029D0001D2B675B5C4D2B61209B8120E307E08A9
-:1002AD007F008E0A8F0B751208751312750808756D
-:1002BD00091C75100875114A751408751578EE54DA
-:1002CD00C07003020396752D00752E808E2F8F3012
-:1002DD00C374BC9FFF74089ECF2402CF3400FEE48C
-:1002ED008F288E27F526F525F524F523F522F52102
-:1002FD00AF28AE27AD26AC25AB24AA23A922A82171
-:10030D00C31205825031AE23AF24E5302FF582E5BF
-:10031D002F3EF583E0FDE52E2FF582E52D3EF5838D
-:10032D00EDF0EF2401F524E43EF523E43522F5222A
-:10033D00E43521F52180B9852D0A852E0B74002415
-:10034D0080FF740834FFFEC3E5139FF513E5129E7D
-:10035D00F512C3E50D9FF50DE50C9EF50CC3E50FEC
-:10036D009FF50FE50E9EF50EC3E5099FF509E5080E
-:10037D009EF508C3E5119FF511E5109EF510C3E537
-:10038D00159FF515E5149EF514D2E843D82090E697
-:10039D0068E0440BF090E65CE0443DF0000000E4C2
-:1003AD00F5A2000000D2AFD20412000390E680E067
-:1003BD0054F7F0538EF8C20390E6C2E054FBF00000
-:1003CD00000000000090E619E054FEF000000090DF
-:1003DD00E61BE054FEF000000090E6187410F000EB
-:1003ED00000090E61A740CF0000000000000000000
-:1003FD000090E6017403F01205B3300105120056AA
-:10040D00C2013003F212004150EDC203120D08205B
-:10041D00001690E682E030E704E020E1EF90E682FE
-:10042D00E030E604E020E0E4120C8912004E80C7B3
-:0B00360090E50DE030E402C322D3226D
-:1000560090E6B9E0700302011514700302019224C0
-:10006600FE700302021524FB700302010F147003D5
-:100076000201091470030200FD1470030201032437
-:10008600056003020279120050400302028590E6E1
-:10009600BBE024FE602A14603B24FD601114602A34
-:1000A60024067050E50A90E6B3F0E50B803C12009A
-:1000B60036503EE51290E6B3F0E513802D02027449
-:1000C600E50C90E6B3F0E50D8020E50E90E6B3F082
-:1000D600E50F801690E6BAE0FF120CB5AA06A9074E
-:1000E600EA49600DEE90E6B3F0EF90E6B4F0020256
-:1000F60085020274020274120DF5020285120E28A0
-:10010600020285120E20020285120DE302028512FA
-:1001160007FC400302028590E6B8E0247F601514D0
-:10012600601924027063A200E43325E0FFA202E412
-:10013600334F8041E490E740F0803F90E6BCE054C6
-:100146007EFF7E00E0D394807C0040047D01800227
-:100156007D00EC4EFEED4F24F2F58274073EF583EA
-:10016600E493FF3395E0FEEF24A1FFEE34E68F82A1
-:10017600F583E0540190E740F0E4A3F090E68AF0BE
-:1001860090E68B7402F00202850202741207FE40AA
-:100196000302028590E6B8E024FE6016240260039E
-:1001A60002028590E6BAE0B40105C20002028502A9
-:1001B600027490E6BAE0705590E6BCE0547EFF7E8D
-:1001C60000E0D394807C0040047D0180027D00EC39
-:1001D6004EFEED4F24F2F58274073EF583E493FF5D
-:1001E6003395E0FEEF24A1FFEE34E68F82F583E03F
-:1001F60054FEF090E6BCE05480131313541FFFE046
-:10020600540F2F90E683F0E04420F08072805F1256
-:1002160008FB506B90E6B8E024FE60192402704E8D
-:1002260090E6BAE0B40104D200805490E6BAE064E5
-:1002360002604C803990E6BCE0547EFF7E00E0D33D
-:1002460094807C0040047D0180027D00EC4EFEED32
-:100256004F24F2F58274073EF583E493FF3395E06D
-:10026600FEEF24A1FFEE34E68F82F583800D90E643
-:10027600A08008120CE0500790E6A0E04401F09040
-:06028600E6A0E04480F058
-:01028C00224F
-:0300330002004682
-:0400460053D8EF326A
-:100C890090E682E030E004E020E60B90E682E03076
-:100C9900E119E030E71590E680E04401F07F147E29
-:0C0CA90000120B3390E680E054FEF022B5
-:1000030030040990E680E0440AF0800790E680E03F
-:100013004408F07FDC7E05120B3390E65D74FFF03D
-:0F00230090E65FF05391EF90E680E054F7F02203
-:080E3000E4F51BD2E9D2AF2268
-:100BB500AD0790E678E020E6F9C2E990E678E044F2
-:100BC50080F0ED25E090E679F090E678E030E0F908
-:100BD50090E678E04440F090E678E020E6F990E68B
-:080BE50078E030E1D6D2E922EC
-:100C5700AC0790E678E020E6F9E51B702390E6788C
-:100C6700E04480F0EC25E090E679F08D16AF03A91B
-:100C7700077517018A188919E4F51A751B01D3221C
-:020C8700C32286
-:100C2300AC0790E678E020E6F9E51B702590E678BE
-:100C3300E04480F0EC25E0440190E679F08D16AFB6
-:100C430003A9077517018A188919E4F51A751B0397
-:040C5300D322C322C3
-:03004B000206EAC0
-:1006EA00C0E0C083C082C085C084C086758600C051
-:1006FA00D075D000C000C001C002C003C006C00748
-:10070A0090E678E030E206751B060207D490E67898
-:10071A00E020E10CE51B64026006751B070207D4A2
-:10072A00E51B24FE605F14603624FE70030207C5D1
-:10073A0024FC70030207D1240860030207D4AB1714
-:10074A00AA18A919AF1A051A8F82758300120533E0
-:10075A0090E679F0E51A65167070751B05806B9046
-:10076A00E679E0AB17AA18A919AE1A8E827583002A
-:10077A00120560751B02E5166401704E90E678E07A
-:10078A004420F08045E51624FEB51A0790E678E085
-:10079A004420F0E51614B51A0A90E678E04440F0D1
-:1007AA00751B0090E679E0AB17AA18A919AE1A8E44
-:1007BA0082758300120560051A800F90E678E0447E
-:1007CA0040F0751B008003751B005391DFD007D0E2
-:1007DA0006D003D002D001D000D0D0D086D084D0A9
-:0807EA0085D082D083D0E032FB
-:020CB500A9078D
-:100CB700AE14AF158F828E83A3E064037017AD0166
-:100CC70019ED7001228F828E83E07C002FFDEC3EB0
-:080CD700FEAF0580DFE4FEFF23
-:010CDF0022F2
-:100D4F00120C23E51B24FA600E146006240770F3BF
-:0C0D5F00D322E4F51BD322E4F51BD322C1
-:100D6B00120C57E51B24FA600E146006240770F36F
-:0C0D7B00D322E4F51BD322E4F51BD322A5
-:100D080090E682E044C0F090E681F043870100005D
-:040D180000000022B5
-:100B33008E318F3290E600E054187012E5322401B2
-:100B4300FFE43531C313F531EF13F532801590E629
-:100B530000E05418FFBF100BE53225E0F532E53114
-:100B630033F531E5321532AE31700215314E600581
-:060B7300120D1C80EE22B1
-:100D1C007400F58690FDA57C05A3E582458370F9EA
-:010D2C0022A4
-:03004300020900AF
-:030053000209009F
-:10090000020D8700020DCD00020DB700020D9F0001
-:10091000020BED000208BE000200320002004A0095
-:10092000020052000208FD000208FE000208FF005B
-:10093000020E3800020E3900020E3A00020E3B0091
-:10094000020E3C0002004A00020E3D00020E3E0074
-:10095000020E3F00020E4000020E4100020E420055
-:10096000020E430002004A0002004A0002004A0050
-:10097000020E4400020E4500020E4600020E470021
-:10098000020E4800020E4900020E4A00020E4B0001
-:10099000020E4C00020E4D00020E4E00020E4F00E1
-:1009A000020E5000020E5100020E5200020E5300C1
-:0809B000020B7900020E540055
-:100800001201000200000040E4E411220000010295
-:1008100000010A06000200000040010009022E004B
-:1008200001010080320904000004FF0000000705F8
-:10083000020200020007050402000200070586020A
-:100840000002000705880200020009022E000101D3
-:100850000080320904000004FF00000007050202C6
-:100860004000000705040240000007058602400022
-:10087000000705880240000004030904180358001B
-:100880006F00720063006F006D0020004C00740068
-:1008900064002E0028035800500044002800420045
-:1008A000610073006500640020006F006E0020008E
-:0E08B000410058005500500050002900000083
-:03000000020A5899
-:0C0A5800787FE4F6D8FD758139020A9F12
-:10043D00E709F608DFFA8046E709F208DFFA803EA1
-:10044D0088828C83E709F0A3DFFA8032E309F6088E
-:10045D00DFFA8078E309F208DFFA807088828C83F6
-:10046D00E309F0A3DFFA806489828A83E0A3F608AA
-:10047D00DFFA805889828A83E0A3F208DFFA804C84
-:10048D0080D280FA80C680D4806980F2803380105B
-:10049D0080A680EA809A80A880DA80E280CA8033C4
-:1004AD0089828A83ECFAE493A3C8C582C8CCC5833C
-:1004BD00CCF0A3C8C582C8CCC583CCDFE9DEE7800C
-:1004CD000D89828A83E493A3F608DFF9ECFAA9F08B
-:1004DD00EDFB2289828A83ECFAE0A3C8C582C8CCE1
-:1004ED00C583CCF0A3C8C582C8CCC583CCDFEADEFA
-:1004FD00E880DB89828A83E493A3F208DFF980CC5C
-:10050D0088F0EF60010E4E60C388F0ED2402B40454
-:10051D000050B9F582EB2402B4040050AF232345FB
-:06052D00822390048D738F
-:10053300BB010CE58229F582E5833AF583E022507D
-:1005430006E92582F8E622BBFE06E92582F8E222C7
-:0D055300E58229F582E5833AF583E49322E1
-:10056000F8BB010DE58229F582E5833AF583E8F0D1
-:10057000225006E92582C8F622BBFE05E92582C87D
-:02058000F22265
-:10058200EB9FF5F0EA9E42F0E99D42F0E89C45F0CF
-:010592002246
-:100593007401FF3395E0FEFDFC080808E6CF2FF653
-:1005A30018E6CE3EF618E6CD3DF618E6CC3CF6222C
-:100A640002028DE493A3F8E493A34003F68001F219
-:100A740008DFF48029E493A3F85407240CC8C33393
-:100A8400C4540F4420C8834004F456800146F6DF62
-:100A9400E4800B0102040810204080900E17E47ECD
-:100AA400019360BCA3FF543F30E509541FFEE49357
-:100AB400A360010ECF54C025E060A840B8E493A31E
-:100AC400FAE493A3F8E493A3C8C582C8CAC583CA49
-:100AD400F0A3C8C582C8CAC583CADFE9DEE780BE01
-:010E1F0000D2
-:00000001FF
diff --git a/xpp/utils/adj_clock.8 b/xpp/utils/adj_clock.8
new file mode 100644
index 0000000..0e9cf71
--- /dev/null
+++ b/xpp/utils/adj_clock.8
@@ -0,0 +1,144 @@
+." $Id:$
+.TH adj_clock 8 "2006-10-18"
+.SH "NAME"
+adj_clock \(em Synchronize system clock to zaptel clock
+.SH "SYNOPSIS"
+.B adj_clock
+.I [ -c
+.B count
+.I ] [ -i
+.B interval
+.I ] [ -t
+.B period
+.I ] [ -v ]
+
+.SH "DESCRIPTION"
+.B adj_clock
+compares synchronizes the system clock from Zaptel's clock: in each cycle
+It will read 1024 *
+.B interval
+ticks from a Zaptel pseudo channel, which should take exactly
+.B interval
+seconds. It measures the time it did take, and uses
+.I adjtimex(3)
+to fix the system clock accordingly.
+
+Note that NTP servers usually use adjtimex. You may get strange behaviour
+if you have a NTP server (such as ntpd(8)) running on the system.
+
+Output is sent to both the standard error and to the syslog. Syslog
+messages are with facility daemon.
+
+.SH OPTIONS
+.I -c
+.B count
+.RS
+Run just
+.B count
+synchronization cycles. Default is to run forever.
+.RE
+
+.I -i
+.B interval
+.RS
+Loop interval (in seconds). Optional, as program should provide a sane value.
+
+Small values allow faster synchronization when the system is quiet. Even
+a value as low as 10 should work. However they are much more suspectable
+to short interruptions.
+
+.RE
+
+.I -t
+.B period
+.RS
+Set the synchronization tolerance priod (micro-seconds). The default
+is 100. Don't touch it unless you know what you're doing.
+.RE
+
+.I -v
+.RS
+Be more verbose: log status messages even when synchronized.
+.RE
+
+.SH FILES
+.B /dev/zap/pseudo
+.RS
+.RE
+The device file used to open a "pseudo" channel (a channels that
+constantly streams voice and is synchronized by the master Zaptel
+device).
+
+.SH SYNCHRONIZATION
+Some more technical details. This explains the strange numbers the
+program prints.
+
+In each cycle
+.B adj_clock
+measures
+.B interval
+seconds using Zaptel ticks. It then compares that to the system time
+from gettimeofday(2). It then calls adjtimex(2) to slightly change the
+rate of the system clock. It uses two parameters:
+.B ticks,
+which is a more
+coarse one (1 tick will give roughly a change of rate of 9 seconds per
+day) and
+.I frequency,
+which allows much finer settings.
+
+The program tries to set what it can by ticks, and the rest through
+frequency. It considers itself "synchronized" when the rate difference
+is small enough so
+.I (a)
+It does not have to use ticks anymore. And
+.I (b)
+The rest of the interval to change is smaller than the tolerance period
+(100 micro-seconds, by default).
+
+The meaning of the parameters it prints is, thus:
+
+.I interval
+.RS
+The current interval parameter (seconds).
+.RE
+
+.I diff_tick
+.RS
+The number of ticks it tries to set through adjtimex(2).
+Anything different than 0 means we're still way off mark.
+.RE
+
+.I diff_usec
+.RS
+The time difference (micro-seconds) that we need to overcome in the
+first place. This is the difference between the system clock and the
+measured zaptel clock.
+.RE
+
+.I usec_left
+.RS
+How much of this difference (microseconds) we still need to adjust
+after using ticks. This should be low enough (less than the tolerance
+period).
+.RE
+
+.SH SIGNALS
+.B adj_clock
+is so far an interactive program, and thus killed by SIGHUP. SIGUSR is
+used to increase verbosity level and SIGUSR2 is used to reset verbosity
+level to 0. When SIGUSR1 is recieved a status message will also be sent
+to the logs.
+
+.SH SEE ALSO
+ztcfg(8), zttest(8), adjtimex(2), gettimeofday(2), adjtimex(8)
+
+.SH AUTHOR
+
+This manual page was written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
+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.
+
+On Debian systems, the complete text of the GNU General Public
+License can be found in /usr/share/common-licenses/GPL.
diff --git a/xpp/utils/adj_clock.c b/xpp/utils/adj_clock.c
new file mode 100644
index 0000000..6dfa483
--- /dev/null
+++ b/xpp/utils/adj_clock.c
@@ -0,0 +1,228 @@
+/*
+ * Written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
+ * Copyright (C) 2006, Xorcom
+ *
+ * Derived from zttest.c
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <sys/timex.h>
+#include <linux/param.h>
+#include <syslog.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <math.h>
+
+static const char *rcsid = "$Id$";
+
+#define FREQ_PER_TICK (64*1024)
+#define USEC_PER_ZAP_TICK 1000 /* Zaptel tick in usec */
+#define USER_HZ 100
+#define SYNC_TOLERANCE 100
+#define DEFAULT_INTERVAL 60
+
+static const char *program;
+static int synced_time; /* time (seconds) we are so far synced */
+static int verbose = 0;
+static int sync_tolerance = 100;
+
+void usage() {
+ fprintf(stderr, "%s: synchronize system clock from zaptel clock.\n"
+ "Version: %s\n"
+ "\n"
+ "Usage: %s [ -c COUNT ] [-i INTERVAL] [ -t PERIOD ] [-v]\n"
+ " %s -h\n"
+ "\n"
+ "Options:\n"
+ " -c only run COUNT cycles of synchronization (default: forever).\n"
+ " -i set cycle Interval to INTERVAL (in seconds. Default: %d).\n"
+ " -t sync tolerance to PERIOD (in usec. Default: %d). For debugging.\n"
+ " -v Be more Verbose\n"
+ " -h Print this Help text and exit.\n"
+ "", program, rcsid, program, program, DEFAULT_INTERVAL,
+ sync_tolerance);
+}
+
+/* based on zttest.c */
+
+/*
+ * Print a message to the log according to the value of synced_time
+ *
+ * All parameters are for the "Not Synced" warning message.
+ * TODO: Find a better way.
+ */
+void status_message(void) {
+ if (synced_time == 0)
+ syslog(LOG_NOTICE, "Not Synced.\n");
+ else
+ syslog(LOG_INFO, "Good Sync for %d seconds\n", synced_time);
+
+ return;
+}
+
+/*
+ * interval: period, in seconds
+ * diff_usec: Current offset, in micro-seconds.
+ */
+int clock_sync(int interval, int diff_usec)
+{
+ struct timex cur_time = {.modes=0}; /* just query */
+ int diff_tick; /* Difference in adjtimex ticks */
+ int req_tick; /* Required adjtimex tick value */
+ long long diff_freq;
+ long long req_freq;
+ int usec_left; /* Usec adjusted by frequency */
+ int ret;
+
+ ret = adjtimex(&cur_time);
+
+ diff_tick = diff_usec / (interval * USER_HZ);
+ usec_left = diff_usec - diff_tick * (interval * USER_HZ);
+ diff_freq = usec_left * FREQ_PER_TICK / interval;
+
+ req_tick = cur_time.tick - diff_tick;
+ req_freq = cur_time.freq - diff_freq;
+
+ if(!diff_tick && abs(usec_left) < sync_tolerance)
+ synced_time += interval;
+ else
+ synced_time = 0;
+ status_message();
+ if (verbose || !synced_time)
+ syslog(LOG_INFO, "interval: %d, diff_tick: %d, diff_usec: %d, usec_left: %d.\n",
+ interval, diff_tick, diff_usec, usec_left);
+
+ /* set the clock rate */
+ cur_time.freq = req_freq;
+ cur_time.tick = req_tick;
+ cur_time.modes = ADJ_TICK | ADJ_FREQUENCY;
+ ret = adjtimex(&cur_time);
+ if (ret < 0)
+ syslog(LOG_ERR, "Adjtimex failed to set frequency. New frequency: %lld. Error: %d (%s)\n",
+ req_freq, errno, strerror(errno));
+ return 0;
+}
+
+static int pass = 0;
+
+void hup_handler(int sig)
+{
+ if (verbose > 0) {
+ syslog(LOG_INFO, "--- Results after %d passes ---\n", pass);
+ status_message();
+ }
+ closelog();
+ exit(0);
+}
+
+void sigusr1_handler(int sig) {
+ verbose++;
+ syslog(LOG_INFO, "Increased verbosity to %d (increase: SIGUSR1, reset: SIGUSR2).\n", verbose);
+ status_message();
+}
+
+void sigusr2_handler(int sig) {
+ verbose = 0;
+ syslog(LOG_INFO, "Set verbosity to 0 (increase: SIGUSR1, reset: SIGUSR2).\n");
+}
+
+void sync_cycle(int fd, int interval)
+{
+ char buf[1024]; /* TODO: why 1024 and not 1000? */
+ struct timeval start;
+ struct timeval end;
+ long long usec;
+ int count = 0;
+ int i;
+ int res;
+
+ gettimeofday(&start, NULL);
+ for (i=0; i < interval*8; i++) {
+ res = read(fd, buf, sizeof(buf));
+ if (res < 0) {
+ syslog(LOG_ERR, "Failed to read from pseudo interface: %s\n", strerror(errno));
+ exit(1);
+ }
+ count += res/8;
+ }
+ gettimeofday(&end, NULL);
+
+ /* time difference in microseconds: */
+ usec = (end.tv_sec - start.tv_sec) * 1000000;
+ usec += end.tv_usec - start.tv_usec;
+
+ clock_sync(interval, usec - (count * USEC_PER_ZAP_TICK));
+
+ pass++;
+}
+
+int main(int argc, char *argv[])
+{
+ int fd;
+ int opt;
+ int interval = DEFAULT_INTERVAL;
+ int cycles_to_run = 0;
+ int i;
+
+ program = argv[0];
+ while((opt = getopt(argc, argv, "c:hi:t:v")) != -1) {
+ switch (opt) {
+ case 'h': usage(); exit(0); break;
+ case 'c': cycles_to_run = atoi(optarg); break;
+ case 'i': interval = atoi(optarg); break; /* number of seconds */
+ case 't': sync_tolerance = atoi(optarg); break; /* usec */
+ case 'v': verbose++; break;
+ default:
+ fprintf(stderr, "%s: Unknown option: %c. Aborting\n", argv[0], opt);
+ usage();
+ exit(1);
+ }
+ }
+
+ openlog(program, LOG_PERROR | LOG_PID, LOG_DAEMON);
+ fd = open("/dev/zap/pseudo", O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to open zap interface: %s\n", strerror(errno));
+ exit(1);
+ }
+ if (verbose >=1)
+ syslog(LOG_INFO, "Opened pseudo zap interface, measuring accuracy...\n");
+
+ signal(SIGHUP, hup_handler);
+ signal(SIGINT, hup_handler);
+ signal(SIGUSR1, sigusr1_handler);
+ signal(SIGUSR2, sigusr2_handler);
+
+ if (cycles_to_run > 0) {
+ for(i=0; i<cycles_to_run; i++) {
+ sync_cycle(fd, interval);
+ }
+ hup_handler(0); /* exit */;
+ }
+
+ /* else (option -c not provided): run forever. */
+ for(;;) {
+ sync_cycle(fd, interval);
+ }
+}
diff --git a/xpp/utils/genzaptelconf b/xpp/utils/genzaptelconf
index d69b710..053bf1c 100755
--- a/xpp/utils/genzaptelconf
+++ b/xpp/utils/genzaptelconf
@@ -34,7 +34,7 @@
# (redhat/centos)
# /etc/default/zaptel may override the following variables
-VERSION=0.5.5
+VERSION=0.5.7
rcsid='$Id$'
lc_country=us
base_exten=6000
@@ -54,6 +54,8 @@ group_lines=0 # group for lines
# for others. Note that if an Astribank is not detected, the script
# will set this to "no", so you can safely leave it as "yes".
set_immediate=yes
+# Set fxs_immediate to 'yes' to make all FXS lines answer immediately.
+fxs_immediate=no
ZAPCONF_FILE=${ZAPCONF_FILE:-/etc/zaptel.conf}
ZAPCONF_FILE_SYSTEM=$ZAPCONF_FILE
@@ -68,8 +70,9 @@ exten_defs_file=/etc/asterisk/extensions-defs.conf
DEVZAP_TIMEOUT=${DEVZAP_TIMEOUT:-20}
ZTCFG=${ZTCFG:-/sbin/ztcfg}
-# a temporary directory. Created when the switch -r is parsed on getopts
-# and deleted in the end on update_extensions_defs
+# a temporary directory to store whatever we need to remember.
+#
+# The main loop of genconf is run in a sub-process.
tmp_dir=
# A list of all modules:
@@ -87,7 +90,7 @@ if [ ! -x "$ZTCFG" ]; then
if [ -x /usr/sbin/ztcfg ]; then
ZTCFG=/usr/sbin/ztcfg
else
- echo "ztcfg is not on found, do you have zaptel properly installed?"
+ echo >&2 "ztcfg is not on found, do you have zaptel properly installed?"
exit 1;
fi
fi
@@ -106,6 +109,8 @@ verbose=no
do_restart=yes
fxsdisable=no
+span_te_timing_counter=1
+
die() {
echo "$@" >&2
exit 1
@@ -184,11 +189,6 @@ update_module_list() {
fi
}
-update_extensions_defs() {
- # cleaning up the temp dir
- if [ -d "$tmp_dir" ]; then rm -rf "$tmp_dir"; fi
-}
-
zap_reg_xpp() {
@@ -226,8 +226,8 @@ usage() {
echo >&2 "$program: generate zaptel.conf and zapata.conf"
echo >&2 "(version $VERSION, $rcsid)"
echo >&2 "usage:"
- echo >&2 " $program [-sdv] [-m k|l|g] [-c <country_code>] [-r |-e <base_exten>] "
- echo >&2 " $program [-sdv] -l"
+ echo >&2 " $program [-sRdv] [-m k|l|g] [-c <country_code>] [-e <base_exten>] [-F]"
+ echo >&2 " $program [-sRdv] -l"
echo >&2 " $program -su"
echo >&2 " $program -h (this screen)"
echo >&2 ""
@@ -237,9 +237,9 @@ usage() {
echo >&2 " -F: Don't print FXSs in zapata.conf"
echo >&2 " -l: output a list of detected channels instead of zaptel.conf"
echo >&2 " -d: Perform hardware detection"
- echo >&2 " -u: Unload zaptel modules"
+ echo >&2 " -u: Unload zaptel modules (will not restart Asterisk)."
echo >&2 " -v: verbose"
- echo >&2 " -s: Don't fail if asterisk is running. Stop it"
+ echo >&2 " -s: Stop Asterisk before running, and start it at the end."
echo >&2 " -R: Don't restart asterisk in the end."
}
@@ -264,19 +264,19 @@ print_pattern() {
then method=ls
fi
case "$mode" in
- zaptel)
+ list) echo $chan $sig $astbanktype;;
+ files)
# sadly, both input ports and output ports go into the same span as
# the FXS ports. Thus we need to separate between them. See also
# the zapata.conf section:
- if [ "$astbank_type" != '' ]; then echo "# astbanktype: $astbank_type"; fi
- echo "${sig}$method=$chan"
- ;;
- list) echo $chan $sig $astbanktype;;
- zapata)
+ if [ "$astbank_type" != '' ];
+ then echo "# astbanktype: $astbank_type" >>$zaptel_file;
+ fi
+ echo "${sig}$method=$chan" >>$zaptel_file
# zap2amp will rewrite those from zaptel.conf and hints there
- if [ "$fxsdisable" = 'yes' ] && [ $sig = 'fxo' ]; then return; fi
+ if [ "$fxsdisable" = 'yes' ] && [ "$sig" = 'fxo' ]; then return; fi
- echo "signalling=${sig}_$method"
+ echo "signalling=${sig}_$method" >>$zapata_file
if [ "$sig" = 'fxo' ]
then
# to preconfigure channel 1's extension to 550, set
@@ -302,59 +302,60 @@ print_pattern() {
else # use the pre-configured extension number
vmbox=$cfg_vmbox
fi
- echo "callerid=\"Channel $chan\" <$exten>"
- echo "mailbox=$exten"
+ echo "callerid=\"Channel $chan\" <$exten>" >> $zapata_file
+ echo "mailbox=$exten" >> $zapata_file
if [ "$group_manual" != "yes" ]
then
- echo "group=$group_phones"
+ echo "group=$group_phones" >> $zapata_file
fi
if [ "$context_manual" != "yes" ]
then
if [ "$astbank_type" != '' ];
then
context_var_name=context_$astbank_type
- echo context=${!context_var_name}
+ echo context=${!context_var_name} >> $zapata_file
else
- echo "context=$context_phones"
+ echo "context=$context_phones" >> $zapata_file
fi
fi
else # this is an FXO (trunk/phone: FXO signalling)
# we have may have set it. So reset it:
- echo "callerid=asreceived"
- echo "mailbox="
+ echo "callerid=asreceived" >> $zapata_file
+ echo "mailbox=" >> $zapata_file
if [ "$group_manual" != "yes" ]
then
- echo "group=$group_lines"
+ echo "group=$group_lines" >> $zapata_file
fi
if [ "$context_manual" != "yes" ]
then
- echo "context=$context_lines"
+ echo "context=$context_lines" >> $zapata_file
fi
if [ "$lc_country" = 'uk' ]
then
- echo "cidsignalling=v23"
+ echo "cidsignalling=v23" >> $zapata_file
case $line in
- *WCFXO*) echo "cidstart=history";;
- *) echo "cidstart=polarity";; #a TDM400
+ *WCFXO*) echo "cidstart=history" >> $zapata_file;;
+ *) echo "cidstart=polarity" >> $zapata_file;;
esac
fi
- echo ";;; line=\"$line\""
+ echo ";;; line=\"$line\"" >> $zapata_file
# if kewlstart is not used, busydetect has to be employed:
if [ "$method" = 'ls' ]
- then echo 'busydetect=yes'
- else echo 'busydetect=no'
+ then echo 'busydetect=yes' >> $zapata_file
+ else echo 'busydetect=no' >> $zapata_file
fi
fi
if [ "$set_immediate" = 'yes' ]
then
- if [ "$astbank_type" = 'input' ]
- then echo 'immediate=yes'
- else echo 'immediate=no'
+ if [ "$astbank_type" = 'input' ] || \
+ ( [ "$fxs_immediate" = 'yes' ] && [ "$sig" = "fxo" ] )
+ then echo 'immediate=yes' >> $zapata_file
+ else echo 'immediate=no' >> $zapata_file
fi
fi
- echo "channel => $chan"
- echo ""
+ echo "channel => $chan" >> $zapata_file
+ echo "" >> $zapata_file
# Keep a note of what channels we have identified
say "DEBUG: adding to channels list: channel: $chan, sig: $sig"
@@ -456,16 +457,7 @@ unload_modules() {
# sleep a while until the xpp modules fully register
wait_for_xpp() {
- case "`uname -r`" in
- 2.6.8*)
- autoreg="/sys/module/xpp/zap_autoreg"
- ;;
- *)
- autoreg="/sys/module/xpp/parameters/zap_autoreg"
- ;;
- esac
- if [ -d /proc/xpp ] && \
- [ "`cat $autoreg`" = 'Y' ]
+ if [ -d /proc/xpp ]
then
# wait for the XPDs to register:
# TODO: improve error reporting and produce a messagee here
@@ -549,14 +541,10 @@ genconf() {
#say "DEBUG: resetting channels lists"
rm -f $tmp_dir/fx{s,o}_*
- if [ "$mode" = 'zapata' ]
- then
- rem_char=';'
- else
- rem_char='#'
- fi
-
- spanlist=`echo /proc/zaptel/* | grep -v '\*'`
+# spanlist=`echo /proc/zaptel/* | grep -v '\*'`
+# spanlist=$(for i in `for i in /proc/zaptel/*; do if [ -f $i ]; then echo $i | cut -f 4 -d / ; fi; done | sort -n`; do echo -n "/proc/zaptel/$i "; done)
+# spanlist=(cd /proc/zaptel; ls | sort -n | sed 's|^|/proc/zaptel/|')
+ spanlist=`ls /proc/zaptel/ 2>/dev/null | sort -n | sed 's|^|/proc/zaptel/|'`
#if [ "$spanlist" == "" ]; then
# die "No zapata interfaces in /proc/zaptel"
@@ -564,8 +552,22 @@ genconf() {
case "$mode" in
- zaptel)
- cat <<EOF
+ files)
+ local zaptel_file=`mktemp -t genzaptelconf-zaptel-XXXXXX`
+ local zapata_file=`mktemp -t genzaptelconf-zapata-XXXXXX`
+ if [ -r "${ZAPCONF_FILE}" ]; then
+ chown --reference="${ZAPCONF_FILE}" $zaptel_file || true
+ chmod --reference="${ZAPCONF_FILE}" $zaptel_file
+ else
+ chmod 644 $zaptel_file
+ fi
+ if [ -r "${ZAPATA_FILE}" ]; then
+ chown --reference="${ZAPATA_FILE}" $zapata_file || true
+ chmod --reference="${ZAPATA_FILE}" $zapata_file
+ else
+ chmod 644 $zapata_file
+ fi
+ cat <<EOF >$zaptel_file
# Autogenerated by $0 -- do not hand edit
# Zaptel Configuration File
#
@@ -575,9 +577,7 @@ genconf() {
# It must be in the module loading order
EOF
- ;;
- zapata)
- cat <<EOF
+ cat <<EOF >$zapata_file
; Autogenerated by $0 -- do not hand edit
; Zaptel Channels Configurations (zapata.conf)
;
@@ -596,9 +596,6 @@ EOF
# The '<(command)' syntax creates a temporary file whose content is is the
# output of 'command'.
#
- # This approach failed with the T1 card we have: the read operation simply
- # hung.
- #
# Another problem with such an approach is how to include an existing
# configuration file. For instance: how to include some default settings.
#
@@ -610,18 +607,21 @@ EOF
# the first line is the title line. It states the model name
# the second line is empty
title=`head -n 1 $procfile`
- echo ""
- # stuff that needs to be remembered accross lines (for PRI support)
- echo "$rem_char $title"
+ # stuff that needs to be remembered accross lines (for PRI/BRI support)
+ echo "" >>$zaptel_file
+ echo "# $title" >>$zaptel_file
+ echo "" >>$zapata_file
+ echo "; $title" >>$zapata_file
echo '-1' >$tmp_dir/span_begin
echo '-1' >$tmp_dir/span_end
- echo '1' >$tmp_dir/span_timing
+ echo '0' >$tmp_dir/span_timing
echo '1' >$tmp_dir/span_lbo
echo '' >$tmp_dir/span_framing
echo 'ami' >$tmp_dir/span_coding
echo '' >$tmp_dir/span_switchtype
echo '' >$tmp_dir/span_signalling
+ # Check if ZapBRI cards are in TE or NT mode
if echo $title | egrep -q '((quad|octo)BRI PCI ISDN Card.* \[NT\]\ |octoBRI \[NT\] |HFC-S PCI A ISDN.* \[NT\] )'
then
echo 'nt' >$tmp_dir/span_termtype
@@ -639,18 +639,19 @@ EOF
chan_num=`echo $line |awk '{print $1}'`
case "$line" in
*WCTDM/*|*/WRTDM/*|*OPVXA1200/*)
+ # TDM400P/2400P and similar cards (Sangoma A200, OpenVox A1200)
# this can be either FXS or FXO
maybe_fxs=0
maybe_fxo=0
- $ztcfg_cmd -c <(print_pattern $chan_num fxo zaptel) &>/dev/null && maybe_fxs=1
- $ztcfg_cmd -c <(print_pattern $chan_num fxs zaptel) &>/dev/null && maybe_fxo=1
+ $ztcfg_cmd -c <(echo fxoks=$chan_num) &>/dev/null && maybe_fxs=1
+ $ztcfg_cmd -c <(echo fxsks=$chan_num) &>/dev/null && maybe_fxo=1
if [ $maybe_fxs = 1 ] && [ $maybe_fxo = 1 ]
then
# An installed module won't accept both FXS and FXO signalling types:
# this is an empty slot.
# TODO: I believe that the Sangoma A20x will reject both and thus
# print nothing here.
- echo "$rem_char channel $chan_num, WCTDM, no module."
+ echo "# channel $chan_num, WCTDM, no module." >> $zaptel_file
continue
fi
@@ -658,46 +659,64 @@ EOF
if [ $maybe_fxo = 1 ]; then print_pattern $chan_num fxs $mode; fi
;;
*WCFXO/*)
+ # X100P
print_pattern $chan_num fxs $mode || \
- echo "$rem_char channel $chan_num, WCFXO, inactive."
+ echo "# channel $chan_num, WCFXO, inactive." >>$zaptel_file
;;
*WCUSB/*)
print_pattern $chan_num fxo $mode
;;
*XPP_FXO/*)
+ # Astribank FXO span
print_pattern $chan_num fxs $mode
;;
*XPP_FXS/*)
+ # Astribank FXS span (regular port)
print_pattern $chan_num fxo $mode
;;
*XPP_OUT/*)
+ # Astribank FXS span (output port)
print_pattern -a output $chan_num fxo $mode
;;
*XPP_IN/*)
+ # Astribank FXS span (input port)
print_pattern -a input $chan_num fxo $mode
;;
- *ZTHFC*/*|*ztqoz*/*|*ztgsm/*|*TE4/*|*TE2/*|*WCT1/*|*Tor2/*|*TorISA/*) # should also be used for other PRI channels
+ *ZTHFC*/*|*ztqoz*/*|*ztgsm/*|*TE[24]/*|*WCT1/*|*Tor2/*|*TorISA/*|*XPP_BRI_*/*|*WP[TE]1/*)
+ # PRI/BRI channel
+ # Rather than identifying cards by the header line, we identify them by the channel names
+ # This is shorter. This also allows us to count the channel numbers and check if a PRI
+ # card is E1 or T1.
if [ "`cat $tmp_dir/span_begin`" = "-1" ]
then
echo $chan_num >$tmp_dir/span_begin
echo $span_num >$tmp_dir/span_num
+ # The Astribank channels provide the information of TE/NT in the channel name. So
+ # why not use it?
case "$line" in
- *ZTHFC*/*|*ztqoz*/*)
+ *XPP_BRI_TE/*) echo 'te' >$tmp_dir/span_termtype;;
+ *XPP_BRI_NT/*) echo 'nt' >$tmp_dir/span_termtype;;
+ esac
+ case "$line" in
+ *ZTHFC*/*|*ztqoz*/*|*XPP_BRI_*/*)
+ # BRI channel
echo 'ccs' >$tmp_dir/span_framing
echo 'euroisdn' >$tmp_dir/span_switchtype
if [ "`cat $tmp_dir/span_termtype`" = 'nt' 2>/dev/null ]
then
- echo 'bri_net' >$tmp_dir/span_signalling
+ echo 'bri_net' >$tmp_dir/span_signalling
else
echo 'bri_cpe' >$tmp_dir/span_signalling
fi
;;
*ztgsm*/*)
+ # Junghanns's GSM cards.
echo 'ccs' >$tmp_dir/span_framing
# what switch type? Any meaning to it?
echo 'gsm' >$tmp_dir/span_signalling
;;
- *TE4/*|*TE2/*|*WCT1/*|*Tor2/*|*TorISA/*)
+ *TE[24]/*|*WCT1/*|*Tor2/*|*TorISA/*|*WP[TE]1/*)
+ # PRI span (E1/T1)
echo 'esf' >$tmp_dir/span_framing
echo 'b8zs' >$tmp_dir/span_coding
echo 'national' >$tmp_dir/span_switchtype
@@ -713,11 +732,18 @@ EOF
#echo 'euroisdn' >$tmp_dir/span_switchtype
#echo 'pri_cpe' >$tmp_dir/span_signalling
;;
- il)
+ il|de|au)
echo 'ccs' >$tmp_dir/span_framing
echo 'hdb3' >$tmp_dir/span_coding
echo 'crc4' >$tmp_dir/span_yellow
echo 'euroisdn' >$tmp_dir/span_switchtype
+ ;;
+ cl)
+ echo 'ccs' >$tmp_dir/span_framing
+ echo 'hdb3' >$tmp_dir/span_coding
+ #echo 'crc4' >$tmp_dir/span_yellow
+ echo 'national' >$tmp_dir/span_switchtype
+ ;;
esac
;;
esac
@@ -727,9 +753,18 @@ EOF
echo $chan_num >$tmp_dir/span_end
;;
'') ;; # Empty line (after span header)
- *) echo "$rem_char ??: $line";;
+ *)
+ case "$mode" in
+ list) echo "# ??: $line";;
+ files)
+ echo "# ??: $line" >>$zaptel_file
+ echo "; ??: $line" >>$zaptel_file
+ esac
+ ;;
esac
done
+ # end of part in sub-process.
+
if [ "`cat $tmp_dir/span_begin`" != -1 ]
then # write PRI span ocnfig:
# read files to variables:
@@ -747,52 +782,65 @@ EOF
bchans="$span_begin-$(($span_end-1))"
;;
31) #E1
- dchan="$(($span_begin+15))"
+ dchan="$(($span_begin+15))"
bchans="$span_begin-$(($span_begin+14)),$(($span_begin+16))-$span_end"
+ if [ "$span_switchtype" = 'national' ]; then
+ span_framing=ccs
+ span_coding=hdb3
+ span_switchtype=euroisdn
+ fi
+ ;;
+ esac
+ # Let's assume that a TE span should get the clock from the remote unit,
+ # and NT spans should provide timing. Just as a sane default.
+ # If we have several TE spans, the first will have priority 1,
+ # second: 2, etc.
+ case "$span_signalling" in *_cpe*)
+ span_timing=$span_te_timing_counter
+ span_te_timing_counter=$(($span_te_timing_counter + 1))
;;
esac
case "$mode" in
- zaptel)
- echo span=$span_num,$span_timing,$span_lbo,$span_framing,$span_coding$span_yellow
+ files)
+ echo span=$span_num,$span_timing,$span_lbo,$span_framing,$span_coding$span_yellow >> $zaptel_file
if [ "$span_termtype" != '' ]
- then echo "# termtype: $span_termtype"
+ then echo "# termtype: $span_termtype" >>$zaptel_file
fi
- echo bchan=$bchans
- echo dchan=$dchan
- ;;
- zapata)
+ echo bchan=$bchans >>$zaptel_file
+ echo dchan=$dchan >>$zaptel_file
+
if [ "$span_termtype" != '' ]
then
# an ISDN card's span that we know if it is in NT mode or TE mode.
# NT is the same as FXS for us and TE is the same as FXO
if [ "$span_termtype" = 'nt' ]
then
- echo "callerid=\"Channels $span_begin - $span_end\" <$span_begin>"
+ echo "callerid=\"Channels $span_begin - $span_end\" <$span_begin>" >> $zapata_file
#echo "mailbox=$exten"
if [ "$group_manual" != "yes" ]
then
- echo "group=$group_phones"
+ echo "group=$group_phones" >> $zapata_file
fi
if [ "$context_manual" != "yes" ]
then
- echo "context=$context_phones"
+ echo "context=$context_phones" >> $zapata_file
fi
else # we have may have set it. So reset it:
echo "callerid=asreceived"
#echo "mailbox="
if [ "$group_manual" != "yes" ]
then
- echo "group=$group_lines"
+ echo "group=$group_lines" >> $zapata_file
fi
if [ "$context_manual" != "yes" ]
then
- echo "context=$context_lines"
+ echo "context=$context_lines" >> $zapata_file
fi
fi
fi
- echo "switchtype = $span_switchtype"
- echo "signalling = $span_signalling"
- echo "channel => $bchans"
+ echo "switchtype = $span_switchtype" >> $zapata_file
+ echo "signalling = $span_signalling" >> $zapata_file
+ echo "channel => $bchans" >> $zapata_file
;;
list)
echo BRI/PRI: chans: $bchans, control: $dchan
@@ -801,21 +849,23 @@ EOF
fi
done
- if [ "$mode" = 'zaptel' ]
+ if [ "$mode" = 'files' ]
then
- cat <<EOF
+ cat <<EOF >> ${zaptel_file}
# Global data
+loadzone = $loadzone
+defaultzone = $defaultzone
EOF
- echo "loadzone = $loadzone"
- echo "defaultzone = $defaultzone"
fi
- if [ "$mode" = 'zapata' ] || [ "$mode" = 'list' ]
- then
- update_extensions_defs
- fi
+ mv ${ZAPCONF_FILE} ${ZAPCONF_FILE}.bak
+ mv $zaptel_file ${ZAPCONF_FILE}
+ mv ${ZAPATA_FILE} ${ZAPATA_FILE}.bak
+ mv $zapata_file ${ZAPATA_FILE}
+ # cleaning up the temp dir
+ if [ -d "$tmp_dir" ]; then rm -rf "$tmp_dir"; fi
}
while getopts 'c:de:Fhlm:MRsuv' arg
@@ -896,13 +946,9 @@ if [ "$mode" = list ]; then
else
zap_reg_xpp
check_for_astribank
- say "Generating '${ZAPCONF_FILE}'"
- mv "${ZAPCONF_FILE}" "${ZAPCONF_FILE}.bak"
wait_for_zapctl
- genconf zaptel > "${ZAPCONF_FILE}"
- say "Generating '${ZAPATA_FILE}'"
- mv "${ZAPATA_FILE}" "${ZAPATA_FILE}.bak"
- genconf zapata > "${ZAPATA_FILE}"
+ say "Generating '${ZAPCONF_FILE} and ${ZAPATA_FILE}'"
+ genconf files
if [ "$set_immediate" = 'yes' ] && [ -x /etc/init.d/zaptel ]
then /etc/init.d/zaptel start
else run_ztcfg
diff --git a/xpp/utils/genzaptelconf.8 b/xpp/utils/genzaptelconf.8
index 0ec62a2..081b52d 100644
--- a/xpp/utils/genzaptelconf.8
+++ b/xpp/utils/genzaptelconf.8
@@ -5,10 +5,10 @@
.SH SYNOPSIS
.PP
.B genzaptelconf
-[-sdv] [-c <country_code>] [-r |-e <base_exten>] [ -F ]
+[-sRdv] [-c <country_code>] [-e <base_exten>] [ -F ]
.B genzaptelconf
-[-sdv] -l -- only list to standard output
+[-sRdv] -l -- only list to standard output
.B genzaptelconf
-su -- only unload zaptel modules
@@ -65,7 +65,7 @@ as extension
.I exten_num
+
.I i
-. This is mostly for the caller-id values. Crude, but may be good enough.
+ . This is mostly for the caller-id values. Crude, but may be good enough.
See also
.I -r
.RE
@@ -99,11 +99,11 @@ This triggers the
option as well.
.RE
-.B -r
+.B -R
.RS
-Try to guess a useful
-.I zapata-channels
-configuration for Xorcom Rapid .
+Don't restart asterisk even if it was stopped using
+.I -s
+ .
.RE
.B -s
@@ -115,7 +115,6 @@ work if nobody uses the zaptel channels:
* to allow reading configuration files.
-By default the script will check if asterisk is running and alert if so.
This option tells the script to stop asterisk (if it was running) and to
try to start it after the end of the test.
.RE
@@ -127,61 +126,29 @@ Be verbose. lists the detected modules if
is used. Lists detected channls. In the end tries to connect to asterisk
to get a list of configured zaptel channels.
.RE
-.SH FILES
-.I /etc/zaptel.conf
-.RS
-The configuration file used by
-.I ztcfg
-to configure zaptel devices. re-written by
-.I genzaptelconf
-.RE
-
-.I /etc/zaptel.conf.bak
-.RS
-When
-.I zaptel.conf
-The original zaptel.conf
-.RE
-
-.I /etc/asterisk/zapata.conf
-.RS
-The configuration file of Asterisk's
-.I chan_zap.
-Not modified directly by
-.I genzaptelconf.
-If you want genzaptelconf's setting to take effect, add the following
-line at the end of
-.I zapata.conf:
-.RS
-#include "zapata-channels.conf"
-.RE
-.RE
-
-.I /etc/asterisk/zapata-channels.conf
-.RS
-This is the snippet of
-.I chan_zap
-configuration file that
-.I genzaptelconf generates.
-.RE
+.SH CONFIGURATION
+Look at the beginning of the script for a number of variables that can
+be overriden through the configuraion file. Some variables can also be
+overriden through the environment. The configuration file is sourced by
+bash but for compatibility expected to have only 'var=VALUE' lines and
+comments or empty lines.
+
+The configuration will first be read from
+.I /etc/default/zaptel
+if it exists, and
+.I /etc/sysconfig/zaptel
+otherwise (But those file names may be overriden, see
+.I ZAPTEL_BOOT_DEBIAN
+and
+.I ZAPTEL_BOOT_FEDORA
+below). Variables set in those files will override the default settings
+and setting rom the environment.
-.I /etc/asterisk/zapata-channels.conf.bak
-.RS
-The backup copy of
-.I zapata-channels.conf
-.RE
+The following variables may be set from the environment:
+ZAPCONF_FILE, ZAPATA_FILE, ZAPTEL_BOOT_DEBIAN, ZAPTEL_BOOT_FEDORA,
+DEVZAP_TIMEOUT, ZTCFG
-.I /etc/default/zaptel
.RS
-This file holds configuration for both
-.I genzaptelconf
-and
-.I /etc/init.d/zaptel .
-It is sourced by both scripts and can thus be used to override settings
-of variables from those scripts.
-Some of the variables that can be set in /etc/default/zaptel and affect
-genzaptelconf:
-
.I lc_country
.RS
The default country. Can be also overriden by the option -c
@@ -227,6 +194,94 @@ The group number for zaptel phones.
modules list. Used for unloading and modules detection. The order of modules
is the same for both.
.RE
+
+.I ZAPCONF_FILE
+.RS
+ztcfg's configuration file. The sane default is /etc/zaptel.conf .
+.RE
+
+.I ZAPATA_FILE
+.RS
+The generated partial zapata.conf snippet. Default:
+/etc/asterisk/zapata-channels.conf .
+.RE
+
+.I ZAPTEL_BOOT_DEBIAN
+.RS
+The Debian Zaptel defaults file. Normally
+.I /etc/default/zaptel
+.
+.RE
+
+
+.I ZAPTEL_BOOT_FEDORA
+.RS
+The Zaptel defaults file on various other distributions. Normally
+.I /etc/sysconfig/zaptel
+ .
+.RE
+
+.I DEVZAP_TIMEOUT
+.RS
+Maximal number of seconds to wait for /dev/zap to be initializaed by
+udev.
+.RE
+
+.I ZTCFG
+.RS
+The full path to the ztcfg tool. Default:
+.I /sbin/ztcfg
+genzaptelconf will also explicitly test for
+.I /usr/sbin/ztcfg
+as a last resort.
+.RE
+.RE
+
+.SH FILES
+.I /etc/zaptel.conf
+.RS
+The configuration file used by
+.I ztcfg
+to configure zaptel devices. re-written by
+.I genzaptelconf
+ . A backup copy is saved to
+.I /etc/zaptel.conf.bak
+ .
+.RE
+
+.I /etc/asterisk/zapata.conf
+.RS
+The configuration file of Asterisk's
+.I chan_zap.
+Not modified directly by
+.I genzaptelconf.
+If you want genzaptelconf's setting to take effect, add the following
+line at the end of
+.I zapata.conf:
+.RS
+#include "zapata-channels.conf"
+.RE
+.RE
+
+.I /etc/asterisk/zapata-channels.conf
+.RS
+This is the snippet of
+.I chan_zap
+configuration file that
+.I genzaptelconf generates.
+ . A backup copy is saved to
+.I /etc/asterisk/zapata-channels.conf.bak
+ .
+.RE
+
+.I /etc/default/zaptel
+.RS
+This file holds configuration for both
+.I genzaptelconf
+and
+.I /etc/init.d/zaptel .
+It is sourced by both scripts and can thus be used to override settings
+of variables from those scripts.
.RE
.I /etc/modules
@@ -237,9 +292,9 @@ boot time. When the option
(detect) is used, genzaptelconf will write in this file zaptel modules
to be loaded. If you want to use a different file, set
.I MOD_FILELIST
-.RE
-
+ . If it is rewritten, a backup copy is saved to
.I /etc/modules.bak
+ .
.RS
The backup copy of
.I /etc/modules
@@ -248,6 +303,11 @@ The backup copy of
.SH "SEE ALSO"
ztcfg(8) asterisk(8).
+.SH BUGS
+If you override a configuration variable both through the environment
+and through the configuration file, the value from the configuration
+file wins.
+
.SH "AUTHOR"
This manual page was written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
Permission is granted to copy, distribute and/or modify this document under
diff --git a/xpp/utils/xpp_fxloader b/xpp/utils/xpp_fxloader
index f584266..8c54370 100644
--- a/xpp/utils/xpp_fxloader
+++ b/xpp/utils/xpp_fxloader
@@ -29,12 +29,8 @@
#
# BUS!="usb", ACTION!="add", GOTO="zaptel_usb_add_end"
#
-# SYSFS{idVendor}=="04b4", SYSFS{idProduct}=="8613", \
-# RUN+="/etc/hotplug/usb/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/"
-# SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="1130", \
-# RUN+="/etc/hotplug/usb/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/"
-# SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="1131", \
-# RUN+="/etc/hotplug/usb/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/"
+# SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="11[345][01]", \
+# RUN+="/etc/hotplug/usb/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/$sysfs{bcdDevice}"
#
# LABEL="zaptel_usb_add_end"
#
@@ -151,9 +147,13 @@ xppdetect|load|usb)
load_fw 04b4 8613 USB_8613.hex
load_fw e4e4 1130 USB_1130.hex
+ load_fw e4e4 1140 USB_1140.hex
+ load_fw e4e4 1150 USB_1150.hex
if [ "$1" != 'usb' ]
then
load_fpga e4e4 1131 FPGA_FXS.hex
+ load_fpga e4e4 1141 FPGA_1141.hex
+ load_fpga e4e4 1151 FPGA_1151.hex
fi
sleep 3 # Let it stabilize
@@ -182,12 +182,12 @@ then
$LOGGER "Trying to find what to do for product $PRODUCT, device $DEVICE"
prod_id=`echo "$PRODUCT" | cut -d/ -f2`
case "$PRODUCT" in
- 4b4/8613/*|e4e4/1130/*|e4e4/1140/*)
+ 4b4/8613/*|e4e4/11[345]0/*)
FIRM_USB="$FIRMWARE_DIR/USB_$prod_id.hex"
$LOGGER "Loading firmware '$FIRM_USB' into '$DEVICE'"
do_fxload -D "$DEVICE" -I "$FIRM_USB"
;;
- e4e4/1131/*|e4e4/1141/*)
+ e4e4/11[345]1/*)
if [ "$prod_id" = 1131 ]; then
FIRM_FPGA="$FIRMWARE_DIR/FPGA_FXS.hex" # Legacy
else
diff --git a/xpp/utils/xpp_fxloader.usermap b/xpp/utils/xpp_fxloader.usermap
index bdfa861..70ca68a 100644
--- a/xpp/utils/xpp_fxloader.usermap
+++ b/xpp/utils/xpp_fxloader.usermap
@@ -2,3 +2,7 @@
xpp_fxloader 0x0003 0x04b4 0x8613 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
xpp_fxloader 0x0003 0xe4e4 0x1130 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
xpp_fxloader 0x0003 0xe4e4 0x1131 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1140 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1141 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1150 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1151 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
diff --git a/xpp/xbus-core.c b/xpp/xbus-core.c
index 961c361..9f73a86 100644
--- a/xpp/xbus-core.c
+++ b/xpp/xbus-core.c
@@ -55,7 +55,6 @@ static int proc_xbus_command_write(struct file *file, const char __user *buffer,
/* Command line parameters */
extern int print_dbg;
-extern int max_queue_len;
/* Forward declarations */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
@@ -133,105 +132,6 @@ void xbus_packet_free(xbus_t *xbus, xpacket_t *p)
// xbus->busname, atomic_read(&xbus->packet_counter));
}
-/*------------------------- Packet Queues --------------------------*/
-void init_xbus_packet_queue(packet_queue_t *q, const char name[])
-{
- INIT_LIST_HEAD(&q->head);
- spin_lock_init(&q->lock);
- q->count = 0;
- q->worst_count = 0;
- q->overflows = 0;
- snprintf(q->qname, XPD_NAMELEN, "%s", name);
-}
-
-#if 0
-/*
- * Assume the queue is locked
- */
-void __dump_packet_queue(const char *msg, packet_queue_t *q)
-{
- xpacket_t *tmp;
-
- list_for_each_entry(tmp, &q->head, list) {
- dump_packet(msg, tmp);
- }
-}
-#endif
-
-void drain_xbus_packet_queue(xbus_t *xbus, packet_queue_t *q)
-{
- unsigned long flags;
- xpacket_t *pack;
- xpacket_t *next;
-
- spin_lock_irqsave(&q->lock, flags);
- DBG("queue=%s count=%d\n", q->qname, q->count);
- DBG(" total packets count=%d\n", atomic_read(&xpacket_count));
- list_for_each_entry_safe(pack, next, &q->head, list) {
- list_del(&pack->list);
- q->count--;
- xbus->ops->packet_free(xbus, pack);
- }
- if(q->count != 0)
- ERR("drain_xbus_packet_queue: queue %s still has %d packets\n",
- q->qname, q->count);
- spin_unlock_irqrestore(&q->lock, flags);
-}
-
-void xbus_enqueue_packet(xbus_t *xbus, packet_queue_t *q, xpacket_t *pack)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&q->lock, flags);
-
- if(q->count >= max_queue_len) {
- static unsigned long last_notice = 0; // rate limit
-
- if((jiffies - last_notice) < HZ) {
- NOTICE("xbus_enqueue_packet: dropping packet (queue len = %d, max=%d)\n",
- q->count, max_queue_len);
- last_notice = jiffies;
- }
- q->overflows++;
- xbus->ops->packet_free(xbus, pack);
- goto out;
- }
- list_add_tail(&pack->list, &q->head);
- q->count++;
-
- if(q->count > q->worst_count)
- q->worst_count = q->count;
-
- if(q->count < max_queue_len/100 && q->worst_count > q->count) // Decay worst_count
- q->worst_count--;
-
- // dump_packet("ENQUEUED", pack, print_dbg);
-out:
- spin_unlock_irqrestore(&q->lock, flags);
-}
-
-xpacket_t *xbus_dequeue_packet(packet_queue_t *q)
-{
- unsigned long flags;
- struct list_head *p;
- xpacket_t *pack = NULL;
-
- spin_lock_irqsave(&q->lock, flags);
-
- if(list_empty(&q->head)) {
- // DBG("LIST EMPTY (count=%d)\n", q->count);
- goto out;
- }
- p = q->head.next;
- list_del(p);
- q->count--;
- pack = list_entry(p, xpacket_t, list);
- // dump_packet("DEQUEUED", pack, print_dbg);
-out:
- spin_unlock_irqrestore(&q->lock, flags);
- return pack;
-}
-
/*------------------------- Bus Management -------------------------*/
xbus_t *xbus_of(int xbus_num)
@@ -430,7 +330,6 @@ void xbus_activate(xbus_t *xbus)
BUG_ON(!xbus);
ops = xbus->ops;
BUG_ON(!ops);
- BUG_ON(!xbus->priv);
/* Sanity checks */
BUG_ON(!ops->packet_send);
BUG_ON(!ops->packet_new || !ops->packet_free);
@@ -504,6 +403,7 @@ static void xbus_free(xbus_t *xbus)
if(!xbus)
return;
spin_lock_irqsave(&xbuses_lock, flags);
+ BUG_ON(!xbus_of(xbus->num));
BUG_ON(xbus != xbus_of(xbus->num));
xbuses_array[xbus->num] = NULL;
bus_count--;
@@ -658,6 +558,10 @@ void xbus_remove(xbus_t *xbus)
int ret;
BUG_ON(!xbus);
+ if(!xbus_of(xbus->num)) {
+ DBG("XBUS #%d was already removed. Skip.\n", xbus->num);
+ return;
+ }
DBG("%s\n", xbus->busname);
/* Block until no one use */
diff --git a/xpp/xbus-core.h b/xpp/xbus-core.h
index 19f9fd7..f2bac8c 100644
--- a/xpp/xbus-core.h
+++ b/xpp/xbus-core.h
@@ -33,12 +33,6 @@ void xbus_core_shutdown(void); /* Terminator */
xpacket_t *xbus_packet_new(xbus_t *xbus, gfp_t flags);
void xbus_packet_free(xbus_t *xbus, xpacket_t *p);
-/* packet queues */
-void init_xbus_packet_queue(packet_queue_t *q, const char name[]);
-void drain_xbus_packet_queue(xbus_t *xbus, packet_queue_t *q);
-void xbus_enqueue_packet(xbus_t *xbus, packet_queue_t *q, xpacket_t *pack);
-xpacket_t *xbus_dequeue_packet(packet_queue_t *q);
-
/* XBUS handling */
xbus_t *xbus_of(int xbus_num);
xpd_t *xpd_of(xbus_t *xbus, int xpd_num);
diff --git a/xpp/xdefs.h b/xpp/xdefs.h
index ab3670e..d7c7032 100644
--- a/xpp/xdefs.h
+++ b/xpp/xdefs.h
@@ -67,11 +67,11 @@ struct list_head { struct list_head *next; struct list_head *prev; };
#define XBUS_NAMELEN 20 /* must be <= from maximal workqueue name */
#define XBUS_DESCLEN 40
-#define UNIT_BITS 4 /* Bit for Astribank unit number */
-#define SUBUNIT_BITS 4 /* Bit for Astribank subunit number */
+#define UNIT_BITS 3 /* Bit for Astribank unit number */
+#define SUBUNIT_BITS 3 /* Bit for Astribank subunit number */
-#define MAX_UNIT 4 /* 1 FXS + 3 FXS/FXO */
-#define MAX_SUBUNIT 1 /* Firmware does not support subunits yet */
+#define MAX_UNIT BIT(UNIT_BITS) /* 1 FXS + 3 FXS/FXO | 1 BRI + 3 FXS/FXO */
+#define MAX_SUBUNIT BIT(SUBUNIT_BITS) /* 8 port BRI */
/*
* Compile time sanity checks
@@ -88,6 +88,11 @@ struct list_head { struct list_head *next; struct list_head *prev; };
#define VALID_XPD_NUM(x) ((x) < MAX_XPDS && (x) >= 0)
+#define CHAN_BITS 5 /* 0-30 for E1, 31 = ALL_CHANS */
+#define ALL_CHANS BITMASK(CHAN_BITS)
+#define MAX_CHAN (ALL_CHANS - 1)
+#define VALID_CHAN_NUM(x) ((x) < MAX_CHAN)
+
typedef char *charp;
typedef unsigned char byte;
typedef int bool;
@@ -97,7 +102,7 @@ typedef struct xpacket_raw xpacket_raw_t;
typedef struct xpacket xpacket_t;
typedef struct xops xops_t;
typedef __u32 xpp_line_t; /* at most 31 lines for E1 */
-typedef int lineno_t;
+typedef byte lineno_t;
#endif /* XDEFS_H */
diff --git a/xpp/xpd.h b/xpp/xpd.h
index 71db99e..74b759d 100644
--- a/xpp/xpd.h
+++ b/xpp/xpd.h
@@ -191,8 +191,8 @@ struct xbus {
#endif
typedef enum xpd_direction {
- TO_PHONE = 0,
- TO_PSTN = 1,
+ TO_PSTN = 0,
+ TO_PHONE = 1,
} xpd_direction_t;
#ifdef __KERNEL__
@@ -255,6 +255,7 @@ struct xpd {
xpp_line_t cid_on;
xpp_line_t digital_outputs; /* 0 - no, 1 - yes */
xpp_line_t digital_inputs; /* 0 - no, 1 - yes */
+ xpp_line_t digital_signalling; /* PRI/BRI signalling channels */
int ringing[CHANNELS_PERXPD];
bool ringer_on[CHANNELS_PERXPD]; /* For ring toggling */
@@ -286,6 +287,8 @@ struct xpd {
const xops_t *xops; /* Card level operations */
void *priv; /* Card level private data */
bool card_present;
+ reg_cmd_t requested_reply;
+ reg_cmd_t last_reply;
unsigned long last_response; /* in jiffies */
unsigned id;
diff --git a/xpp/xpp_usb.c b/xpp/xpp_usb.c
index 89571c3..bc8af46 100644
--- a/xpp/xpp_usb.c
+++ b/xpp/xpp_usb.c
@@ -229,6 +229,7 @@ void xusb_packet_free(xbus_t *xbus, xpacket_t *p)
#else
+/* FIXME FIXME FIXME: should move code to card methods */
static void packet_debug(const char msg[], xusb_t *xusb, xpacket_t *pack)
{
char title[XBUS_DESCLEN];
@@ -261,16 +262,26 @@ static void packet_debug(const char msg[], xusb_t *xusb, xpacket_t *pack)
dump_packet("USB SEND PCM", pack, print_dbg);
#endif
return;
- } else if(pack->content.opcode == XPROTO_NAME(FXS, SLIC_WRITE)) {
- slic_cmd_t *sc;
+ } else if(pack->content.opcode == XPROTO_NAME(GLOBAL, REGISTER_REQUEST)) {
+ reg_cmd_t *regcmd;
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- if(sc->bytes == 2 && sc->content.direct.reg_num == 0x06 && sc->content.direct.read) /* ignore SLIC_QUERY */
+ regcmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
+ if(REG_FIELD(regcmd, regnum) == 0x06) /* ignore SLIC_QUERY */
return;
- if(sc->bytes == 2 && sc->content.direct.reg_num == DAA_VBAT_REGISTER && sc->content.direct.read) /* ignore DAA_QUERY */
+ if(REG_FIELD(regcmd, regnum) == DAA_VBAT_REGISTER) /* ignore DAA_QUERY */
return;
- } else if(pack->content.opcode == XPROTO_NAME(FXS, SLIC_REPLY)) {
+ if(REG_FIELD(regcmd, regnum) == 0x30) { /* ignore BRI query */
+#if 0
+ static int rate_limit;
+ if((rate_limit++ % 1000) < 10)
+ dump_packet("BRI STATE REG", pack, print_dbg);
+#endif
+ return;
+ }
+#if 0
+ } else if(pack->content.opcode == XPROTO_NAME(FXS, REGISTER_REPLY)) {
return;
+#endif
}
snprintf(title, XBUS_DESCLEN, "%s: %s", msg, xusb->xbus->busname);
dump_packet(title, pack, print_dbg);
@@ -405,16 +416,16 @@ static const struct xusb_model_info {
struct xusb_endpoint out;
xbus_type_t bus_type;
} model_table[] = {
- XUSB_MODEL(0x86, 0x02, FIRMWARE_LOOPBACK, "bulkloop.hex"),
- XUSB_MODEL(0x86, 0x02, FIRMWARE_LOOPBACK, "FPGA_bulkloop.hex"),
- XUSB_MODEL(0x86, 0x02, FIRMWARE_XPP, "FPGA_XPD.hex"),
+ XUSB_MODEL(0x86, 0x02, FIRMWARE_XPP, "FPGA_XPD"),
};
/* table of devices that work with this driver */
static const struct usb_device_id xusb_table [] = {
// { USB_DEVICE(0x04B4, 0x8613) }, // default of cypress
- { USB_DEVICE(0xE4E4, 0x2211), .driver_info=(kernel_ulong_t)&model_table[2] }, // FPGA_XPD.hex
- { USB_DEVICE(0xE4E4, 0x1132), .driver_info=(kernel_ulong_t)&model_table[2] }, // FPGA_XPD.hex
+ { USB_DEVICE(0xE4E4, 0x2211), .driver_info=(kernel_ulong_t)&model_table[0] }, // OLD FPGA
+ { USB_DEVICE(0xE4E4, 0x1132), .driver_info=(kernel_ulong_t)&model_table[0] }, // FPGA_FXS
+ { USB_DEVICE(0xE4E4, 0x1142), .driver_info=(kernel_ulong_t)&model_table[0] }, // FPGA_1141
+ { USB_DEVICE(0xE4E4, 0x1152), .driver_info=(kernel_ulong_t)&model_table[0] }, // FPGA_1151
/* "Gadget Zero" firmware runs under Linux */
//{ USB_DEVICE(0x0525, 0xa4a0) },
{ } /* Terminating entry */
diff --git a/xpp/xpp_zap.c b/xpp/xpp_zap.c
index 33ec4c6..0512dcc 100644
--- a/xpp/xpp_zap.c
+++ b/xpp/xpp_zap.c
@@ -38,9 +38,7 @@
#include <linux/delay.h> /* for udelay */
#include <linux/workqueue.h>
#include <linux/proc_fs.h>
-
-#include "zaptel.h"
-
+#include <zaptel.h>
#include <version.h> /* For zaptel version */
#include "xbus-core.h"
#include "xproto.h"
@@ -66,13 +64,13 @@ static unsigned int xpp_timer_count = 0;
static unsigned int xpp_last_jiffies = 0;
DEF_PARM(int, print_dbg, 0, "Print DBG statements");
-DEF_PARM(int, max_queue_len, MAX_QUEUE_LEN, "Maximum Queue Length.");
-DEF_PARM(bool, have_sync_bus, 0, "True if all Astribank(TM) devices are connected via a sync-cable");
DEF_PARM(bool, zap_autoreg, 1, "Register spans automatically (1) or not (0)");
+DEF_PARM(bool, prefmaster, 1, "Do we want to be zaptel preferred sync master");
+// DEF_ARRAY(int, pcmtx, 4, 0, "Forced PCM values to transmit");
#include "zap_debug.h"
#ifdef XPP_EC_CHUNK
-#include "echo_supress/ec_xpp.h"
+#include "supress/ec_xpp.h"
#endif
@@ -89,7 +87,7 @@ static void external_sync(xpd_t *the_xpd)
{
int i, j;
- DBG("SYNC %s (%s sync cable)\n", (the_xpd)?"Astribanks":"HOST", (have_sync_bus)?"with":"without");
+ DBG("SYNC %s\n", (the_xpd)?"Astribanks":"HOST");
// Shut all down
for(i = 0; i < MAX_BUSES; i++) {
xbus_t *xbus = xbus_of(i);
@@ -173,11 +171,15 @@ void xpp_tick(unsigned long param)
if(!xpd->card_present)
continue;
xpd->timer_count++;
+ if(SPAN_REGISTERED(xpd))
+ xpp_transmitprep(xpd);
+ if(SPAN_REGISTERED(xpd))
+ xpp_receiveprep(xpd);
+ /*
+ * Must be called *after* tx/rx so
+ * D-Chan counters may be cleared
+ */
CALL_XMETHOD(card_tick, xbus, xpd);
- if(!SPAN_REGISTERED(xpd))
- continue;
- xpp_transmitprep(xpd);
- xpp_receiveprep(xpd);
}
up_read(&xbus->in_use);
}
@@ -229,8 +231,7 @@ static void xpd_free(xpd_t *xpd)
#define REV(x,y) (10 * (x) + (y))
static byte good_revs[] = {
- REV(1,9),
- REV(2,0),
+ REV(2,3),
};
#undef REV
@@ -341,10 +342,10 @@ void card_detected(struct card_desc_struct *card_desc)
if(CALL_XMETHOD(card_init, xbus, xpd) < 0)
goto err;
// Turn off all channels
- CALL_XMETHOD(CHAN_ENABLE, xbus, xpd, ~0, 0);
+ CALL_XMETHOD(XPD_STATE, xbus, xpd, 0);
xpd->card_present = 1;
// Turn on all channels
- CALL_XMETHOD(CHAN_ENABLE, xbus, xpd, ALL_LINES, 1);
+ CALL_XMETHOD(XPD_STATE, xbus, xpd, 1);
if(zap_autoreg)
zaptel_register_xpd(xpd);
@@ -389,6 +390,7 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo
(xpd == sync_master) ? "SYNC MASTER" : "SYNC SLAVE",
xpd->timer_count, xpd->span.mainttimer
);
+ len += sprintf(page + len, "Address: U=%d S=%d\n\n", xpd->addr.unit, xpd->addr.subunit);
len += sprintf(page + len, "STATES:");
len += sprintf(page + len, "\n\t%-17s: ", "output_relays");
for_each_line(xpd, i) {
@@ -424,6 +426,7 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo
}
#if 1
if(SPAN_REGISTERED(xpd)) {
+ len += sprintf(page + len, "\nzaptel state: %s RUNNING\n", (xpd->span.flags & ZT_FLAG_RUNNING)?"IS":"IS NOT");
len += sprintf(page + len, "\nPCM:\n | [readchunk] | [writechunk] | delay");
for_each_line(xpd, i) {
struct zt_chan *chans = xpd->span.chans;
@@ -437,7 +440,9 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo
continue;
if(IS_SET(xpd->digital_inputs, i))
continue;
-#if 1
+ if(IS_SET(xpd->digital_signalling, i))
+ continue;
+#if 0
rp = chans[i].readchunk;
wp = chans[i].writechunk;
#else
@@ -700,8 +705,9 @@ int proc_sync_read(char *page, char **start, off_t off, int count, int *eof, voi
xpp_timer_rate = 0;
now = jiffies;
if(now - xpp_last_jiffies > 0) {
- xpp_timer_rate = ((xpp_timer_count % SAMPLE_TICKS) * 1000) / (now - xpp_last_jiffies);
- len += sprintf(page + len, "tick rate: %4d/second (average over %d seconds)\n", xpp_timer_rate, SAMPLE_TICKS/HZ);
+ unsigned long delta = (now - xpp_last_jiffies);
+ xpp_timer_rate = (xpp_timer_count % SAMPLE_TICKS) * HZ / delta;
+ len += sprintf(page + len, "tick rate: %4d/second (SAMPLE_TICKS=%d)\n", xpp_timer_rate, SAMPLE_TICKS);
}
if (len <= off+count)
*eof = 1;
@@ -893,8 +899,10 @@ static void xpp_transmitprep(xpd_t *xpd)
int channels = xpd->channels;
struct zt_chan *chans = xpd->span.chans;
unsigned long flags;
+ bool digital_telephony;
spin_lock_irqsave(&xpd->lock, flags);
+ digital_telephony = (xpd->type == XPD_TYPE_BRI_NT) || (xpd->type == XPD_TYPE_BRI_TE);
// if((xpd->timer_count % PREP_REPORT_RATE) < 10)
// DBG("%d\n", xpd->timer_count);
@@ -912,7 +920,13 @@ static void xpp_transmitprep(xpd_t *xpd)
zt_transmit(&xpd->span);
spin_lock_irqsave(&xpd->lock, flags);
- for (i = 0; i < channels; i++) {
+ for (i = 0; i < channels; i++, w += ZT_CHUNKSIZE) {
+ /*
+ * We don't copy signalling buffers (they may be
+ * longer than ZT_CHUNKSIZE).
+ */
+ if(IS_SET(xpd->digital_signalling, i))
+ continue;
if (xpd->delay_until_dialtone[i] > 0) {
xpd->delay_until_dialtone[i]--;
if (xpd->delay_until_dialtone[i] <= 0) {
@@ -920,11 +934,12 @@ static void xpp_transmitprep(xpd_t *xpd)
wake_up_interruptible(&xpd->txstateq[i]);
}
}
- if(IS_SET(xpd->offhook, i) || IS_SET(xpd->cid_on, i)) {
+ if(IS_SET(xpd->offhook, i) || IS_SET(xpd->cid_on, i) || digital_telephony) {
+
memcpy((u_char *)w, chans[i].writechunk, ZT_CHUNKSIZE);
- // fill_beep((u_char *)w, 5);
+ // fill_beep((u_char *)w, xpd->addr.subunit, 2);
+ // memset((u_char *)w, pcmtx[xpd->addr.subunit % 4], ZT_CHUNKSIZE);
}
- w += ZT_CHUNKSIZE;
}
// if(xpd->offhook != 0 || sync_master != xpd) {
ret = CALL_XMETHOD(PCM_WRITE, xpd->xbus, xpd, xpd->offhook | xpd->cid_on, writechunk);
@@ -935,21 +950,30 @@ static void xpp_transmitprep(xpd_t *xpd)
spin_unlock_irqrestore(&xpd->lock, flags);
}
-void fill_beep(u_char *buf, int duration)
+void fill_beep(u_char *buf, int num, int duration)
{
- int which = (jiffies/(duration*HZ)) & 0x3;
+ bool alternate = (duration) ? (jiffies/(duration*HZ)) & 0x1 : 0;
+ int which;
+ u_char *snd;
/*
* debug tones
*/
static u_char beep[] = {
-// 0x7F, 0xBE, 0xD8, 0xBE, 0x80, 0x41, 0x24, 0x41, /* Dima */
-// 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, /* silence */
-// 0x67, 0x90, 0x89, 0x90, 0xFF, 0x10, 0x09, 0x10, /* Izzy */
-// 0x67, 0xCD, 0xC5, 0xCD, 0xFF, 0x49, 0x41, 0x49, /* Dima 2 */
+ 0x7F, 0xBE, 0xD8, 0xBE, 0x80, 0x41, 0x24, 0x41, /* Dima */
+ 0x67, 0x90, 0x89, 0x90, 0xFF, 0x10, 0x09, 0x10, /* Izzy */
+ };
+ static u_char beep_alt[] = {
0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, /* silence */
};
- memcpy(buf, &beep[(which*8) % ARRAY_SIZE(beep)], ZT_CHUNKSIZE);
+ if(alternate) {
+ which = num % ARRAY_SIZE(beep_alt);
+ snd = &beep_alt[which];
+ } else {
+ which = num % ARRAY_SIZE(beep);
+ snd = &beep[which];
+ }
+ memcpy(buf, snd, ZT_CHUNKSIZE);
}
#ifdef XPP_EC_CHUNK
@@ -958,9 +982,9 @@ void fill_beep(u_char *buf, int duration)
*/
static inline void xpp_ec_chunk(struct zt_chan *chan, unsigned char *rxchunk, const unsigned char *txchunk)
{
- short rxlin;
- int x;
- unsigned long flags;
+ int16_t rxlin;
+ int x;
+ unsigned long flags;
/* Perform echo cancellation on a chunk if necessary */
if (!chan->ec)
@@ -983,8 +1007,10 @@ static void xpp_receiveprep(xpd_t *xpd)
int channels = xpd->channels;
struct zt_chan *chans = xpd->span.chans;
unsigned long flags;
+ bool digital_telephony;
spin_lock_irqsave(&xpd->lock, flags);
+ digital_telephony = (xpd->type == XPD_TYPE_BRI_NT) || (xpd->type == XPD_TYPE_BRI_TE);
// if((xpd->timer_count % PREP_REPORT_RATE) == 0)
// DBG("%d\n", xpd->timer_count);
@@ -995,20 +1021,27 @@ static void xpp_receiveprep(xpd_t *xpd)
readchunk = xpd->readchunk + ZT_CHUNKSIZE * CHANNELS_PERXPD;
}
- for (i = 0; i < channels; i++) {
- if(IS_SET(xpd->offhook, i) || IS_SET(xpd->cid_on, i)) {
+ for (i = 0; i < channels; i++, readchunk += ZT_CHUNKSIZE) {
+ /*
+ * We don't copy signalling buffers (they may be
+ * longer than ZT_CHUNKSIZE).
+ */
+ if(IS_SET(xpd->digital_signalling, i))
+ continue;
+ if(IS_SET(xpd->offhook, i) || IS_SET(xpd->cid_on, i) || digital_telephony) {
// memset((u_char *)readchunk, 0x5A, ZT_CHUNKSIZE); // DEBUG
- // fill_beep((u_char *)readchunk, 1); // DEBUG: BEEP
+ // fill_beep((u_char *)readchunk, 1, 1); // DEBUG: BEEP
memcpy(chans[i].readchunk, (u_char *)readchunk, ZT_CHUNKSIZE);
} else {
memset(chans[i].readchunk, 0x7F, ZT_CHUNKSIZE); // SILENCE
}
- readchunk += ZT_CHUNKSIZE;
}
#if WITH_ECHO_SUPPRESSION
/* FIXME: need to Echo cancel double buffered data */
for (i = 0;i < xpd->span.channels; i++) {
+ if(IS_SET(xpd->digital_signalling, i)) /* Don't echo cancel PRI/BRI D-chans */
+ continue;
#ifdef XPP_EC_CHUNK
xpp_ec_chunk(&chans[i], chans[i].readchunk, xpd->ec_chunk2[i]);
#else
@@ -1058,12 +1091,15 @@ int xpp_open(struct zt_chan *chan)
{
xpd_t *xpd = chan->pvt;
xbus_t *xbus = xpd->xbus;
+ int pos = chan->chanpos - 1;
unsigned long flags;
spin_lock_irqsave(&xbus->lock, flags);
xbus->open_counter++;
atomic_inc(&xpd->open_counter);
- DBG("chan=%d (open_counter=%d)\n", chan->chanpos, xbus->open_counter);
+ if(IS_SET(xpd->digital_signalling, pos)) /* D-chan offhook */
+ BIT_SET(xpd->offhook, pos);
+ DBG("chan=%d (open_counter=%d)\n", pos, xbus->open_counter);
spin_unlock_irqrestore(&xbus->lock, flags);
return 0;
}
@@ -1072,6 +1108,7 @@ int xpp_close(struct zt_chan *chan)
{
xpd_t *xpd = chan->pvt;
xbus_t *xbus = xpd->xbus;
+ int pos = chan->chanpos - 1;
unsigned long flags;
bool should_remove = 0;
@@ -1079,13 +1116,21 @@ int xpp_close(struct zt_chan *chan)
xbus->open_counter--;
atomic_dec(&xpd->open_counter);
if(xpd->direction == TO_PHONE) { /* Hangup phone */
- xpd->idletxhookstate[chan->chanpos - 1] = FXS_LINE_ENABLED;
+ xpd->idletxhookstate[pos] = FXS_LINE_ENABLED;
}
if (!xbus->hardware_exists && xbus->open_counter == 0)
should_remove = 1;
+ if(IS_SET(xpd->digital_signalling, pos)) /* D-chan onhook */
+ BIT_CLR(xpd->offhook, pos);
spin_unlock_irqrestore(&xbus->lock, flags);
-
- DBG("chan=%d (open_counter=%d, should_remove=%d)\n", chan->chanpos, xbus->open_counter, should_remove);
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ /* Clear D-Channel pending data */
+ chan->bytes2receive = 0;
+ chan->eofrx = 0;
+ chan->bytes2transmit = 0;
+ chan->eoftx = 0;
+#endif
+ DBG("chan=%d (open_counter=%d, should_remove=%d)\n", pos, xbus->open_counter, should_remove);
if(should_remove) {
DBG("Going to remove: %s\n", xbus->busname);
xbus_remove(xbus);
@@ -1353,7 +1398,7 @@ static int zaptel_register_xpd(xpd_t *xpd)
DBG("Registering span of %s.\n", xpd->xpdname);
xpd->xops->card_zaptel_preregistration(xpd, 1);
- if(zt_register(&xpd->span, 1)) {
+ if(zt_register(&xpd->span, prefmaster)) {
xbus_t *xbus = xpd->xbus;
ERR("%s/%s: Failed to zt_register span\n", xbus->busname, xpd->xpdname);
return -ENODEV;
@@ -1397,8 +1442,8 @@ int __init xpp_zap_init(void)
int ret;
struct proc_dir_entry *ent;
- INFO("%s revision %s MAX_XPDS=%d\n", THIS_MODULE->name, ZAPTEL_VERSION,
- MAX_XPDS);
+ INFO("%s revision %s MAX_XPDS=%d (%d*%d)\n", THIS_MODULE->name, ZAPTEL_VERSION,
+ MAX_XPDS, MAX_UNIT, MAX_SUBUNIT);
#if WITH_ECHO_SUPPRESSION
INFO("FEATURE: %s (with ECHO_SUPPRESSION)\n", THIS_MODULE->name);
#else
@@ -1409,6 +1454,11 @@ int __init xpp_zap_init(void)
#else
INFO("FEATURE: %s (without XPP_EC_CHUNK)\n", THIS_MODULE->name);
#endif
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ INFO("FEATURE: %s (with BRISTUFF support)\n", THIS_MODULE->name);
+#else
+ INFO("FEATURE: %s (without BRISTUFF support)\n", THIS_MODULE->name);
+#endif
#ifdef CONFIG_PROC_FS
xpp_proc_toplevel = proc_mkdir(PROC_DIR, NULL);
diff --git a/xpp/xpp_zap.h b/xpp/xpp_zap.h
index 39608c0..4cd3a8b 100644
--- a/xpp/xpp_zap.h
+++ b/xpp/xpp_zap.h
@@ -34,7 +34,7 @@ void xpd_remove(xpd_t *xpd);
void update_xpd_status(xpd_t *xpd, int alarm_flag);
void update_zap_ring(xpd_t *xpd, int pos, bool on);
void update_line_status(xpd_t *xpd, int pos, bool good);
-void fill_beep(u_char *buf, int duration);
+void fill_beep(u_char *buf, int num, int duration);
void xpp_tick(unsigned long param);
int xpp_open(struct zt_chan *chan);
int xpp_close(struct zt_chan *chan);
diff --git a/xpp/xproto.c b/xpp/xproto.c
index ff91c58..ebd9bba 100644
--- a/xpp/xproto.c
+++ b/xpp/xproto.c
@@ -26,6 +26,7 @@
#include "xbus-core.h"
#include "zap_debug.h"
#include <linux/module.h>
+#include <linux/delay.h>
static const char rcsid[] = "$Id$";
@@ -40,19 +41,19 @@ static const xproto_table_t *xprotocol_tables[XPD_TYPE_NOMODULE];
bool valid_xpd_addr(const xpd_addr_t *addr)
{
- return ((addr->subunit & ~0x1) == 0) && ((addr->unit & ~0x3) == 0);
+ return ((addr->subunit & ~BITMASK(SUBUNIT_BITS)) == 0) && ((addr->unit & ~BITMASK(UNIT_BITS)) == 0);
}
int xpd_addr2num(const xpd_addr_t *addr)
{
BUG_ON(!valid_xpd_addr(addr));
- return addr->unit + addr->subunit * MAX_UNIT;
+ return addr->unit | (addr->subunit << UNIT_BITS);
}
void xpd_set_addr(xpd_addr_t *addr, int xpd_num)
{
- addr->unit = xpd_num % MAX_UNIT;
- addr->subunit = xpd_num / MAX_UNIT;
+ addr->unit = xpd_num & BITMASK(UNIT_BITS);
+ addr->subunit = (xpd_num >> UNIT_BITS) & BITMASK(SUBUNIT_BITS);
}
@@ -224,13 +225,15 @@ out:
void dump_packet(const char *msg, xpacket_t *packet, bool print_dbg)
{
byte op = packet->content.opcode;
+ byte *addr = (byte *)&packet->content.addr;
if(!print_dbg)
return;
- DBG("%s: U=0x%1X S=0x%1X OP=0x%02X LEN=%d\n",
+ DBG("%s: XPD=%1X-%1X (0x%X) OP=0x%02X LEN=%d\n",
msg,
packet->content.addr.unit,
packet->content.addr.subunit,
+ *addr,
op,
(byte)packet->datalen);
#if VERBOSE_DEBUG
@@ -258,6 +261,36 @@ void dump_packet(const char *msg, xpacket_t *packet, bool print_dbg)
#endif
}
+void dump_reg_cmd(const char msg[], reg_cmd_t *regcmd)
+{
+ char action;
+ char mode;
+ byte chipsel;
+ byte regnum;
+ byte data_low;
+ byte data_high;
+
+ if(regcmd->bytes != sizeof(*regcmd) - 1) { /* The size byte is not included */
+ NOTICE("%s: Wrong size: regcmd->bytes = %d\n", __FUNCTION__, regcmd->bytes);
+ return;
+ }
+ action = (REG_FIELD(regcmd, chipsel) & 0x80) ? 'R' : 'W';
+ chipsel = REG_FIELD(regcmd, chipsel) & ~0x80;
+ if(REG_FIELD(regcmd, regnum) == 0x1E) {
+ mode = 'I';
+ regnum = REG_FIELD(regcmd, subreg);
+ data_low = REG_FIELD(regcmd, data_low);
+ data_high = REG_FIELD(regcmd, data_high);
+ } else {
+ mode = 'D';
+ regnum = REG_FIELD(regcmd, regnum);
+ data_low = REG_FIELD(regcmd, data_low);
+ data_high = 0;
+ }
+ DBG("%d %c%c %02X %02X %02X # m=%d eof=%d\n", chipsel, action, mode, regnum,
+ data_low, data_high, regcmd->multibyte, regcmd->eoframe);
+}
+
const char *xproto_name(xpd_type_t xpd_type)
{
const xproto_table_t *proto_table;
@@ -302,7 +335,7 @@ int xproto_register(const xproto_table_t *proto_table)
// CHECK_XOP(card_ioctl); // optional method -- call after testing
CHECK_XOP(SYNC_SOURCE);
CHECK_XOP(PCM_WRITE);
- CHECK_XOP(CHAN_ENABLE);
+ CHECK_XOP(XPD_STATE);
CHECK_XOP(CHAN_CID);
CHECK_XOP(RING);
CHECK_XOP(RELAY_OUT);
@@ -330,6 +363,7 @@ void xproto_unregister(const xproto_table_t *proto_table)
}
EXPORT_SYMBOL(dump_packet);
+EXPORT_SYMBOL(dump_reg_cmd);
EXPORT_SYMBOL(packet_receive);
EXPORT_SYMBOL(valid_xpd_addr);
EXPORT_SYMBOL(xpd_addr2num);
diff --git a/xpp/xproto.h b/xpp/xproto.h
index 7255e09..377c06e 100644
--- a/xpp/xproto.h
+++ b/xpp/xproto.h
@@ -26,6 +26,7 @@
#ifdef __KERNEL__
#include <linux/list.h>
+#include <linux/proc_fs.h>
#include <zaptel.h>
#endif
@@ -38,6 +39,8 @@
*/
#define XPD_TYPE_FXS 3 // TO_PHONE
#define XPD_TYPE_FXO 4 // TO_PSTN
+#define XPD_TYPE_BRI_TE 6 // TO_PSTN
+#define XPD_TYPE_BRI_NT 7 // TO_PHONE
#define XPD_TYPE_NOMODULE 15
typedef byte xpd_type_t;
@@ -52,6 +55,7 @@ typedef byte xpd_type_t;
typedef struct xpd_addr {
byte unit:UNIT_BITS;
byte subunit:SUBUNIT_BITS;
+ byte reserved:(8-UNIT_BITS-SUBUNIT_BITS);
} PACKED xpd_addr_t;
bool valid_xpd_addr(const xpd_addr_t *addr);
@@ -100,15 +104,16 @@ void xpd_set_addr(xpd_addr_t *addr, int xpd_num);
#define PACKET_LEN(p) \
((p)->datalen + sizeof(xpd_addr_t) + 1)
-#define XENTRY(card,op) \
- [ XPROTO_NAME(card,op) ] = { \
- .handler = XPROTO_HANDLER(card,op), \
- .datalen = RPACKET_DATALEN(card,op), \
+#define XENTRY(prototab,module,op) \
+ [ XPROTO_NAME(module,op) ] = { \
+ .handler = XPROTO_HANDLER(module,op), \
+ .datalen = RPACKET_DATALEN(module,op), \
.name = #op, \
- .table = &PROTO_TABLE(card) \
+ .table = &PROTO_TABLE(prototab) \
}
+
#define XPACKET_INIT(p, card, op) \
do { \
p->content.opcode = XPROTO_NAME(card,op); \
@@ -124,6 +129,57 @@ void xpd_set_addr(xpd_addr_t *addr, int xpd_num);
xpd_set_addr(&p->content.addr, to); \
} while(0);
+/*--------------------------- register handling --------------------------------*/
+/*
+ * After the opcode, there are always:
+ * * A size (in bytes) of the rest. Only 6 bits are counted:
+ * - The MSB signifies a multibyte write (to BRI fifo)
+ * - The MSB-1 signifies end of frame to multibyte writes in BRI.
+ * A normal register command (not multibyte) than contains:
+ * * A channel selector byte:
+ * - ALL_CHANS (currently 31) is a broadcast request to set a
+ * register for all channels.
+ * - Smaller numbers (0-30) represent the addressed channel number.
+ * - The MSB signifies:
+ * 1 - register [R]ead request
+ * 0 - register [W]rite request
+ * * Register number
+ * * Subregister number -- 0 when there is no subregister
+ * * Data low
+ * * Data high -- 0 for single byte registers (direct registers)
+ * A multibyte register command than contains a sequence of bytes.
+ */
+
+#define MULTIBYTE_MAX_LEN 5 /* FPGA firmware limitation */
+
+typedef struct reg_cmd {
+ byte bytes:6;
+ byte eoframe:1; /* For BRI -- end of frame */
+ byte multibyte:1; /* For BRI -- fifo data */
+ union {
+ struct {
+ byte chipsel:CHAN_BITS; /* chip select */
+ byte reserved:1;
+ byte do_subreg:1;
+ byte read_request:1;
+ byte regnum;
+ byte subreg;
+ byte data_low;
+ byte data_high;
+ } PACKED r;
+ /* For Write-Multibyte commands in BRI */
+ struct {
+ byte xdata[MULTIBYTE_MAX_LEN];
+ } PACKED d;
+ } PACKED alt;
+} PACKED reg_cmd_t;
+
+/* Shortcut access macros */
+#define REG_FIELD(regptr,member) ((regptr)->alt.r.member)
+#define REG_XDATA(regptr) ((regptr)->alt.d.xdata)
+
+/*--------------------------- protocol tables ----------------------------------*/
+
typedef struct xproto_entry xproto_entry_t;
typedef struct xproto_table xproto_table_t;
@@ -157,9 +213,9 @@ struct xops {
int (*SYNC_SOURCE)(xbus_t *xbus, xpd_t *xpd, bool setit, bool is_master);
int (*PCM_WRITE)(xbus_t *xbus, xpd_t *xpd, xpp_line_t offhook, volatile byte *buf);
- int (*CHAN_ENABLE)(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, bool on);
- int (*CHAN_CID)(xbus_t *xbus, xpd_t *xpd, int pos);
- int (*RING)(xbus_t *xbus, xpd_t *xpd, int pos, bool on);
+ int (*XPD_STATE)(xbus_t *xbus, xpd_t *xpd, bool on);
+ int (*CHAN_CID)(xbus_t *xbus, xpd_t *xpd, lineno_t chan);
+ int (*RING)(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on);
int (*RELAY_OUT)(xbus_t *xbus, xpd_t *xpd, byte which, bool on);
};
@@ -177,7 +233,7 @@ struct xproto_table {
xpd_type_t type;
const char *name;
bool (*packet_is_valid)(xpacket_t *pack);
- void (*packet_dump)(xpacket_t *pack);
+ void (*packet_dump)(const char *msg, xpacket_t *pack);
};
#include "card_global.h"
@@ -188,12 +244,15 @@ enum opcodes {
XPROTO_NAME(GLOBAL, NULL_REPLY) = 0xFE,
XPROTO_NAME(GLOBAL, DESC_REQ) = 0x04,
XPROTO_NAME(GLOBAL, DEV_DESC) = 0x05,
+ XPROTO_NAME(GLOBAL, REGISTER_REQUEST) = 0x0F,
/**/
XPROTO_NAME(GLOBAL, PCM_WRITE) = 0x11,
XPROTO_NAME(GLOBAL, PCM_READ) = 0x12,
/**/
XPROTO_NAME(GLOBAL, SYNC_SOURCE) = 0x19,
XPROTO_NAME(GLOBAL, SYNC_REPLY) = 0x1A,
+/**/
+ XPROTO_NAME(GLOBAL, ERROR_CODE) = 0x22,
};
@@ -209,14 +268,13 @@ struct xpacket_raw {
MEMBER(GLOBAL, PCM_WRITE);
MEMBER(GLOBAL, PCM_READ);
MEMBER(GLOBAL, SYNC_REPLY);
+ MEMBER(GLOBAL, ERROR_CODE);
MEMBER(FXS, SIG_CHANGED);
- MEMBER(FXS, SLIC_REPLY);
- MEMBER(FXS, SLIC_WRITE);
+ MEMBER(FXS, REGISTER_REPLY);
MEMBER(FXO, SIG_CHANGED);
MEMBER(FXO, DAA_REPLY);
- MEMBER(FXO, DAA_WRITE);
byte data[0];
};
@@ -230,6 +288,7 @@ struct xpacket {
};
void dump_packet(const char *msg, xpacket_t *packet, bool print_dbg);
+void dump_reg_cmd(const char msg[], reg_cmd_t *regcmd);
int packet_receive(xbus_t *xbus, xpacket_t *pack);
int xproto_register(const xproto_table_t *proto_table);
void xproto_unregister(const xproto_table_t *proto_table);