diff options
author | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-11-28 13:36:03 +0000 |
---|---|---|
committer | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-11-28 13:36:03 +0000 |
commit | d8bdfe8d82cf7c57b2a4061fc03b6e0a863064e1 (patch) | |
tree | b67e786e441a4b6951e05552d533a924d5dacccf | |
parent | 6ecdbe426f0630c1ffb85e5e93758ae3e53aba22 (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/branches/1.2@1648 5390a7c7-147a-4af0-8ec9-7488f05a26cb
39 files changed, 2889 insertions, 2145 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, ®_type, ®_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, ®_type, ®_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(®cmd, chipsel) = chipsel; + REG_FIELD(®cmd, 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(®cmd, regnum) = reg_num; + REG_FIELD(®cmd, 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(®cmd, data_low) = data_low; + REG_FIELD(®cmd, data_high) = 0; + REG_FIELD(®cmd, 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", ®cmd); + ret = DAA_DIRECT_REQUEST(xpd->xbus, xpd, REG_FIELD(®cmd, chipsel), writing, REG_FIELD(®cmd, regnum), REG_FIELD(®cmd, 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, ®_type, ®_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, ®_type, ®_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(®cmd, 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(®cmd, do_subreg) = 1; + REG_FIELD(®cmd, regnum) = 0x1E; // FIXME: card dependent... + REG_FIELD(®cmd, subreg) = reg_num; + break; + case 'D': + REG_FIELD(®cmd, do_subreg) = 0; + REG_FIELD(®cmd, regnum) = reg_num; + REG_FIELD(®cmd, 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(®cmd, data_low) = data_low; + REG_FIELD(®cmd, data_high) = data_high; + REG_FIELD(®cmd, 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", ®cmd); + ret = CALL_PROTO(FXS, REGISTER_REQUEST, xpd->xbus, xpd, + REG_FIELD(®cmd, chipsel), + writing, + REG_FIELD(®cmd, do_subreg), + REG_FIELD(®cmd, regnum), + REG_FIELD(®cmd, subreg), + REG_FIELD(®cmd, data_low), + REG_FIELD(®cmd, 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/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 */ @@ -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); |