summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2009-05-27 10:01:24 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2009-05-27 10:01:24 +0000
commit18c6813f2c788b603dab363b9138d65d24252167 (patch)
tree92402484268f2bc1d5e4e55f7321b9204ad47c5f
parent2a73224819e867eaf56371d6055e2ca4d36396b6 (diff)
Big dump of newer xpp code.
For finer details and separate commits, you are advised to look into the commit log of dahdi-{linux,tools}. xpp.r7150 * 116x Astribanks: - Support for the TwinStar capability and for FXO and (BRI|PRI) on same device. - New control protocol ("MPP"). - astribank_hextool - a low-level firmware loading tool instead of fpga_load . - astribank_tool - Other MPP activities . - Can still reset (but just that) through older protocol. - astribank_hexload is required for loading FPGA firmware for USB_FW.hex rev > 6885. - USB_FW rev. 7071 . - More modular FPGA firmware (1161 only). - FPGA_1161.hex rev. 7131. PIC_TYPE_* rev. 7107. - software-settings of some capabilities with astribank_allow . * XPP: - init_card_* script are less verbose. - Reduced rate of "Is a DAHDI sync master" message. - Replace member bus_id with dev_name() and set_dev_name() for building with 2.6.30. - Conditionally remove 'owner' property of procfs was dropped in 2.6.30. - astribank_hook now enabled by default. - Has an optional hook for TwinStar. * BRI: - hardhdlc support: The bri_dchan patch is no longer needed. - If bri_dchan patch applied: old code is used, and "dchan" is used. - If not: new code and "hardhdlc" is used. - zapconf will generate the right configuration, depending on the new sysfs driver attribute bri_hardhdlc, but default to "dchan" as before if not explicitly told. - Bugfix: explicitly turn off leds on startup. * FXS: - Initialization and calibration fixes. - Notify the user just one about wrong VMWI config * Dahdi-perl: - Fix detection of empty slots in wctdm. - Fix working with ethmf's extra file in /proc/zaptel - Improved detection of Rhino cards. - dahdi_genconf's generated text better explains files are generated. - /etc/xpp_order - allow specifiying an explicit order for Astribanks to register with Zaptel. - Dahdi::Xpp::Mpp - A wrapper around astribank_tool . * dahdi.init: - A separate waitfor_xpds script. May now have a wait-loop in some cases. - xpp_sync needs to only be called after dahdi_cfg . (for the PRI module). git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@4641 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rw-r--r--kernel/xpp/.version2
-rw-r--r--kernel/xpp/Changelog_xpp50
-rw-r--r--kernel/xpp/Kbuild41
-rw-r--r--kernel/xpp/README.Astribank189
-rw-r--r--kernel/xpp/card_bri.c302
-rw-r--r--kernel/xpp/card_fxo.c7
-rw-r--r--kernel/xpp/card_fxs.c38
-rw-r--r--kernel/xpp/card_global.c5
-rw-r--r--kernel/xpp/card_pri.c9
-rw-r--r--kernel/xpp/firmwares/FPGA_1161.hex1034
-rw-r--r--kernel/xpp/firmwares/PIC_TYPE_1.hex467
-rw-r--r--kernel/xpp/firmwares/PIC_TYPE_2.hex339
-rw-r--r--kernel/xpp/firmwares/PIC_TYPE_3.hex374
-rw-r--r--kernel/xpp/firmwares/PIC_TYPE_4.hex316
-rw-r--r--kernel/xpp/firmwares/USB_FW.hex780
-rwxr-xr-xkernel/xpp/init_card_1_30280
-rwxr-xr-xkernel/xpp/init_card_2_3037
-rwxr-xr-xkernel/xpp/init_card_3_3026
-rwxr-xr-xkernel/xpp/init_card_4_3018
-rw-r--r--kernel/xpp/utils/Makefile24
-rw-r--r--kernel/xpp/utils/astribank_allow.c378
-rw-r--r--kernel/xpp/utils/astribank_hexload.866
-rw-r--r--kernel/xpp/utils/astribank_hexload.c201
-rw-r--r--kernel/xpp/utils/astribank_tool.879
-rw-r--r--kernel/xpp/utils/astribank_tool.c202
-rw-r--r--kernel/xpp/utils/astribank_usb.c536
-rw-r--r--kernel/xpp/utils/astribank_usb.h102
-rw-r--r--kernel/xpp/utils/debug.c53
-rw-r--r--kernel/xpp/utils/debug.h46
-rw-r--r--kernel/xpp/utils/genconf_parameters39
-rw-r--r--kernel/xpp/utils/hexfile.c3
-rw-r--r--kernel/xpp/utils/hexfile.h46
-rwxr-xr-xkernel/xpp/utils/lszaptel2
-rw-r--r--kernel/xpp/utils/mpp.h324
-rw-r--r--kernel/xpp/utils/mpp_funcs.c1028
-rw-r--r--kernel/xpp/utils/mpp_funcs.h78
-rw-r--r--kernel/xpp/utils/pic_loader.c275
-rw-r--r--kernel/xpp/utils/pic_loader.h46
-rwxr-xr-xkernel/xpp/utils/twinstar160
-rwxr-xr-xkernel/xpp/utils/twinstar_hook132
-rw-r--r--kernel/xpp/utils/twinstar_setup155
-rw-r--r--kernel/xpp/utils/xpp.rules2
-rwxr-xr-xkernel/xpp/utils/xpp_fxloader164
-rwxr-xr-xkernel/xpp/utils/xpp_sync9
-rwxr-xr-xkernel/xpp/utils/zapconf2
-rwxr-xr-xkernel/xpp/utils/zaptel_drivers8
-rwxr-xr-xkernel/xpp/utils/zaptel_hardware52
-rw-r--r--kernel/xpp/utils/zconf/Zaptel.pm1
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Chans.pm10
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Config/Gen/Unicall.pm4
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Config/Gen/Users.pm2
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Config/Gen/Xpporder.pm142
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zapata.pm4
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zaptel.pm47
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Config/Params.pm2
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Hardware.pm95
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Hardware/PCI.pm12
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Hardware/USB.pm88
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Span.pm5
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Xpp.pm93
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Xpp/Mpp.pm221
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm31
-rw-r--r--kernel/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm24
-rwxr-xr-xkernel/xpp/utils/zt_registration34
-rw-r--r--kernel/xpp/xbus-core.c78
-rw-r--r--kernel/xpp/xbus-core.h8
-rw-r--r--kernel/xpp/xbus-pcm.c6
-rw-r--r--kernel/xpp/xbus-sysfs.c10
-rw-r--r--kernel/xpp/xdefs.h2
-rw-r--r--kernel/xpp/xpd.h2
-rw-r--r--kernel/xpp/xpp.conf7
-rw-r--r--kernel/xpp/xpp_usb.c4
-rw-r--r--kernel/xpp/xpp_zap.c8
-rw-r--r--kernel/xpp/xpp_zap.h2
-rw-r--r--kernel/xpp/xproto.c6
-rw-r--r--kernel/xpp/xproto.h7
-rw-r--r--zaptel.init5
77 files changed, 8699 insertions, 787 deletions
diff --git a/kernel/xpp/.version b/kernel/xpp/.version
index c1d4f47..e8c4a78 100644
--- a/kernel/xpp/.version
+++ b/kernel/xpp/.version
@@ -1 +1 @@
-branch-rel-6839-r6908
+trunk-r7150
diff --git a/kernel/xpp/Changelog_xpp b/kernel/xpp/Changelog_xpp
index 7ca130d..4e743c3 100644
--- a/kernel/xpp/Changelog_xpp
+++ b/kernel/xpp/Changelog_xpp
@@ -1,3 +1,51 @@
+Wed May 27 2009 Oron Peled <oron@actcom.co.il> - xpp.r7150
+ * 116x Astribanks:
+ - Support for the TwinStar capability and for FXO and (BRI|PRI) on
+ same device.
+ - New control protocol ("MPP").
+ - astribank_hextool - a low-level firmware loading tool instead of
+ fpga_load .
+ - astribank_tool - Other MPP activities .
+ - Can still reset (but just that) through older protocol.
+ - astribank_hexload is required for loading FPGA firmware for USB_FW.hex
+ rev > 6885.
+ - USB_FW rev. 7071 .
+ - More modular FPGA firmware (1161 only).
+ - FPGA_1161.hex rev. 7131. PIC_TYPE_* rev. 7107.
+ - software-settings of some capabilities with astribank_allow .
+ * XPP:
+ - init_card_* script are less verbose.
+ - Reduced rate of "Is a DAHDI sync master" message.
+ - Replace member bus_id with dev_name() and set_dev_name() for
+ building with 2.6.30.
+ - Conditionally remove 'owner' property of procfs was dropped in 2.6.30.
+ - astribank_hook now enabled by default.
+ - Has an optional hook for TwinStar.
+ * BRI:
+ - hardhdlc support: The bri_dchan patch is no longer needed.
+ - If bri_dchan patch applied: old code is used, and "dchan" is used.
+ - If not: new code and "hardhdlc" is used.
+ - zapconf will generate the right configuration, depending on the new
+ sysfs driver attribute bri_hardhdlc, but default to "dchan" as
+ before if not explicitly told.
+ - Bugfix: explicitly turn off leds on startup.
+ * FXS:
+ - Initialization and calibration fixes.
+ - Notify the user just one about wrong VMWI config
+ * Dahdi-perl:
+ - Fix detection of empty slots in wctdm.
+ - Fix working with ethmf's extra file in /proc/zaptel
+ - Improved detection of Rhino cards.
+ - dahdi_genconf's generated text better explains files are generated.
+ - /etc/xpp_order - allow specifiying an explicit order for
+ Astribanks to register with Zaptel.
+ - Dahdi::Xpp::Mpp - A wrapper around astribank_tool .
+ * dahdi.init:
+ - A separate waitfor_xpds script. May now have a wait-loop in
+ some cases.
+ - xpp_sync needs to only be called after dahdi_cfg .
+ (for the PRI module).
+
Sun Mar 1 2009 Oron Peled <oron@actcom.co.il> - xpp.r6795
* Fix cases where the command_queue overflowed during initialization.
- Also add a 'command_queue_length' parameter to xpp.ko
@@ -21,9 +69,9 @@ Sun Mar 1 2009 Oron Peled <oron@actcom.co.il> - xpp.r6795
For sites that get non-standard power-denial signals from central
office on offhook.
- Don't hangup on power-denial, just notify Dahdi and wait for
+ Asterisk's desicion.
- Fix caller-id detection for the case central office sends it before
first ring without any indication before.
- Asterisk's desicion.
* New USB_FW.hex (xpp.r6885): handles some firmware rewriting races.
Mon, Dec 8 2008 Oron Peled <oron@actcom.co.il> - xpp.r6430
diff --git a/kernel/xpp/Kbuild b/kernel/xpp/Kbuild
index 54ec975..a8c4eda 100644
--- a/kernel/xpp/Kbuild
+++ b/kernel/xpp/Kbuild
@@ -13,11 +13,8 @@ EXTRA_CFLAGS = $(XPP_LOCAL_CFLAGS) \
-g # -DOLD_PROC
#
-ifneq (,$(shell grep -w echo_can_state_t $(ZAP_KERNEL)/zaptel.h))
-EXTRA_CFLAGS += -DZAPTEL_EC_TYPEDEF
-endif
-obj-m += xpp.o xpd_fxs.o xpd_fxo.o xpd_pri.o
+obj-m += xpp.o xpd_fxs.o xpd_fxo.o xpd_bri.o xpd_pri.o
HAS_BRISTUFF := $(shell grep -c '^[[:space:]]*\#[[:space:]]*define[[:space:]]\+CONFIG_ZAPATA_BRI_DCHANS\>' $(ZAP_KERNEL)/zconfig.h)
@@ -25,15 +22,12 @@ HAS_BRISTUFF := $(shell grep -c '^[[:space:]]*\#[[:space:]]*define[[:space:]]\+C
ifneq (,$(filter y m,$(CONFIG_USB)))
obj-m += xpp_usb.o
endif
-ifneq (0,$(HAS_BRISTUFF))
-obj-m += xpd_bri.o
-endif
-xpp-y += xbus-core.o xbus-sysfs.o xbus-pcm.o xframe_queue.o xpp_zap.o xproto.o card_global.o zap_debug.o
-xpd_fxs-y += card_fxs.o
-xpd_fxo-y += card_fxo.o
-xpd_bri-y += card_bri.o
-xpd_pri-y += card_pri.o
+xpp-objs += xbus-core.o xbus-sysfs.o xbus-pcm.o xframe_queue.o xpp_zap.o xproto.o card_global.o zap_debug.o
+xpd_fxs-objs += card_fxs.o
+xpd_fxo-objs += card_fxo.o
+xpd_bri-objs += card_bri.o
+xpd_pri-objs += card_pri.o
ifeq (y,$(PARPORT_DEBUG))
EXTRA_CFLAGS += -DDEBUG_SYNC_PARPORT
@@ -53,5 +47,28 @@ $(obj)/xpp_version.h: FORCE
fi
$(Q)rm -f $@.tmp
+# Validations:
+# - Syntactic verification of perl scripts
+# - Handle country table validation for init_card_2_*
+
+XPP_PROTOCOL_VERSION := $(shell grep XPP_PROTOCOL_VERSION $(src)/xproto.h | sed -e 's/^.*XPP_PROTOCOL_VERSION[ \t]*//')
+
+xpp_verifications = \
+ init_card_1_$(XPP_PROTOCOL_VERSION) \
+ init_card_2_$(XPP_PROTOCOL_VERSION) \
+ init_card_3_$(XPP_PROTOCOL_VERSION) \
+ init_card_4_$(XPP_PROTOCOL_VERSION)
+
+xpp_verified = $(foreach file, $(xpp_verifications), $(file).verified)
+
+
+always := $(xpp_verified)
+
+clean-files += $(xpp_verified)
+
+$(obj)/init_card_%_$(XPP_PROTOCOL_VERSION).verified: $(src)/init_card_%_$(XPP_PROTOCOL_VERSION)
+ @echo ' VERIFY $<'
+ $(Q)perl -c $< 2> $@ || (cat $@; rm -f $@; exit 1)
+
.PHONY: FORCE
FORCE:
diff --git a/kernel/xpp/README.Astribank b/kernel/xpp/README.Astribank
index 6fd0deb..435d78a 100644
--- a/kernel/xpp/README.Astribank
+++ b/kernel/xpp/README.Astribank
@@ -57,6 +57,11 @@ user space utilities, apart from the standard 'make; make install':
Patch for BRI
~~~~~~~~~~~~~
+(In latest SVN version of Zaptel this patch is no longer needed. Furthermore, it does
+not apply. The same directory has a newer patch that applies. This
+section is kept in the document for the time being for the benefit of
+those with older versions)
+
In order for the BRI module (xpd_bri.ko) to build, you still need an
external patch:
@@ -77,7 +82,7 @@ Installation Scenarios
~~~~~~~~~~~~~~~~~~~~~~
Below are some commented sequences of commands that can be used at some
common scenarios. Those scenarios begin only after you installed the
-software (Zaptel, asterisk, etc.).
+software (zaptel, asterisk, etc.).
New Installation Scenario
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -210,6 +215,69 @@ modules:
#fxs_skip_calib 1
-----------------------------------------------------------
+xpp_order: Explicitly order Astribanks
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+(This feature is available in latest Zaptel SVN)
+
+On a system with multiple Astribank you would normally want to guarantee
+that Astribanks are registered in the same order regardless of the order
+in which they are connected or detected. Assuming that you register them
+all at the same time. In order to do that, you should list the
+Astribanks explicitly under /etc/xpp_order .
+
+Astribanks that are listed there are registered first (according to the
+order of lines in the files). Astribanks not listed there are added
+last, and sorted by the 'USB connector' string.
+
+You can identify an Astribank in two ways:
+
+Label::
+ each Astribank (except some really old ones) has a label . This
+ identifies the actual Astribank box.
+
+Connector::
+ Identify the path the Astribank is connected through. E.g.: to what
+ USB port you connected it.
+
+Identifying an Astribank by the label seems simpler and more
+predictable. Though it may have some slightly surprising effects if
+replace one Astribank with another.
+
+The sample configuration file:
+-----------------------------------------------------------
+#
+# This is an optional configuration file for ordering
+# Zaptel registration.
+#
+# It is read from /etc/xpp_order. This location
+# may be overriden via the environment variable XPPORDER_CONF
+#
+# Lines may contain:
+# - The Astribank label (verbatim)
+# - The Astribank connector string (prefixed with @)
+# Ordering number of each listed Astribank is determined
+# by its position in this file.
+# Astribanks not listed in this file, get an ordering
+# number of 99 (last).
+#
+# Astribanks with same ordering number are sorted by their
+# connectors (to preserve legacy behaviour).
+#
+# Examples:
+#usb:1234
+#@usb-0000:06:02.2-2
+-----------------------------------------------------------
+
+
+In order to generate one that includes all the Astribanks in the system
+with the current order in which they are connected, use:
+
+ zapconf xpporder
+
+For more technical details see the section <<_registering_in_zaptel>>
+below.
+
+
/etc/zaptel.conf
~~~~~~~~~~~~~~~~
@@ -237,7 +305,9 @@ Astribank 4 BRI
span=3,2,1,ccs,ami
span=4,0,1,ccs,ami
bchan=1-2,4-5,7-8,10-11
- dchan=3,6,9,12
+ ; if you applied the bri_dchan patch:
+ ;dchan=3,6,9,12
+ hardhdlc=3,6,9,12
Astribank 4 PRI E1
^^^^^^^^^^^^^^^^^^
@@ -865,7 +935,7 @@ There are some technical terms that are used in this document and in the
driver / zaptel.
span::
- Dahdi breaks the channels it knows about to logical units called
+ Zaptel breaks the channels it knows about to logical units called
"spans". A port in a E1/T1/ISDN card is usually a span. An whole
analog card is also a "span". You can see the list of spans as the list
of files under /proc/zaptel directory or in output of the dahdi_tool
@@ -876,7 +946,7 @@ XBUS::
XPD::
Basically this is a logical unit of the Astribank. It will be
- registered in Dahdi as a single span. This can be either an analog
+ registered in Zaptel as a single span. This can be either an analog
(FXS or FXO) module or a single port in case of a BRI module.
@@ -897,30 +967,31 @@ during the Zaptel installation.
The Astribank needs a firmware loaded into it. Without the firmware,
the device will appear in lsusb with Vendor ID e4e4 and Product ID 11x0
-(1130, 1140 or 1150). The firmware loading process consists of two stages.
-In the first stage the "USB" firmware is loaded by using program fxload.
-When the first stage is completed the Vendor ID is e4e4 and the Product ID
-is 11x1. (e.g. 1151 if it were 1150 previously).
+(1130, 1140, 1150 or 1160). The firmware loading process consists of two
+stages. In the first stage the "USB" firmware is loaded by using program
+fxload. When the first stage is completed the Vendor ID is e4e4 and the
+Product ID is 11x1. (e.g. 1151 if it were 1150 previously).
You can use the following command in order to load the "USB" firmware
manually:
- fxload -t fx2 -D /proc/bus/usb/MMM/NNN -I /usr/share/zaptel/USB_FW.hex
+ fxload -t fx2 -D /dev/bus/usb/MMM/NNN -I /usr/share/zaptel/USB_FW.hex
where,
fxload::
A standard program that is typically part either of package 'fxload'
or 'hotplug-utils' .
-/proc/bus/usb::
- The mount point of the USB file-system (usbfs).
+/dev/bus/usb::
+ On some old systems it is missing . /proc/bus/usb (usbfs) could be
+ used instead.
MMM::
the first number (bus number)
NNN::
the second number (device number) you see for the device in lsusb
If the loading process has been completed successfully, the device
-disconnects and then connects again itself with USB Product ID 1131
+disconnects and then connects again itself with USB Product ID 11x1
(and a new device number).
In the second stage, the "FPGA" firmware is loaded.
@@ -931,7 +1002,20 @@ which is built in the directory xpp/utils and then copied to folder
The command syntax is similar to the syntax of fxload. You can use the
following command in order to load the FPGA firmware manually:
- fpga_load -D /proc/bus/usb/MMM/NNN -I /usr/share/zaptel/FPGA_1151.hex
+ # pick the right name according to the device ID. FPGA_1161.hex is for
+ # 116x Astribanks:
+ astribank_hexload -D /dev/bus/usb/MMM/NNN -F /usr/share/zaptel/FPGA_1161.hex
+ # Note the shell expantion in this line:
+ astribank_hexload -D /dev/bus/usb/MMM/NNN -p /usr/share/zaptel/PIC_TYPE_[1-4].hex
+ # reenumerate (disconnect and reconnect)
+ astribank_tool -D /dev/bus/usb/MMM/NNN -n
+
+With older USB firmwares before the one included in DAHDI 2.2 or latest
+Zaptel SVN, you needed to use instead of all the above:
+
+ # pick the right name according to the device ID. FPGA_1151.hex is for
+ # 115x Astribanks:
+ fpga_load -D /dev/bus/usb/MMM/NNN -I /usr/share/zaptel/FPGA_1151.hex
Please note, that NNN value differs from that that was used for the
fxload command due to the fact that device has "reconnected" itself
@@ -939,9 +1023,8 @@ with another Product ID number. So you need to run lsusb again and get
the new NNN value. Usually, the new value is equal to the old value
incremented by 1.
-On newer systems usbfs (/prob/bus/usb) is replaced by basically the same
-structure under /dev/bus/usb . Note, however, that zaptel_hardware still
-relies on some data from usbfs that is not found in /dev/usb .
+On newer systems (e.g. Centos 4) /dev/bus/usb may not be available. In
+that case, use /proc/bus/usb . usbfs should be mounted there.
Automatic Firmware Loading
@@ -985,6 +1068,14 @@ usb 7-1: reset high speed USB device using ehci_hcd and address 46
INFO-xpp_usb: XUSB: Xorcom LTD -- Astribank -- FPGA
-------------------------------------
+Another useful tool for tracing UDEV-related issue is the udev monitor:
+
+ udevadm monitor
+
+Or with some older versions of udev:
+
+ udevmonitor
+
Firmware Loading with Hotplug
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1007,7 +1098,7 @@ Loading The Modules
Here is what should happen:
In short: you should plug the Astribank device(s) or have them plugged in at
the boot time. Then all the modules should be loaded automatically.
-You will see xpp_usb , xpd_fxs and, possibly, xpd_fxo in the modules list
+You will see xpp_usb, xpp, and some xpd_* modules in the modules list
(the output of lsmod).
After the module xpp is loaded, you'll also be able to see the directory
@@ -1021,7 +1112,7 @@ Now to the ugly details:
The driver of the Astribank is composed of several modules:
xpp::
- The basic module, that communicates with Dahdi and provides some
+ The basic module, that communicates with Zaptel and provides some
common services to other modules.
xpd_fxs::
FXS modules (analog phones). Module type 1.
@@ -1039,7 +1130,7 @@ However the xpd_* modules are installed on-demand: no need to load
xpd_fxo if you have only Astribank FXS.
Once an Astribank device connected and the firmware is loaded, the
-Vendor-ID/Product-ID of the device will be e4e4/1132 . The handler for that
+Vendor-ID/Product-ID of the device will be e4e4/11x2 . The handler for that
combination is listed as the kernel module xpp_usb. Therefore, the system
runs 'modprobe xpp_usb' if that module is not already loaded.
@@ -1075,7 +1166,13 @@ NOTICE-xpp: xproto_get: Failed to load module for type=3. exit status=256.
NOTICE-xpp: XBUS-00: CARD 0: missing protocol table for type 3. Ignored.
--------------------------------------------------
In this case it was because I maliciously removed the module xpd_bri
-(type 3) from the system.
+(type 3) from the system.
+
+This can also happen if you accidentally blacklist the relevant xpd-*
+module. 'blacklist some_module' in modprobe.conf or modprobe.d/*.conf
+means that a direct insmod or modprobe of their name will work, but any
+attempt to load a module through its aliases will fail. Recall that the
+cpd-* modules are loaded on-demand using the alias 'xpd-type-N' .
Device Initializations Scripts
@@ -1111,11 +1208,8 @@ Connect / Disconnect Hook
When the Astribank has finished initialization it also notifies
userspace applications. This can be used to run a custom command when an
Astribank is connected (after it has finished initialization) or when it
-has disconnected.
-
-To use that you need to comment-out the last line in the udev rules file
-xpp.rules. A sample hook script is included in
-kernel/xpp/utils/astribank_hook.sample .
+has disconnected. The hook script is installed by default to
+/usr/share/zaptel/astribank_hook .
Registering in Zaptel
@@ -1136,7 +1230,7 @@ they are registered. To register:
For a system with several spans you'll see a "fast train of lights".
-"If you have multiple Astribank devices, zt_registration will
+If you have multiple Astribank devices, zt_registration will
register them by the ascending order of the USB connector ID. This
means that as long as the same Astribank is connected to the same
port, the order of plugging is not important.
@@ -1161,11 +1255,13 @@ usb:004/007 xpp_usb+ e4e4:1152 Astribank-multi FPGA-firmware
If you have multiple Astribank devices, dahdi_registration will register
them by the order of the "connector" field. This means that as long as
the same Astribank is connected to the same port, the order of plugging
-is not important.
+is not important. Alternatively you can set an explicit registration
+order using /etc/dahdi/xpp_order . See above in section about
+<<_xpp_order_explicitly_order_astribanks,xpp_order>>.
The registration is performed through the sysfs interface. See below
<<_sys_devices_xpp_xbus_nn_nn_m_p_span,the span attribute>>. Also note
-that dahdi_registration also allows you to unregister spans, which will
+that zt_registration also allows you to unregister spans, which will
work for all spans that are not in use (That is: none of their channels
is in use).
@@ -1185,6 +1281,19 @@ parameter <<_zap_autoreg>> in the modprobe configuration file (A file under
options xpp zap_autoreg=1
+Astribanks Synchronization Source
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+If there is more than one Astribank on the system, all the Astribanks
+keep their clock in sync. Optionally the Astribanks can synchronize
+their clock to the master Zaptel device (in case it is a different Zaptel
+device). Normally you just use the default init.d script or run
+explicitly:
+
+ xpp_sync auto
+
+(For now see the man page of xpp_sync for more information)
+
+
Zaptel And Above
^^^^^^^^^^^^^^^^
From here you get a standard Zaptel span. The next step is to configure
@@ -1325,6 +1434,10 @@ For the status of the D channel of the ports on all BRI spans, run:
/proc/xpp/XBUS-nn/XPD-mm/pri_info
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+(In latest SVN this file is read-only. The writetable functionality
+moved in part (E1/T1) to pri_protocol sysfs and in part (NT/TE) to
+zaptel.conf settings)
+
In addition to the usual information about the LEDs, this file also
provides useful information regarding ISDN Layer 1 and Layer 2 status.
For example, you can run the following command in order to monitor
@@ -1526,6 +1639,26 @@ easily see all the XPDs of the same type, as they are linked again
from the driver's directory.
+===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/pri_protocol
+Can have either of those two:
+
+E1::
+ Provides 31 channels, of which channel 16 is normally the D-channel.
+ Common in places outside of North America and Japan. This is the
+ default setup.
+
+T1::
+ T1 provides 24 channels. The last one is normally the D-Channel.
+ Common in North America.
+
+This can also be set by writing the strings explicitly to the file. But
+can only be done when an XPD is not a registered span.
+
+This writing is normally done by the device initialization script, based
+on the 'pri_protocol' settings in
+xref:_xpp_conf_astribank_initialization[/etc/xpp.conf] .
+
+
Useful Module Parameters
~~~~~~~~~~~~~~~~~~~~~~~~
Compilation-time defaults for the all modules can be shown as part of the
diff --git a/kernel/xpp/card_bri.c b/kernel/xpp/card_bri.c
index 1e3ec8b..7c344af 100644
--- a/kernel/xpp/card_bri.c
+++ b/kernel/xpp/card_bri.c
@@ -35,10 +35,6 @@
static const char rcsid[] = "$Id$";
-#ifndef CONFIG_ZAPATA_BRI_DCHANS
-#error CONFIG_ZAPATA_BRI_DCHANS is not defined
-#endif
-
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements"); /* must be before zap_debug.h */
static DEF_PARM(uint, poll_interval, 500, 0644, "Poll channel state interval in milliseconds (0 - disable)");
static DEF_PARM_BOOL(nt_keepalive, 1, 0644, "Force BRI_NT to keep trying connection");
@@ -131,6 +127,7 @@ typedef union {
#define REG30_LOST 3 /* in polls */
#define DCHAN_LOST 15000 /* in ticks */
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
#define BRI_DCHAN_SIGCAP ( \
ZT_SIG_EM | \
ZT_SIG_CLEAR | \
@@ -143,6 +140,9 @@ typedef union {
ZT_SIG_CAS | \
ZT_SIG_SF \
)
+#else
+#define BRI_DCHAN_SIGCAP ZT_SIG_HARDHDLC
+#endif
#define BRI_BCHAN_SIGCAP (ZT_SIG_CLEAR | ZT_SIG_DACS)
#define IS_NT(xpd) ((xpd)->direction == TO_PHONE)
@@ -212,8 +212,12 @@ struct BRI_priv_data {
/*
* D-Chan: buffers + extra state info.
*/
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
int dchan_r_idx;
byte dchan_rbuf[DCHAN_BUFSIZE];
+#else
+ atomic_t hdlc_pending;
+#endif
byte dchan_tbuf[DCHAN_BUFSIZE];
bool txframe_begin;
@@ -251,7 +255,7 @@ static void dump_hex_buf(xpd_t *xpd, char *msg, byte *buf, size_t len)
debug_buf[0] = '\0';
for(i = 0; i < len && n < DEBUG_BUF_SIZE; i++)
n += snprintf(&debug_buf[n], DEBUG_BUF_SIZE - n, "%02X ", buf[i]);
- XPD_DBG(GENERAL, xpd, "%s[0..%zd]: %s%s\n", msg, len-1, debug_buf,
+ XPD_NOTICE(xpd, "%s[0..%zd]: %s%s\n", msg, len-1, debug_buf,
(n >= DEBUG_BUF_SIZE)?"...":"");
}
@@ -432,6 +436,104 @@ static void nt_activation(xpd_t *xpd, bool on)
/*
* D-Chan receive
*/
+static void bri_hdlc_abort(xpd_t *xpd, struct zt_chan *dchan, int event)
+{
+ struct BRI_priv_data *priv;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ if(debug & DBG_COMMANDS)
+ dump_hex_buf(xpd, "D-Chan(abort) RX: dchan_rbuf",
+ priv->dchan_rbuf, priv->dchan_r_idx);
+ priv->dchan_r_idx = 0;
+#else
+ zt_hdlc_abort(dchan, event);
+#endif
+}
+
+static int bri_check_stat(xpd_t *xpd, struct zt_chan *dchan, byte *buf, int len)
+{
+ struct BRI_priv_data *priv;
+ byte status;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ if(priv->dchan_r_idx < 4) {
+ XPD_NOTICE(xpd, "D-Chan RX short frame (dchan_r_idx=%d)\n",
+ priv->dchan_r_idx);
+ dump_hex_buf(xpd, "D-Chan RX: current packet", buf, len);
+ bri_hdlc_abort(xpd, dchan, ZT_EVENT_ABORT);
+ return -EPROTO;
+ }
+#else
+ if(len <= 0) {
+ XPD_NOTICE(xpd, "D-Chan RX DROP: short frame (len=%d)\n", len);
+ bri_hdlc_abort(xpd, dchan, ZT_EVENT_ABORT);
+ return -EPROTO;
+ }
+#endif
+ status = buf[len-1];
+ if(status) {
+ int event = ZT_EVENT_ABORT;
+
+ if(status == 0xFF) {
+ XPD_NOTICE(xpd, "D-Chan RX DROP: ABORT: %d\n", status);
+ } else {
+ XPD_NOTICE(xpd, "D-Chan RX DROP: BADFCS: %d\n", status);
+ event = ZT_EVENT_BADFCS;
+ }
+ dump_hex_buf(xpd, "D-Chan RX: current packet", buf, len);
+ bri_hdlc_abort(xpd, dchan, event);
+ return -EPROTO;
+ }
+ return 0;
+}
+
+int bri_hdlc_putbuf(xpd_t *xpd, struct zt_chan *dchan, unsigned char *buf, int len)
+{
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ struct BRI_priv_data *priv;
+ byte *dchan_buf;
+ byte *dst;
+ int idx;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ dchan_buf = dchan->readchunk;
+ idx = priv->dchan_r_idx;
+ if(idx + len >= DCHAN_BUFSIZE) {
+ XPD_ERR(xpd, "D-Chan RX overflow: %d\n", idx);
+ dump_hex_buf(xpd, " current packet", buf, len);
+ dump_hex_buf(xpd, " dchan_buf", dchan_buf, idx);
+ return -ENOSPC;
+ }
+ dst = dchan_buf + idx;
+ idx += len;
+ priv->dchan_r_idx = idx;
+ memcpy(dst, buf, len);
+#else
+ zt_hdlc_putbuf(dchan, buf, len);
+#endif
+ return 0;
+}
+
+void bri_hdlc_finish(xpd_t *xpd, struct zt_chan *dchan)
+{
+ struct BRI_priv_data *priv;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ dchan->bytes2receive = priv->dchan_r_idx - 1;
+ dchan->eofrx = 1;
+#else
+ zt_hdlc_finish(dchan);
+#endif
+}
+
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
{
xbus_t *xbus;
@@ -493,14 +595,8 @@ static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
ret = -EPROTO;
goto drop;
}
- if(dchan_buf[idx-1]) {
- XPD_NOTICE(xpd, "D-Chan RX Bad checksum: [%02X:%02X=%02X] (%d)\n",
- dchan_buf[idx-3], dchan_buf[idx-2], dchan_buf[idx-1], dchan_buf[idx-1]);
- dump_hex_buf(xpd, "D-Chan RX: current packet", src, len);
- dump_hex_buf(xpd, "D-Chan RX: chan_buf", dchan_buf, idx);
- ret = -EPROTO;
+ if((ret = bri_check_stat(xpd, dchan, dchan_buf, idx)) < 0)
goto drop;
- }
if(debug)
dump_dchan_packet(xpd, 0, dchan_buf, idx /* - 3 */); /* Print checksum? */
/*
@@ -517,10 +613,105 @@ drop:
out:
return ret;
}
+#else
+static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
+{
+ xbus_t *xbus;
+ struct BRI_priv_data *priv;
+ byte *src;
+ struct zt_chan *dchan;
+ uint len;
+ bool eoframe;
+ int ret = 0;
+
+ src = REG_XDATA(regcmd);
+ len = regcmd->bytes;
+ eoframe = regcmd->eoframe;
+ if(len <= 0)
+ return 0;
+ if(!SPAN_REGISTERED(xpd)) /* Nowhere to copy data */
+ return 0;
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ xbus = xpd->xbus;
+#ifdef XPP_DEBUGFS
+ xbus_log(xbus, xpd, 0, regcmd, sizeof(reg_cmd_t)); /* 0 = RX */
+#endif
+ dchan = XPD_CHAN(xpd, 2);
+ if(!IS_OFFHOOK(xpd, 2)) { /* D-chan is used? */
+ static int rate_limit;
+
+ if((rate_limit++ % 1000) == 0)
+ XPD_DBG(SIGNAL, xpd, "D-Chan unused\n");
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ dchan->bytes2receive = 0;
+ dchan->bytes2transmit = 0;
+#endif
+ goto out;
+ }
+ XPD_DBG(GENERAL, xpd, "D-Chan RX: eoframe=%d len=%d\n", eoframe, len);
+ ret = bri_hdlc_putbuf(xpd, dchan, src, (eoframe) ? len - 1 : len);
+ if(ret < 0)
+ goto out;
+ if(!eoframe)
+ goto out;
+ if((ret = bri_check_stat(xpd, dchan, src, len)) < 0)
+ goto out;
+ /*
+ * Tell Zaptel that we received len-1 bytes. They include the data and a 2-byte checksum.
+ * The last byte (that we don't pass on) is 0 if the checksum is correct. If it were wrong,
+ * we would drop the packet in the "if(src[len-1])" above.
+ */
+ bri_hdlc_finish(xpd, dchan);
+ priv->dchan_rx_counter++;
+ priv->dchan_norx_ticks = 0;
+out:
+ return ret;
+}
+#endif
/*
* D-Chan transmit
*/
+#ifndef CONFIG_ZAPATA_BRI_DCHANS
+/* ZAPTEL calls this when it has data it wants to send to the HDLC controller */
+static void bri_hdlc_hard_xmit(struct zt_chan *chan)
+{
+ xpd_t *xpd = chan->pvt;
+ struct zt_chan *dchan;
+ struct BRI_priv_data *priv;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ dchan = XPD_CHAN(xpd, 2);
+ if (dchan == chan) {
+ atomic_inc(&priv->hdlc_pending);
+ }
+}
+#endif
+
+int bri_hdlc_getbuf(struct zt_chan *dchan, unsigned char *buf, unsigned int *size)
+{
+ int len = *size;
+ int eoframe;
+
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ len = dchan->bytes2transmit; /* dchan's hdlc package len */
+ if(len > *size)
+ len = *size; /* Silent truncation */
+ eoframe = dchan->eoftx; /* dchan's end of frame */
+ dchan->bytes2transmit = 0;
+ dchan->eoftx = 0;
+ dchan->bytes2receive = 0;
+ dchan->eofrx = 0;
+#else
+ eoframe = zt_hdlc_getbuf(dchan, buf, &len);
+#endif
+ *size = len;
+ return eoframe;
+}
+
static int tx_dchan(xpd_t *xpd)
{
struct BRI_priv_data *priv;
@@ -531,19 +722,22 @@ static int tx_dchan(xpd_t *xpd)
priv = xpd->priv;
BUG_ON(!priv);
+#ifndef CONFIG_ZAPATA_BRI_DCHANS
+ if(atomic_read(&priv->hdlc_pending) == 0)
+ return 0;
+#endif
if(!SPAN_REGISTERED(xpd) || !(xpd->span.flags & ZT_FLAG_RUNNING))
return 0;
dchan = XPD_CHAN(xpd, 2);
- len = dchan->bytes2transmit; /* dchan's hdlc package len */
- eoframe = dchan->eoftx; /* dchan's end of frame */
- dchan->bytes2transmit = 0;
- dchan->eoftx = 0;
- dchan->bytes2receive = 0;
- dchan->eofrx = 0;
+ len = ARRAY_SIZE(priv->dchan_tbuf);
+ if(len > MULTIBYTE_MAX_LEN)
+ len = MULTIBYTE_MAX_LEN;
+ eoframe = bri_hdlc_getbuf(dchan, priv->dchan_tbuf, &len);
if(len <= 0)
return 0; /* Nothing to transmit on D channel */
if(len > MULTIBYTE_MAX_LEN) {
XPD_ERR(xpd, "%s: len=%d. need to split. Unimplemented.\n", __FUNCTION__, len);
+ dump_hex_buf(xpd, "D-Chan TX:", priv->dchan_tbuf, len);
return -EINVAL;
}
if(!test_bit(HFC_L1_ACTIVATED, &priv->l1_flags) && !test_bit(HFC_L1_ACTIVATING, &priv->l1_flags)) {
@@ -552,7 +746,6 @@ static int tx_dchan(xpd_t *xpd)
te_activation(xpd, 1);
else
nt_activation(xpd, 1);
- return 0;
}
if(debug)
dump_dchan_packet(xpd, 1, priv->dchan_tbuf, len);
@@ -565,8 +758,12 @@ static int tx_dchan(xpd_t *xpd)
eoframe, priv->dchan_tbuf, len);
if(ret < 0)
XPD_NOTICE(xpd, "%s: failed sending xframe\n", __FUNCTION__);
- if(eoframe)
+ if(eoframe) {
+#ifndef CONFIG_ZAPATA_BRI_DCHANS
+ atomic_dec(&priv->hdlc_pending);
+#endif
priv->dchan_tx_counter++;
+ }
priv->dchan_notx_ticks = 0;
return ret;
}
@@ -610,11 +807,16 @@ err:
return -EINVAL;
}
-static xpd_t *BRI_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone)
+static xpd_t *BRI_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table,
+ byte subtype, int subunits, int subunit_ports, bool to_phone)
{
xpd_t *xpd = NULL;
int channels = min(3, CHANNELS_PERXPD);
+ if(subunit_ports != 1) {
+ XBUS_ERR(xbus, "Bad subunit_ports=%d\n", subunit_ports);
+ return NULL;
+ }
XBUS_DBG(GENERAL, xbus, "\n");
xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct BRI_priv_data), proto_table, channels);
if(!xpd)
@@ -636,6 +838,8 @@ static int BRI_card_init(xbus_t *xbus, xpd_t *xpd)
BUG_ON(!xpd);
XPD_DBG(GENERAL, xpd, "\n");
priv = xpd->priv;
+ DO_LED(xpd, GREEN_LED, BRI_LED_OFF);
+ DO_LED(xpd, RED_LED, BRI_LED_OFF);
set_bri_timer(xpd, "T1", &priv->t1, HFC_TIMER_OFF);
write_state_register(xpd, 0); /* Enable L1 state machine */
priv->initialized = 1;
@@ -685,26 +889,33 @@ static int BRI_card_zaptel_preregistration(xpd_t *xpd, bool on)
cur_chan->pvt = xpd;
if(i == 2) { /* D-CHAN */
cur_chan->sigcap = BRI_DCHAN_SIGCAP;
- cur_chan->flags |= ZT_FLAG_BRIDCHAN;
cur_chan->flags &= ~ZT_FLAG_HDLC;
-
+ priv->txframe_begin = 1;
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ priv->dchan_r_idx = 0;
+ cur_chan->flags |= ZT_FLAG_BRIDCHAN;
/* Setup big buffers for D-Channel rx/tx */
cur_chan->readchunk = priv->dchan_rbuf;
cur_chan->writechunk = priv->dchan_tbuf;
- priv->dchan_r_idx = 0;
- priv->txframe_begin = 1;
cur_chan->maxbytes2transmit = MULTIBYTE_MAX_LEN;
cur_chan->bytes2transmit = 0;
cur_chan->bytes2receive = 0;
- } else
+#else
+ atomic_set(&priv->hdlc_pending, 0);
+#endif
+ } else {
cur_chan->sigcap = BRI_BCHAN_SIGCAP;
+ }
}
CALL_XMETHOD(card_pcm_recompute, xbus, xpd, 0);
xpd->span.spanconfig = bri_spanconfig;
xpd->span.chanconfig = bri_chanconfig;
xpd->span.startup = bri_startup;
xpd->span.shutdown = bri_shutdown;
+#ifndef CONFIG_ZAPATA_BRI_DCHANS
+ xpd->span.hdlc_hard_xmit = bri_hdlc_hard_xmit;
+#endif
return 0;
}
@@ -932,6 +1143,8 @@ static int BRI_card_open(xpd_t *xpd, lineno_t pos)
static int BRI_card_close(xpd_t *xpd, lineno_t pos)
{
+ /* Clear D-Channel pending data */
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
struct zt_chan *chan = XPD_CHAN(xpd, pos);
/* Clear D-Channel pending data */
@@ -939,6 +1152,7 @@ static int BRI_card_close(xpd_t *xpd, lineno_t pos)
chan->eofrx = 0;
chan->bytes2transmit = 0;
chan->eoftx = 0;
+#endif
if(pos == 2) {
LINE_DBG(SIGNAL, xpd, pos, "ONHOOK the whole span\n");
BIT_CLR(xpd->offhook_state, 0);
@@ -1033,7 +1247,9 @@ static int bri_startup(struct zt_span *span)
*
* Don't Get Mad, Get Even: Now we override zaptel :-)
*/
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
dchan->flags |= ZT_FLAG_BRIDCHAN;
+#endif
dchan->flags &= ~ZT_FLAG_HDLC;
}
return 0;
@@ -1521,6 +1737,9 @@ static int proc_bri_info_read(char *page, char **start, off_t off, int count, in
} else {
len += sprintf(page + len, "(dead)\n");
}
+#ifndef CONFIG_ZAPATA_BRI_DCHANS
+ len += sprintf(page + len, "hdlc_pending=%d\n", atomic_read(&priv->hdlc_pending));
+#endif
len += sprintf(page + len, "dchan_notx_ticks: %d\n", priv->dchan_notx_ticks);
len += sprintf(page + len, "dchan_norx_ticks: %d\n", priv->dchan_norx_ticks);
len += sprintf(page + len, "LED: %-10s = %d\n", "GREEN", priv->ledstate[GREEN_LED]);
@@ -1539,6 +1758,25 @@ static int proc_bri_info_read(char *page, char **start, off_t off, int count, in
return len;
}
+static DRIVER_ATTR_READER(dchan_hardhdlc_show, drv,buf)
+{
+ int len = 0;
+
+#if defined(CONFIG_ZAPATA_BRI_DCHANS)
+ len += sprintf(buf + len, "0\n");
+#elif defined(ZT_SIG_HARDHDLC)
+ len += sprintf(buf + len, "1\n");
+#else
+#error Cannot build BRI without BRISTUFF or HARDHDLC supprt
+#endif
+ return len;
+}
+
+static DRIVER_ATTR(dchan_hardhdlc,S_IRUGO,dchan_hardhdlc_show,NULL);
+
+extern void driver_remove_file(struct device_driver *, struct driver_attribute *);
+
+
static int bri_xpd_probe(struct device *dev)
{
xpd_t *xpd;
@@ -1581,7 +1819,18 @@ static int __init card_bri_startup(void)
if((ret = xpd_driver_register(&bri_driver.driver)) < 0)
return ret;
+ ret = driver_create_file(&bri_driver.driver, &driver_attr_dchan_hardhdlc);
+ if(ret < 0)
+ return ret;
INFO("revision %s\n", XPP_VERSION);
+#if defined(CONFIG_ZAPATA_BRI_DCHANS)
+ INFO("FEATURE: WITH BRISTUFF\n");
+#elif defined(ZT_SIG_HARDHDLC)
+ INFO("FEATURE: WITH HARDHDLC\n");
+#else
+#error Cannot build BRI without BRISTUFF or HARDHDLC supprt
+#endif
+
xproto_register(&PROTO_TABLE(BRI));
return 0;
}
@@ -1590,6 +1839,7 @@ static void __exit card_bri_cleanup(void)
{
DBG(GENERAL, "\n");
xproto_unregister(&PROTO_TABLE(BRI));
+ driver_remove_file(&bri_driver.driver, &driver_attr_dchan_hardhdlc);
xpd_driver_unregister(&bri_driver.driver);
}
diff --git a/kernel/xpp/card_fxo.c b/kernel/xpp/card_fxo.c
index bddfa0c..3ad8b7a 100644
--- a/kernel/xpp/card_fxo.c
+++ b/kernel/xpp/card_fxo.c
@@ -428,7 +428,8 @@ err:
return -EINVAL;
}
-static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone)
+static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table,
+ byte subtype, int subunits, int subunit_ports, bool to_phone)
{
xpd_t *xpd = NULL;
int channels;
@@ -440,9 +441,9 @@ static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit, const xproto_tab
return NULL;
}
if(subtype == 2)
- channels = min(2, CHANNELS_PERXPD);
+ channels = min(2, subunit_ports);
else
- channels = min(8, CHANNELS_PERXPD);
+ channels = min(8, subunit_ports);
xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct FXO_priv_data), proto_table, channels);
if(!xpd)
return NULL;
diff --git a/kernel/xpp/card_fxs.c b/kernel/xpp/card_fxs.c
index 47688ef..b7bcdd2 100644
--- a/kernel/xpp/card_fxs.c
+++ b/kernel/xpp/card_fxs.c
@@ -100,6 +100,7 @@ enum fxs_state {
#define REG_BATTERY_BATSL BIT(1) /* Battery Feed Select */
#define REG_LOOPCLOSURE 0x44 /* 68 - Loop Closure/Ring Trip Detect Status */
+#define REG_LOOPCLOSURE_ZERO 0xF8 /* Loop Closure zero bits. */
#define REG_LOOPCLOSURE_LCR BIT(0) /* Loop Closure Detect Indicator. */
/*---------------- FXS Protocol Commands ----------------------------------*/
@@ -376,7 +377,8 @@ err:
return -EINVAL;
}
-static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone)
+static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table,
+ byte subtype, int subunits, int subunit_ports, bool to_phone)
{
xpd_t *xpd = NULL;
int channels;
@@ -391,9 +393,9 @@ static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_tab
return NULL;
}
if(subtype == 2)
- regular_channels = min(6, CHANNELS_PERXPD);
+ regular_channels = min(6, subunit_ports);
else
- regular_channels = min(8, CHANNELS_PERXPD);
+ regular_channels = min(8, subunit_ports);
channels = regular_channels;
if(unit == 0)
channels += 6; /* 2 DIGITAL OUTPUTS, 4 DIGITAL INPUTS */
@@ -569,7 +571,6 @@ static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos, bool msg_waiting)
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15, 0xEF, 0x7B);
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x14, 0x9F, 0x00);
ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x22, 0x19);
- ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x4A, 0x34);
ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x30, 0xE0);
ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x31, 0x01);
ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x32, 0xF0);
@@ -578,11 +579,12 @@ static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos, bool msg_waiting)
} else {
/* A write to register 0x40 will now turn on/off the ringer */
LINE_DBG(SIGNAL, xpd, pos, "RINGER\n");
+
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x16, 0x00, 0x00);
- ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15, 0x60, 0x01);
- ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x14, 0xF0, 0x7E);
+ ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15, 0x77, 0x01);
+ ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x14, 0xFD, 0x7E);
+
ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x22, 0x00);
- ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x4A, 0x34);
ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x30, 0x00);
ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x31, 0x00);
ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x32, 0x00);
@@ -873,7 +875,11 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
if (get_user(val, (int __user *)arg))
return -EFAULT;
if(!vmwi_ioctl) {
- LINE_NOTICE(xpd, pos, "Got ZT_VMWI notification but vmwi_ioctl parameter is off. Ignoring.\n");
+ static bool notified = 0;
+
+ if(!notified++)
+ LINE_NOTICE(xpd, pos,
+ "Got ZT_VMWI notification but vmwi_ioctl parameter is off. Ignoring.\n");
return 0;
}
/* Digital inputs/outputs don't have VM leds */
@@ -1309,11 +1315,17 @@ static int FXS_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
xpp_line_t mask = BIT(info->portnum);
xpp_line_t offhook;
- offhook = (val & REG_LOOPCLOSURE_LCR) ? mask : 0;
- LINE_DBG(SIGNAL, xpd, info->portnum,
- "REG_LOOPCLOSURE: dataL=0x%X (offhook=0x%X mask=0x%X\n",
- val, offhook, mask);
- process_hookstate(xpd, offhook, mask);
+ /*
+ * Validate reply. Non-existing/disabled ports
+ * will reply with 0xFF. Ignore these.
+ */
+ if((val & REG_LOOPCLOSURE_ZERO) == 0) {
+ offhook = (val & REG_LOOPCLOSURE_LCR) ? mask : 0;
+ LINE_DBG(SIGNAL, xpd, info->portnum,
+ "REG_LOOPCLOSURE: dataL=0x%X (offhook=0x%X mask=0x%X\n",
+ val, offhook, mask);
+ process_hookstate(xpd, offhook, mask);
+ }
} else {
#if 0
XPD_NOTICE(xpd, "Spurious register reply(ignored): %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
diff --git a/kernel/xpp/card_global.c b/kernel/xpp/card_global.c
index 88b9f60..14cf02c 100644
--- a/kernel/xpp/card_global.c
+++ b/kernel/xpp/card_global.c
@@ -307,9 +307,8 @@ int parse_chip_command(xpd_t *xpd, char *cmdline)
BUG_ON(!xpd);
xbus = xpd->xbus;
- if(XBUS_IS(xbus, DISCONNECTED)) {
- XBUS_DBG(GENERAL, xbus, "Dropped packet. In state %s.\n",
- xbus_statename(XBUS_STATE(xbus)));
+ if(!XBUS_FLAGS(xbus, CONNECTED)) {
+ XBUS_DBG(GENERAL, xbus, "Dropped packet. Disconnected.\n");
return -EBUSY;
}
strlcpy(buf, cmdline, MAX_PROC_WRITE); /* Save a copy */
diff --git a/kernel/xpp/card_pri.c b/kernel/xpp/card_pri.c
index a8eef64..8760cf8 100644
--- a/kernel/xpp/card_pri.c
+++ b/kernel/xpp/card_pri.c
@@ -661,7 +661,7 @@ static void set_reg_lim0(const char *msg, xpd_t *xpd)
}
/*
- * Normally set by the timing parameter in zaptel.conf
+ * Normally set by the timing parameter in /etc/zaptel.conf
* If this is called by ztcfg, than it's too late to change
* zaptel sync priority (we are already registered)
*
@@ -909,12 +909,17 @@ static int pri_chanconfig(struct zt_chan *chan, int sigtype)
return 0;
}
-static xpd_t *PRI_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone)
+static xpd_t *PRI_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table,
+ byte subtype, int subunits, int subunit_ports, bool to_phone)
{
xpd_t *xpd = NULL;
struct PRI_priv_data *priv;
int channels = min(31, CHANNELS_PERXPD); /* worst case */
+ if(subunit_ports != 1) {
+ XBUS_ERR(xbus, "Bad subunit_ports=%d\n", subunit_ports);
+ return NULL;
+ }
XBUS_DBG(GENERAL, xbus, "\n");
xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct PRI_priv_data), proto_table, channels);
if(!xpd)
diff --git a/kernel/xpp/firmwares/FPGA_1161.hex b/kernel/xpp/firmwares/FPGA_1161.hex
new file mode 100644
index 0000000..6a705e8
--- /dev/null
+++ b/kernel/xpp/firmwares/FPGA_1161.hex
@@ -0,0 +1,1034 @@
+#
+# $Id: FPGA_1161.hex 7131 2009-05-20 15:44:04Z dima $
+#
+:020000040000FA
+:80000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6AD6FF4000B00910006AD6FF4000B00910006AD6FF4000B009100000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4455544455557475577775577675577775577765566665562635523235D2F37127511115511115511115511172
+:800080001551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111551111511010000000000181AA1111A2101000000181AA1111A2101181A210100181AE121F112122F21F1121227212592121AE12154
+:80010000F112122F21F11212230100000000181AA1111A21012425120200181AA1111A2101181A210100181AA1111AA1111A2101181AA1111AA1111A210100002425522225D222F112122F21F1121227212552222552222552222592121AA1111A2101181A612125522225D222F112122F21F112122F21F11212272125D222F112122F21D9
+:80018000F112122F21F11212272125120200000024255222251202002425522225120200242552222512020000242512020024255222251202002425522225120200000000242512020000002425522225120200000000242512020000000000000000000000000000000000000000000000000000000000242512020000002425522225EA
+:80020000120200242552222552222552222552222552222552E2E5DE9EFFF9F9930F24255222255222251202242512020000000000181AA1111A21010000000000000000000000000000242552222512020000008485D8A8F11A1AAF21F1121223010000002CF112122F21F1121223012CF112122301002CF112122F21F112122B111A21F7
+:80028000012CF112122F21F112122F21F1121223010000008CF888888FA8F88A8AA72825120200008CFCC8C88F8CFCC8C8830C8CF8888887A8A55A8A8598C8CAEC8CFCC8C8878C85588885588885D888FCC8C88F8CFCC8C88F8CFCC8C8830C0000008CF888888FA8F88A8AA72825120200008CFCC8C88FACFCCACAA72C25D282F8888887DA
+:80030000282512028CFCC8C88FACFCCACAA72C25120200ACFCCACAAFACFCCACAAFACFCCACAA30C000000CCF88C8CCFC8F88C8CC3080000008CFCC8C88FACFCCACAA72C25D2C2F88C8CC308008CFCC8C88FACFCCACAA72C25120200ACFCCACAAFACFCCACAAFACFCCACAA30C000000CCF88C8CCFC8FAACACCB2A2A22020000CCFCCCCCCFEC01
+:80038000FEEEEEEF2EF222222FC2F88C8CCFC8F22C2CC7C2C59CCCCAECECFEEEEEEFEEF22E2EE7C2C55CCCC5DCECFEEEEEEFEEFEEEEEEFEEFEEEEEE30E000000C8CAEC1CFEE1E11F1EF2212113020000CCF88C8CCFE8F99E9EEF79F447477F24F6626223062CF112122BC1CAEC1CF221211302CCF88C8CCFE8F99E9EEF29F11212230100BC
+:80040000ECF99E9EEFE9F99E9EEFE9F99E9EE309000000C8CAEC1CFCC1C1171C1511010000CCF88C8CCFF8FBBFBFFF3BF333333BC3CAEC1CF441411B444AE4C4F88C8CCFF8FFFFFFFF3FF773733F17F441411B444AE4F4FFFFFFFFFFFFFFFFFFFFFFFFFFF30F0000008CF888888F88F888888308000000CCFCCCCCCFFCFFFFFFFF3FF333A2
+:80048000333F83F88888830800CCFCCCCCCFFCFFFFFFFF3FF33333330300FCFFFFFFFFFFFFFFFFFFFFFFFFFFF30F000000CCF88C8CCFC8FAACACCB2A2A220200008CFCC8C88FBCFFFBFBBF3FF333333FC3F88C8CCF88F2282887828598C8CAECBCFFFBFBBFBFF33B3BBF83F22828878285D8B8FFFBFBBFBFFFFBFBBFBFFFFBFBB30F0000B1
+:80050000004445D444F224244B222A22020000CCFCCCCCCFFCFFFFFFFF3FF33333374345D444F22424474245D484FCC8C88FFCFFFFFFFF7FF337377F43F22424474245D4F4FFFFFFFFFFFFFFFFFFFFFFFFFFF30F000000000000000000CCFCCCCCCFFCFFFFFFFF3FF3333333030000CCFCCCCCCFFCFFFFFFFF3FF33333330300FCFFFFFF92
+:80058000FFFFFFFFFFFFFFFFFFFFF30F0000008485D888F118188B111A210100004CFCC4C44F7CFFF7F77F3FF333333303181A21014CFCC4C44F7CFFF7F77F3FF333333B131A21017CFFF7F77F7FFFF7F77F7FFFF7F7730F00000000009CF339399FC3F88C8CC30800000000CCFCCCCCCFFCFFFFFFFF3FF3333333030000CCFCCCCCCFFC30
+:80060000FFFFFFFF3FF33333330300FCFFFFFFFFFFFFFFFFFFFFFFFFFFF30F000000000000000000CCFCCCCCCFFCFFFFFFFF3FF3333333030000CCFCCCCCCFFCFFFFFFFF3FF33333330300FCFFFFFFFFFFFFFFFFFFFFFFFFFFF30F000000484AE434F4434337343513030000CCF88C8CCFD8FBBDBDDF1BF331311B434AE434F443433B440A
+:800680004AE4C4F88C8CCFD8FFFDFDDF1FF771711F17F441411B444AE4D4FFFDFDDFDFFFFDFDDFDFFFFDFDD30F000000484AA4646AA6262A22020000CCF88C8CCFF8FBBFBFFF3BF333333B434AA4646AA6464AE4C4F88C8CCFF8FFFFFFFF3FF773733B676AA6464AE4F4FFFFFFFFFFFFFFFFFFFFFFFFFFF30F000000C8CAACCCCA2C0C003C
+:800700000000CCFCCCCCCFFCFFFFFFFF3FF333333BC3CA2C0C00CCFCCCCCCFFCFFFFFFFF3FF33333330300FCFFFFFFFFFFFFFFFFFFFFFFFFFFF30F0000004CFCC4C44F4CFCC4C4430C000000C4C5DCFCF33F3FFF33F333333F43FCC4C44B4C4AA4444A64C4C5DCFCF77F7FFF37F773733B474AA4444AE4F4F77F7FFFF7F77F7FFFF7F77F31
+:800780007FF3070000004CFCC4C44F4CFCC4C4430C000000C4C5DCFCF33F3FFF33F333333F43FCC4C44B4C4AA4444A64C4C5DCFCF77F7FFF37F773733B474AA4444AE4F4F77F7FFFF7F77F7FFFF7F77F7FFF97FAA9A9973A351303000000004445D444F114144B111A21010000CCFCCCCCCFFCFFFFFFFF3FF3333337434594141A2101CCE0
+:80080000FCCCCCCFBCFFFBFBBF7FF33737730300FCFFFFFFFFBFFFFBFBBFFFFFFFFFF30F0000004445D464F116166F21F11212230100008CFCC8C88FBCFFFBFBBF3FF33333374345D424F1121223018CFCC8C88FBCFFFBFBBF3FF333333723251202BCFFFBFBBFBFFFFBFBBFBFFFFBFBB30F000000CCF44C4CCFF4F44F4FF73435130300E2
+:8008800000CCF88C8CCFF8FBBFBFFF3BF333333FC3F44C4CCFB4F44B4BBF84F448488F44F884844FB8FFFBFBBFFFF77F7FFFB7F44B4BBF84F448488FF4FFFFFFFFBFFFFBFBBFFFFFFFFFF30F000000CCF44C4CCFD4F44D4DD7141511010000CCF88C8CCFD8FBBDBDDF1BF331311FC3F44C4CCF14F441411B444AE4C4F88C8CCF98FFF9F90C
+:800900009F5FF775755F17F441411B444AE4D4FFFDFDDF9FFFF9F99FDFFFFDFDD30F000000CCFCCCCCCFDCFFFDFDDF1FF3313113030000C4C5DCDCF33D3DDF13F331311FC3FCCCCCCF1CF771711B474A64C4C5DCDCF77D7DDF17F771711F17F661611B464AE4D4F77D7DDFD7F77D7DDFD7F77D7DD307000000CCF44C4CCFD4F77D7DDF1791
+:80098000F33131130300008CF888888F98FBB9B99F1BF3313117C3C5DC9CF3393997838598888AE898FBB9B99F9BF339399F83F33838878385D898FBB9B99F9BFBB9B99F9BFBB9B9930B00000000000000000000000000000000009CF889899FA8F44A4AA3040000000000000000000000000000000000000000000000000000000000000B
+:800A000000000000000000000000BE13000000000000000000000000000000000000000000000000000022000000000000008241000000000000EC345200000000000000000000000000000000000000000000000000000000000000000000000000000000E03B010000000000000000000000000000000000000000000000000020020010
+:800A800000000000002018040000000000C04E230500000000000000000000000000000000000000000000000000000000000000000000000000000000BE13001210022200121002221100420022112021140210011242210011001002220000212002004200000042210000200400000021200200D0A23A4900000000000000000000003B
+:800B00000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000180018008001004001000028140000001C080024001C4804000088440000003F4D0300000034
+:800B8000000000000000000000000000000000000000000000800100200200000000200100824100000000C0A2B34102280018400228140048002814808144024001184824001480012480028001248042018084012814001A4502C08112124824001C6841002480A2811604400228F0FD5B00000000000000000000000000000000001248
+:800C000000000012000011000020120100003081001002308141000020180400003C312E00000000000000000000000000000000000000000000000000000000000000000000000000000000E03B010000000000000000000000000000000000000000000000000000000000200800000000000082000000EC34120000000000000000009A
+:800C8000000000000000002001000080010040010000100100800111004002400100000044000000FFF60D00000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000E8
+:800D00000000000000000000000000000000000018000000000000000018000000001001000088440000007C35D200000000000000000000000000000000800100000000000000000000000000000000000000000000008F1F0D0000000000000000000000000000000000000000000014000000000000400100100200000000000000C080
+:800D800016130D00000000000000000000000000000000000000000000000000000000000000000000000000000000BE130000000000000000000000000000000000000000000000000000140000008800000000000000000000C0523302000000000000000000000000000000000000400100000082000000000000000000000000000046
+:800E00000000002F3A0400000000004002000000000000000000000000002001001800001001000000140000000000000021002008E06135B7000000000000000000000000000000000000001100000000004001000000000000000000000000200800DFCB0D0000000000400200000000000000000000000000200100182008000000001B
+:800E800000140000000000000021000080C1B94307000000000000008200000000000000000000000000000080022001000020018001004100180080280118001200F0687B0000000000200200000000000000000000280000000000000000000000000000000000000000000000C012430E00000000000000000000000000000000000046
+:800F000000000048000000000000000000800200000000000000005F940E20020000000000000000000000200200000020040000000000001001002004000000000000000048000000B41305220000000000000000000000002800000000480000000000000014000000000000000000000000000000DF290900000000000000000000003E
+:800F800000000000000000000000480000000000004200000028000000000048000000B8330E800100800200128002000000000000000018000000000020042001000000000012000000002014040000000000FF7C011200002001002002000000800220011A020000200248800400202102180000180000002200800228000000002004DF
+:80100000000012E0A43BD50012000000000000000000001880810200000000000020014280210100120000800200200200000000200400001880F469AA200100808102001822280000008002000000002021022084040000220000000000000020010028000048440000000000C07123071280020000000020010000000020128201243814
+:8010800018000000281800002800004800000038001241282280010000000032000018F09D73002021020000000020821282020000001820012100000000220000000000420040018004800200202181022001002810040018DC314F0000808102008002000080010018000000280000124003808484020000008002002002000000002882
+:801100002220020000200400001F7F09A0110000220000228022810218000000A012210020220100140080042200220000000000223242201104228022A12220220100180000208137458200001200000000002420020018000000281200200121004A0100000000800200000000282200000000000080040080F1E3FE00008021020080F4
+:801180000100180028282021A1211820010000120012103212481821222001280020830220820200800628008004422200A02100000042BC332B22000000000000009012211812100200000028220000281A04128084210100000000000000000000000000002800480000F0C9BD88000000001800188081010038800222122002A012207F
+:8012000002280000120000002838A022004828A031000000000000200180014820240200121E7513020080022200000010020000220000808102602128120000000021001200180000008001000000000000120020010000002FAC02002002000020810100000000002021011200000000242848100112000000000000008002A01200125E
+:80128000004200202104480048004EC723040080020000000000000028000000800180010000002822180000000048280042200400008021040044000000008082016FE58E020000200100200140420200211840024002902200001042220100428001280022000000000000000000000080014200000068A30382002081210118180000EA
+:801300000020028082820200002001000000000000001200420042001800202222220200000000428004228044011FA28A0800200200000000244A01001112A0110018822003212302000022A01200290200182800422828181302000020081218214200000020024100425E16B38722082280A32112000012301224182081A223A0212E79
+:801380002218120028321A42022220221422A2444AA1311A01003AA22222122024067A0242002822000020A4542200808124242402E01101CE83288800800100181A0112002450228021011AA2111880913228212A8222220112A01100184200800212122A04002A031A010000622A210200420080A1614832008026B441C1DB830E0000C4
+:80140000800100181218001A3112A0222682B1320218A012180080A11100217012C23218603221213A8181021280022A0228800300222022025212004418001A04482A0400424AF59AD700008820010012800100180022212221282901290180021A020000210048001200221822002002221800002880020020040020018004118024C101
+:80148000941389020020011A01200118002427212124272225622225722252227012022502120050227012F23222003731257212A22200A01200004A044A45A14400288002A0441A01504400200180A422A0221248E72A00002A882181218181011812484672127252C22133A22113D32231323AA1819632129E2229B222233322401242A9
+:80150000F2122223A2421C35412C912232282232322242282AE41692616AB1112404A082A222B22CB442A14123644441001A2124C6444B241392246A25C5E993AC2200282081A11180212181014825721212E232A2133AB332C1323A032D8212182D222C22A13200250227212B2328483D432F21F112122A0222323A014820A2462E214A36
+:80158000A5114A0480A282282A014E421A2124544400125AA4644AC4442A026A26A1116F778322020018121A2181A111181812E024F1125227212837222D313E121227232B131E122B191AC82229A23236220324212CF112322382C4533F25F112122B213228223AA2232280A2426A92616E111A2404A022A22A2A82B442E121246444410F
+:8016000080A1114842484B242684A2565AE45436E70000000000200100120080020012200100000000002400400200000000000000000000000000002004000042009FF10A000000128001000000001880A122000000A022200100001248001220012022210200222022018002002200480000001200420018484C37AF19B21284F21241B8
+:80168000F012412AF11261222F11A4922F11A4922F11E42269112E9256E122A9242E921B242E921B252E921B252E121B24A6B24122BB4133B219B3B2B441B392C4222F19A4142F1924F292612AF112412AF912612AE911E622C9212E925E212E925AE222B941C2921B242E921F44E222F5412486F24124921F44B2B2D441B392D441B3B2CD
+:80170000C4342B494E142B49222B4943B612B424F9DB17142E12422E121366221364211B261E121B249E121B249E121B24CE121B248E5219F293421B222F39A4222F3985F29253AAF282433AEA1194B22D411EB2141AEA14B4320B2D921F16E423A924881B26272113E629B161A2191B26233C612B1913B2D3B52172C221F2D2412A7292E4
+:80178000B1A4F2D2414B8327116B822F14F434A646E12368144F232AF434926AF4349249D224E946C6122E249E47E30582000000000000800400140000008800000018000000000000000000001400000088006022000020080040042414F0C9A7000018002200004002408203002082022818800200188001004021010032424819010092
+:801800002200A0220080040042000000422001120000001C31CB228A218208122001208283012A21810228800114C03120020012000012000048200318280000A0211228002220022112222084C14412382002260200C041C021245B6E28882828821828200180A211905222204221021A0228A082221A0124000000128002118081031A4B
+:80188000021880042042A122A02200A084800324184C840148281828384004108112C1B2A30612001800002002002041A221000014C0112002222001122001008081042880041C0400281812000080022118422004003800400200800440F26CFA20011A0100400180010000182200000000000000008002000000200222180000000020C7
+:80190000040000004200280000000000221C3C72000000180022008001400180022200002228008001422A240400001A828203420000002001A0212212208182820400424220040000420080E2EA0F800100001001002001003200280000A02200001200222002001820A222A0240012000012808206000020840420240442000020042818
+:80198000C072C38201200120012002120000110022000000000000808424040000282001000000000020011220212202000080020000000020F24D5480012A210212120000000022001301108104A022200100281420011A222402800220050012521800200128D0220100A0421200000022482800102402EC32DC00800214222011010026
+:801A00000000C021000000001800120000200428482022810200808204202401281200802201C0121A0410042218282002220080F4FB4A00002001008001400100000020010000000000000000210000220000002420020028000080028002280000800400484035F98001128021031001001120022003800100200200120014004A810426
+:801A800029042212224A03002A81011223A42100202262212001284A2201224122282A8122042002284248876D0020021211001220010000000014800420020000288001002200002200000000001828184002200200200400000000430400C0F22383210100801181010000000000601260120000282002281A0214802404488084022040
+:801B00002201208323A2214822202201002002002A81022A01000000182828DFA709111901130222009021000000800220011100400114120000000000000028804202002400121A04200280244182110280010000209414281818FC3C44208202008021810111121438142A418101001800111228200228181420A2412812802102A04123
+:801B8000800148008001001812C012290428226800208134420000004100F0B4410011002A1101280000002800002800001222001218148001120000001800006280020000008001400224004822100220043022001002DC2E2C8341010018188041810260124001201121B2110211800211A02110014842200412000000200480012A0490
+:801C000080042842004004121A1482220200420020042021746E040000A02100001828000000111100301100001280810280010020A2128001482004004200581848E02402000028421800800100200280016AE132346E1180410100002041018011210100000000802102100100200112000080018001422682040000002100000000441B
+:801C8000000000000010F2A1CE8008220000000012200132001820A1211800000080810100A01428A01118001218002004200100422005281002001800180028280022180011FC32B78042018A020000362122011448141140811201221901A819C211282428112818120042280012002A0400224822204101181002800829012C0418006A
+:801D000048422C2484027C24240248EF2B061A9B3113021C81A211A013181113228131111B121712A01218C0111AE11181923118159121111815A131A031581A82021A8221A31112124A24E4210422183A042AA4112AA4617A220221A02129A41246A225A012484848424280B443E124A2321F23674413F811218A01118238100111281980
+:801D800021022222181413011B2226C1218001282828382A9221121C8304488021A114200512222A2181246622B022A11100481223250125E24294223602221A614300402212820241C041F02AF540611212130218A011E011A231181C41E112410100121E112AC2211312011C8202181AA2211382011385A455421800A042483222628043
+:801E0000A1632082A1445A017012122206004AA4116022481E325242228004A01112E03337DF80211201188001182811001001110040012601002601226012182200004A0100008022042428241A420248124812220000A04200302610221402211002298281E28DC131171219712191818023820118171219A312381B231B131711112077
+:801E800041F111111E211F11210114152102141C2182A5454AA5152084218181A111121AA7151E424682C2122D525E121A24A441422E522F25B112224256262B42181AF1121663C3122F217152F242622E4227242556324E522F25B21266252B24421F13F23111222882183A2221A11122223A22A1772E311A0514182A83A1311AA3118A41
+:801F0000A822B8282D223AD321A331284A045A25A1751220A1111AA111382AA4552B442B4227222F23B342F61311521CA1141AF352722F21F1A2A2D066D922D222A255186F61F312321AA11127242B664A0665F642415E541AF352526AF49A741C73219111171213828123A211807121B111A2131E111F17B33171111111A1312E311F1331
+:801F8000E113F3311112821C7231A12229C1311F12B121A3514AA5545A2525A71112181AA1111AA3715AA54523E426B21283B752B113A4141A25E52266252B21A6526263A16229A1111AE163B3162161254AB622244612B442A5351AE625F16275E3E813F231313E3115011AA1231A21A1113E311F13A3331AA1731F13E315511180A113C8
+:802000001F13B111F311311B11882AF2812119E222A2333D311AA3225AA5555AA5115A25A111121AA1111AA1773AA5554E422AA2122F23E325E73121B551A5145AF772722F21F122A225728686E226A6551AF112324F43A3112F21B542E426A6442552424E424B552F23F372527AB6BE0110018200001200220018220000188001000000C2
+:8020800000208104002001122001184800000000420000400200A021002081040048001260A1A128121902200100121112201101190120011B2122110080621220826112004A2121040000202184820180A212800118122A148211420280828421012004800400A01220F67ED3143E3246E1237141C1121F14E221F141211E121F16622910
+:802100001F1622F9412123D911B292B521B292A4222F1984F293412AF293512AF213412ADA13A4B21D412EB215E1237B41E122BB41E422B941E421B941C6921B662CB16166281B2696B261F292121B222F29B421B292A5222F1DA5222F1D24F292414B222F15B424FA42414BB24E414F22EB14F426B24E416F2229F426924AD426A9242D19
+:80218000924E242D126E242F793B9819B32294312F1196212D4119B11296112996912D611B921CF621D2481D925E213CE814E22239412E9313E432A9852E831B14AE134E22B6A324271B4AF3B241F0B241422F19A6342719622F1926F612614AD812A2922D612AFD1261882F14E212ED11C2C21B212ED219E222FD41A44F22FD4114AE5291
+:802200001D26BE421F44B2B4F44122B21764BA44A6694E269664629A7444A2214F22F9BFA98008000000000000200400000000200800210000000000000000000020021100000082001002000000001004108137FBC011004001100219010011000012121A0222120022002E1118162104168121A4410021003A0442120028000022002145
+:80228000420020140444000024200400164222016B7D284AA8A2308229011400202202212818130822209211002603000000000000482081012248220014121821208211220480022842001A228C2412E242010040210211112E88C3021B1AA22E82100114001E2100244222001982A1122A2121A22186011A02211A229111001418482216
+:8023000048188081822702122024321210011E22002448A2200144124726A04224224C012A0441194252121681F211944822009012001002200214402109001400400200001180042001184200210048200414120028004800008024220420080024000080010024F324044A0100001901002200120000000020210200002200422601001F
+:8023800000124282222880022160110000222002000048004664124602200100200442EFC20A12220040810228A012A0312414260122288002182A03002082410142C20020812884A124002220042118189012A042A04380052C86A442003A232404002C04A0140000E0C2348F00000080822102181832400100228002008002282041A1CA
+:80240000248A04C021004880A521488A0222602240023418282083045A02260242A0342A2404904220848184018004685F448324A14212001400112880022418268102000038381800000000004218800800002848008001121280042800004A060018801434214002000000C0437383622228280000120000145800C02100C01224808837
+:80248000A41200138102111800244A02100220022288C84820010000009A841802800148202182220242438A24022800DF330B002002380000004820041410012200802428210124000020021122A0281800284200200448400180820220888284B412012400004280024582012C022E7A410000184800282223220218002120010000C0D0
+:8025000021220000002200180080040048884002000028188218422400000042A0822200000000108281D45903242222002812208202C0411A01241021032220011C862221021C01801201602120042C021220248C88040048A01288A0412829244182024218482C082A022A06488841422A01223AE2343F34280080810480814282020044
+:80258000000000401202800400800220810211008A04002822282482001800002002880000424820820100000064401202EF8F068002111420324180C24220021450110042688092112800222823A1411420228502224200A02120048081020080041A81880448400200A011281A842421880420044222E03833D24229169162904212219F
+:80260000221C0414301200100200210000000024001830111681210248120082808C98428088B84208002B24908249480444614C01444368482844484C0444828644122412F427C5200211100100A0880019C112222C013C2241032682418241226118880012211221142B441A118212223182182190423A012001200118002212008004C4
+:80268000483200281A010018280058C096131C91210024122042220280611280842A04200218001110A11813043922512100004022218444022A0800984812A082A08280012440E224AA182009C042924880042C043084295442F033E64800268144A141008086126212184081034240810220A2182A110100301180342132A044208184F5
+:80270000048A84098A228888A1984828824A022C098A0242C082228888A0288880A82142A82089A882E0F538EF000080220111200800424800122001000088281800004820010000001222002C025248008004200100A880014E12222081014200284448004823786306000048004011020000211C0410220224221A4202880014280000D0
+:802780000000000024000082212004218268800123941488488841004C24C81482400412204C22C219230B480048A04200A2800400A02432420000000000882001621842482A04422084A12542482084041142802C82062A2402A042220048240020028280248404C0812AF47DEF28312140210229860248408102200400110022122A812B
+:80280000220813012301224810022120A224210088481820024A021822114800008223081230221800100221204211C64218C0835329B22162121942B17164211316E216A2224215B1232204A2428084812463322A21A1233219E812011180031A95612858482AE524A4442B4162298A813E725A4A818985222225238193964A14D22204CD
+:80288000218AA1728AA1124CA156A0CD4248B21721242F26E6323432CF67C3411724145021421922A5241581682421181D12142D121F36F14152112CC22124222CA1821722251111A114241611A254258132122127229022182B292223A5C42B3412921AB812E224A8389A240E1AE2238A012B224BA244C83A8189018A87A992431542824B
+:8029000024A5488830B1CC328F2CE22484622413C4124AC222282B884AB821A423183810A1327824199222A031A012188A22E82888E113E413737281E53462157A252424A511A0148A288C38C26882889242CA44A2EA2B64CAC4C28243E824B414B28298446EC44592846B498A5E244A18A442474449A86C4BC84463ED4CFC8E9D8044424E
+:8029800041C24116A242208288042691121042B14201211082921228298112210812111E22481692411E22482448168264214824002A140221304222232432420041424902414241701402458274840245820448E04284C8F373F281232AF6222335435131160225F2228288482D2315D322512225F241122D1225F2321215532225D2226B
+:802A0000012D121D21828212502225D222F423211542D222041E122E222D422A52222D82CAF8B2922B9D2B991F19F9B2322B952BB18AF882832B132B11BE129E964F46524447428E844F46F294944F63F192864F4CFCD4F64F61F112926F45F5464625B296E938A8C84F48FE16164BA2DF6E84B642E2227222F2224229B452D722B662621C
+:802A80002229A62E2E2229731232421C62122F263143381E2137222B222AA133B6D212A2832429611119B121E323F542723AB762F132422F2694422B742F22F142722BC34AE828BD92EB23ED2DE93DF883B22F2BE53DF391E22F2CFAE3525E523AB9B2F99666672E2B222B816F68BEE6A9B98E926F69B886BDF2FF92D66F65FD14444B4608
+:802B00006CBDD4F993C24F2CEA2AFD52F43E14D3D631F222422E211D212D431F11B43286F422222F22A8A22D422F327223C15220F263113C013A531326A2132AF122822AD31173816128121F11E11323B412F521631B512B26682D421AB522A6512D42C8C89AFDB2D27E329AFD9393BA6B243EF12726EAEA23E521A58A4B996EA42D422F2A
+:802B800022F38682EEA69AAFBB4B892F6CADFD2BF86F49ED2CA4644D442F49ED25F982C22D627AB5347B9EC7E13F36B663722193431D511F25C7622B262E8339EE2EF442223D331B1127212D211F32B471755292323613F122222B123E322B131E212E81822B181691111F22F732524E713F13E726E523B44284E525E726B142A763EE42D8
+:802C00002F2CBDD2ABDF2B9C9E911F29BBB2BD52BBD1EE3CBAE2B452F732B22F6BB9927664B666F222842BE86F4EB9F4EB6BB992F4D4D44F2FEF2BED45BD56E464D426BDD4FD92C6CEA2AEF66F6DFFF276C30922008008002800112800000000000000000000A01422004200A0140020240192200980248124080000009820248209882067
+:802C800004880020F47F2D485011221C848104268188068001400122520022182A8281021021081A92411200192401184880822882298421A21820015AA82280C2128084522280A4A8A01120A844822021044812682F28081E9143F641222B411F24F2124117242F11F461122F1166262F19B661F812411B922F11F621922F19F2219227F7
+:802D0000152ED22B242ED233E522BD53E232B953E232B141623A1BA4BE411B342F1BF441322F19F441322F1BE424F392414E122F19E426F192416E922F11E422D912E626D912E622D912E2227942E122BD52E222BDC3C2D21B244DD21F44F224521F44F284421F44B294F441246B4B1D366B491F64B296C4A66B4946B69264262B6943F613
+:802D800092644B826F89C9412F23E114F422121F127422D211F612122A94921F16961266F182121F16E22CE916E22915F1C1121B22CE52281F2DA5221F39A52A1B483A32132BB833A4B31F14B432FA41412BB119B412B961B43298412B811B422B191B2223B96176927221612D6AE22934211F2D3121CEC322D6E142F2D2418E242F1DE47B
+:802E000041FA52412DB427144C6B142F41E914F42214422F4AA9462B9249D426A9662C39248E5A630F8200002001200400000080010000000040020000000000000000000000140000000000240000000000440014F03A6188301125010022142908230248140022002C020000001081818298230018182A012001202A8728060028004864
+:802E80002820868181342228004A8304006048128282001280042E4F330F821400001601180024183800112800281423A2283C066621081400C04116C1410011004200001A2884884802882100008681014800800A2094244822144188244817228E21888F930A1C48D2110200221219A1284082A46100141C02242A028088188371410174
+:802F000080D2129822A014111A81228101808A220182824A8C4822422128840620E12908182248A0832302C02458805241A018B0441231C12EEA712001000014244002001901220000409122224A02288260110040011C84021100488004681800000021220040A1252004004200488841A882002440828278BD8E04462141011501004872
+:802F80002082490122000000180022000000481A1211820480080000002C010000002C012C08000021002850424084644200004800DC2E1D12C142A041185822002321E111140216C211230321B023A14200182860122228902100141361211002112238601182C8A2882901220028280048404422A4824921026200200129458208214A40
+:8030000018F288E960144622011304132402A01522301280C1320040B231021200221C0200B0210540A151008814A022001A8888A281208102002A022C0840043042202102420041322C4102402224883E6E2130418061111800400256211831321100240042003800202202001352124002240020011420348210020000290120041002FB
+:80308000A841206222410042444280088044F21F610028482A41410240210110112284C1213011000040210812480000800C802442012412460321804922948280C2212301004AA84282003012908400A02220E2218258260041C0ECA34D111182022002801402902148004214101221018088A112822001005220848482042200228001D2
+:803100008004200411000046829822A0282CA121222302004A018826440462214A01A7568005000000000022800200004002B022B2420442601280382200008001C2210028800800A2800888620021004400004024040044000000244E7FF34B91512180413122001611021CD2120222186601101241022CE212A41422826011E028024A57
+:8031800021044848188E4123128264122418888A11C2228842822E128A06C042214229122408124332824480A216B014584282A0242158481F290E0022420000200400000020010012400248802402000082428004800124280000880028000080220C80022880820400200224104204D0923A6424111148214220642246014211429012DC
+:8032000011421A82026012860148809121130400A09440116114144820C6211C1411B18132411414860200204402242C460419A814144825011180081082082C082288AF69038004001119028002000000001022110250121A141122925114141001240014141800284248008210212208864101204803100400422908821188214D2200AF
+:8032800000212D91E3C2110000222C32112C010012141811181400108181824A0100204101242211122118330411114200581A040010C222482800480022A821000020932234002001902222226F640D208411810128800110010012108214A14180041A02218A8808A0124200222002222888241822860280024E210000212028021001B2
+:803300001288412A482202002022020000747316022100109111C021133211404201421824320068141CF882211426C1211C41C11114368168292200202424822124043042480050122190813041482120120430444840A2122400822418298898442CE2EF030013C4532258C021800122130130420090121825C112002C22182208482850
+:8033800000112A0100221002602811862221082384021001271222214144230812204263428008002418888002C0FA930E0000132502200100001100002130123042001002120000001391214001181400100113082400200224222100400114002211410021200800003FFC011A082113240420B41102190234144218141224C042112C62
+:80340000A42100240000481A011A1101002B2424E024A2812488122D8224004A84414282088244800200220080220880240824822018C1BC331401A0128E21304200001200800420C3111480242205A880214A0228212821281A0228A024202422984282002924420214302200488288181840220220110224A02840052145021E9C9081A2
+:803480002C9441242D7168271415931119822521D11341122281A1125A41A1251C9A812EA31D1220A228111E5119052AA119211439C241422AA6429E131CAC492B868E531F18388223CA8180382229F222A11B841125862214411664111120D826B89109C0822AC8129A29C8828E2219D8323BDB1B11C681B431A1485835A1131E124A9362
+:80350000212E211331438031411D532C61222563312D332C756182F221218E523D23192681F4212121E21712142AD21151121354131B426E522A521216E2283442171435A24222391112D2229A816A22086F62A22B158144E442D221B422A2222B221D818098822434864252342AF2AB4C242114211F141591112AA4262E211815011148D5
+:803580001D111981814222E221C4514E522A213D422593A198869121125E1137111F22A8333E121A042113B4422132214E818E4352324A08243F223422A084407222A1446F245812008222AAE42434211C01672821212744292842A228224726BC34BC250121422113142204001112244002241A021248802401008822184818211823027C
+:803600002302214229A2142D2142860196216418C021008042218854425041504150414811908100800888800841F032FF3C711253232F24F112123F39F513322B1727212B111A42117111533335D3337112D12132127011D332D523F482822F29F22222293222A6B12181042F23B2227892B2227122532225D322F443233F14D333724316
+:803680007383F38343273C371D3718373825D222F4421323113222281F1AF2214445D772F2242517525D2617121D255F32D443F227B11F6B7225532329A4842CE911487286D666F644266F923CFE3F21511325B252F782422B5135F253532F21A3313A53111F1151331D4335F2111215E113C3121CF143533F33F361A32F29DF33F82323AA
+:803700001F127381F183231217353F33F722222F2BF982A227212F33932225924237322F35F433232F14D43358333F31E914D4335C333F22B263F41313702272A281F8636365D666F826265F4253557F72F221211F26F623237F52F2B3337F53513325A2EC246F49E11171827686F266466F22F25AB23C711353212F24E123F113531F21BD
+:80378000B352F312322B331AE3116113173135714353133F31D123B213A31216F313433F23FDA2C22F29F2A22229A283AAB823A141523E333F12F891B22B1A17232563222D424E233F14F751233725373A3F2C71C233D33718335C322D632F267113522223C2A1AE611F4654343F78F227213695252F52F225654F36F623266F12FBB13658
+:803800005733312D422F26D822F9149223F182242F62F446262FC231A23F3151112F24E415F552531F15F573733F37F732323E113AD311F211113553112F21D1117111F132321819F141533F34F5F1A33F3DFF23212F32F22121A6F1A123123F15F431723F33E23BF9B2A23E332F2242F143421CF423235E633F37B6C2F6C3C31F2DF4D3BE
+:80388000D3CAF4838335F223233F16E41151222F22B2A1A2AA1F165666757227B62452554F32F221216F46F623236F72F2B3337F5B5B33242F2CFC82822F49F912924F28F8A2A26F66D622F2487F20010000122001000040810120028001241001008002122019010000002200250200242224400200000000008002230121001002002D4C
+:8039000015630A14132411A141421C12A1211128190111125012301230131CA4282EC331902390A180E11214611A11221901421480A614824223A814822421110060222348B142022114280043022A44022C09002C388218E02218023E751CE422B141E422F141412CB141C6121B642CF141618E121B649AB141329219B29295212B5D2AC5
+:80398000F2D241F0D251222F1D25F252412AFA4241AAEB14E423E914E4236B143EB24AE422B941E421F941612CF961619E921F16E229F961619AF861212B891B222BC91B222BC92AF2D2C1223F3DAC222F1D34242F35B424D812B4A4E914F4A49246F1A49246F1A492424F6A29F484924AE228E944E228E944E278318F1B242F11A4242FF3
+:803A000011B2417212217612217612B161B812A4961E412EC21CE42269153CED15E2221DC1D21B212CBD51CAC21B342E521D82BE4219B382B441B3A294112B4B4AF282614A739231412B291B942B281B122B691B168AF221528AC692DE213CEC1CE222AD2C3CB583E212FD41A42CFD4334AAF141869E421DA46B491DA46B4119BA92E4449E
+:803A8000BA1686FA12442E841AF464822B494B82DBFE800800000000000000000000000000002100000000008008000000000000000000000000000000000010C18263051810011001121001C2190211D0120812100214584031232002140016011420014001800100420022000042105252422100008001160280224482C12223C4121825
+:803B000088CF3B041948A1518A49010048121001188031222C0838212A028848001011A111D01284A44222211C140231482B384829041B841CD2220840A1244820D2218AA284160446E44448240428104414624470820430111141114D179342A118E01B041100185810A14811521042918320C12240A11882E0210225011C41C24178681A
+:803B8000247021021542E124A8212C051C2468264200191481244231822A6459432CB41464482904800329118494242BC26149612242254441F4896A001412204901001400200219E2210818282128004A041501112A0100100111184200008004001123880228004828241002210041001004210000701112A111E01835451800100118D6
+:803C0000144A813221121502242100100260122822200222138404202403140040911180C141228218000023018200242122402124028A04488800800200002088F1694F001A6114484021449112184E412A6214A21132112128124A8194522C051A042242001C8308312B3130116024122210222A611223642A822400282016820A112826
+:803C8000C0442845E442021D4428882564224C8518A244282460222C351800481114C051C04222681661161312810124C0128091435A220628282842426011421A22C111148014220323B16188833A53A882401202826840229A211001484C32444C42212C22082C82048004242829F1A35A182021810400191121B1114682082562120066
+:803D000020228402B0120142481400286028112902128011110100004002001220022110022848442288222014042912C4142C8804208208BC3F5D002992211200243041A222001A048062110014212AC42214800100108222814412820A002188424A22023848231882021180C222008848226022488800822822242003400229085F3F8D
+:803D80000E1D2342112286812201002190112064221C1412010018230829011A082C1101100120212222014800138A040042A0481D8214218631124818CE4282805814232162264C820224002982C8848018828232D7000088402201000014000000208102822248002A04800E00420024824800000082210024221880042902110020443E
+:803E0000018A0200188A0282000000DF75011C2274230112282041811A22C211800229160180418221BE82924112884818118823A612402235222412822460182AA244804B42022974212222C1512225A2469A04A082B021846A242E2428A0222B2123882801801812C218E31D110200142C1102480011800110820110211222120200282C
+:803E8000001001420082004248A0488002008288218821882122003148102464122008820010028288212028F217651442482034432CD531841492422B4914230400304180042904884AE23401A02817158A222401806821200422232288C142224280022A0220028008882906186221216026110022000080022B28886C386B8024010030
+:803F00000080011C0110010022001304A82400282028318228111C2282942100B04101A2281188194891412100000021000082132804001440812242422242024002EF4F8112021880042001422440430111120042238291121814200410021916011612014A025800122004808408882D420046A22821A024112C04000088282002212006
+:803F80000849C2822888422E7C43A54129211182C41324008822901148224800111400A08422C021802308928229924100920000489280042E1100190426918320224401418288D01482328121142415028E24002823090022F0EECF406231100100142301200658001681810223041442110011A0422288880000E024041A062A021828DA
+:804000002388228842011F2822A422118A24024A02004A82022841460280028849B18208A84C84D28136FB00424A11C142139411422413C1124214F012412084044092210015023219C141181C041120B4210800221800002001100180088800400219824402450200420021C06280020048EFCD0B008041810100886220012222002A0425
+:804080001C8284C212424221001001A0211001229041001001009082154202420000280010060040821241712202100210220229D8B23E181442212112004212134501800412004032114022214A22022A08888021014280210100A8181800888A922220C222804A02291882622410224222222222C42500218AA284002142001DDA1822B8
+:8041000000202201004001002024841432212A440100228220012B16B0412882C221520062005602A061281002421B84481083F482412A041384B28182240131004002002022348482008C14EF1596521AA1414E511523E431A1114E939AB412A414463221181A042C046E6127321A3421DE122E223B2228881F12A2A21392211B28424A45
+:8041800082BD81A12123A412524A8C82A2312AA28A26B281CA2248422BC82B481322E416A8642B222A4286D252BC22C2A129D2331A32222C120223482491A2886EA21C34227F1AC5231A85D421B4139152244E412C7443A2243F1334113384C421211E411B642862124A14613766A21414144846A1442BE4121C52214AA622624219C121DE
+:804200003A81034825A2141B8130432C62323B223302F04282248865E22874216218232204C06114291281A2222146A223A8C064884EC1D240D222041129F511134820B141682213D111C4311601C03123542213D423A28D2A7841613432AAE228E91DE119E911FC32913817121719162284A4642CA43A8E935A9141CA98213BA4223712FC
+:804280001738AA2CA4222F28BAA2D821061F14A44413A256622417422A64421CD61416E3625A22882F2CE8686C282D22822DA2A84FB30A4800211C0414213012100221901210024230412818100100110016022448241124196421196421111211888008004A08004E81601441144146114411044110044130842008824C0474D3F513137A
+:804300002F2154224622D8225722009E82AACE424AF541412F31D133D111012F2323B412D12244D211F8A3832F24F44262288AAACCBAF8F1C113798252221D412B899E833F35D511F413412E233F3CFE23813541E315F5331217222C582223F2428227242CC8823F327243B24356541F34D423F247246F76D2133321574267721D613D44EF
+:804380006D24653622216D462F21F592122D8665F442222F28FA5EEC1CF6215225F252313B572C743392523B542D513BA5AAF542511F35F443322B2726B313C4523B412CE337F623432DE11F2FFD92E12F2EF442211BA98EE3CAE81AFCE3B32B3A26F222233F32BEE1F6635337272D124AD133F9F3B28E121AB143F9D1133F19F2A1222F10
+:804400002ED222D222D42338822F18F2A3E23F2EF281631F12C2647F6EF647775731274255742575257322F72761776447222D266F22F822866F68FDD6322F21DA62D864FCA6A66F283E1E2F22F3124227212F2493922F31F552522B5529F592C22B982D122B542F34F432731D111D113F34E417E526F432323D433F22F2B1E13F39EC266C
+:80448000CE22388AE22CAAB9CA2AA11227223F22A4B93BEC2F35D722A45139E13EED2AB922F2311213F2939317388EC22F22F223233F34FAC28123E22AFA22232F3CF8426219F242E36F74F4661637242653545F4242F121617D417F12D2227222F286A42CF492D6AE222F28FAA6464F4EFCC2E2EF6C89A7562F24F552533F27A5743F2405
+:80450000F143123F25F412D33F2DEE2FF673421B411B341F33D113F111433B343AF662322F37F443432F14FEF1F22F3BF6E2412F16BA21EA18FE8271FEF31F1BED3E3BB22E616ED1DEF3FAF5514119E534A7B63F1DFB83323E712F16EE3EF193211F28F2A2223D233D433BA4EE221CFAA2E22F3EF6C2632F42F645622F36F462632F67B26C
+:804580004762121C7221D534F223671F747221F626222F6298862F28FDD6222F22F822A22F26FEE2A66F9834394A4101E0240119014E124082724102111A0200298284A2428222C04100A042C0411822601242000080091828801281022100002A0422A0422002002220022601400280622428245FC3438181141241924140C1121D418AEB
+:804600000124001421704282022839041F2904142A521182E029028692412C081622C412422C28462202428A0800C813C2822220B28224821484544400B0248254241004490841A0884440F481E393B741B21284F2124117242F1134212F1164222F11E422D912E422C9412E9216E12269142E92422ED213E532BD53C2921B253CB14162D4
+:80468000281B2496B14132921B342B491B342B4919F2924113F492411B162F19B461F112411B922F18A4968E412E9286E122691C2ED2422ED233CCD33B2C3CFD41243CF143248E431F44EA19F441A42F19D441BA92D441B292C4A42B494CB892A4822B494B862B414B825FE5C2412C61142AF161412F22E11482E11492124A32921B242BD9
+:80470000191B242B1D1F14B29295213B1819F2D211283F2D051F1825FA93413AB813B422D913E422C8413E924E413E92142E921F16E423D811E621D81166211F16A2991F14D622A8242F2DB841B29298213BC519F25283281F35081F3D34A437394B831F15B4A6F943414F2A39416F2A7941F12492426F2AA146472A49F296124E648E1204
+:804780004E648E669304820000000000000000000000008800400220040000288001000088000000140000000018400220020000000000F0D2B3282848481814A01227141A412121A42225020011002400131111410100114021984282421A840100206212181082011A42028A289542222C84448204208222A8224A061302482400008255
+:80480000A2E0381D072B1C2001241214224AC282908319A88130122C04284810221622262192221418621A6422001D22901240227811021222220024142C8801200222206246101412046068418092222C82644129A82446624414286F41022A2AA5641A0139E132041B134E12114622B8833582805411004082611429A81618262212A1A1
+:8048800021236414222094133052242A08312A82826221807412A1212368118A612828422A14C28480414202284C74226416C022B02206474121482B2841E0523BCD1002000012808208138202C012218082140219021110014001122C1882A8420018001220110100001002422200A0422B2448442244A2200822282014028262A084801B
+:80490000F83AED00201101001501480000D011020060210000000028A028114001481A01001800118222002400A088220000122200408404E042022004004A064880C4FF63279511001880012C0120C422312100110020C2313C1241A142221C06881C84C48228298225024819E1210868221811213800303218482136228801446821612C
+:804980004B2420810A0028496A444E1240226628C0223F928F0113210180011111804442022119121101002217131400623021A088146A082622A224421A0413311228281182112100C022188A22CC122A0818440010121404008042A448490548202288F42276638204408101002301488042010000801102230211802204281304241071
+:804A00002121010088124820810238100212002400122082461284064AA182284902422240829422482904F04D1D0000221424004002802824040011102221042286E2222211420210022A04214822122480622400404262142123810400122048224A04281E44448002402469241044864604C0FEA30D4A0228480042102201881258002E
+:804A8000114641023023001B8280218C924212302200128A8202882200002228888A8488022800901220820820C2120021A0140022204212044022F45FC328100224000022100116010022800200002100001001881110C14120011200280000200180088229044002204202288002408246021212280080C273A3233262004041022810F8
+:804B00000188480010214402304110424162222B4822192411C2A24091121B4A58206822A0242602002968291428A06888214818822902101422A24230222842909429C21244212C221604486F2C0E0080140220440223011A19218102002229811282022A0200004081820400A0110000002A02C08230120080012140A2228002441004C2
+:804B80001890224A0420010024286C36542880324318142A912100800458221122288222222C24810214200152824A22180231200280028A010010021829E122440218180080318412820012401294444424411A220120418424F1F33A00180046020000622110032123041002483400400280041214001002301220012128280080020036
+:804C00000029021A01282022912241002200000024100240C463D30A2400A042212100122081210118112A810288484A21818401238222611918A224280024122C2183A2281888120000122E42212042420200234222023024A0422911022821215821242384013FD20C000000002411100121214282241073120313082125428168110042
+:804C80002480020029012240025022902212212322044822000010048222008041024122414800C04400C0BEE1230972481AC4421AE22224016829028001282200426230224A819421002A28052C522100222001238102800200120018001880C112241218000028439116442100901243911220C2144B821CF17EB5800440010030220032
+:804D00006012002304230419020000488223084A020024000024400200212A42820230222242281828808112021604481A0120822CA1254A24024C04430120E424326E8012012C0200204221042820020000302242140022001124140029020000108202108202240020022880021002100220022228800142000000449DBF2043420200EA
+:804D80000024184002000010C141A8208A0468800840020012A81A0200820040021224320040025022122022321669022849880190223046472241412160222CA12482AC31A2004641C12114001228141C022868482424211C0411111331231B821D82C0321978A13221132A820224218002200822001220834422021C0200002888214B8D
+:804E000012C026000040220428C014522021F86CF3382AE8147122E21461342943824142F171232B1221166221282B44A0422CE426AC4A311E411B412E41154222AADD1BB8621F2A2822F221822818182D121AE121A28828408262222B322C9232563222E021216323B01261222524210122F024324D2223B452D164A122442B13485AE38F
+:804E800061E64194E417499E16C39412286E4134214681B32184F121222214222D232A62228A227213F222223631211B2A1D433A7481E1238243F281212AD223A112111662221E22282C012422242830822C43A21229A121286AC4223250221E221AC2124127222DA44562421843C212446B212582B44434122D16272125E221E421A441CD
+:804F00001AB4150510E21184B4116224F02222808524C47158142C41B32208003B14CE7226127242A284398A4621D53198223D2224282421241A68222AA82125B232B222C3121A01234212C262A0222903122849B3B4A1222D222E544CAB121226A4E24D644A12B626244404406241224D97A21220314112172412A0210013042001000082
+:804F8000C04123C841121400881C8441410200001880010000000000100221000000000041100440020000224422D0D981A3722B262F13B151E114B161A2735A83C1222F33B24162222F22F232222E222F22764292422B642F32F221E2AE231F2264111F267442F222223C9A9186D123E818F8811137232F2279925222242C7882D22268A2
+:805000002826F222222D322D122D122F21B132232394222D222124121E122F617316E241711256262F42B464B984F122122F61F334C6C229F356446D4625D664A46466F216622BD1FAEB7B22DC22E1277751F221713D121F15F332222F26A5123A71737263A1223E322CA4222E222B4627322F26F462623D636EA13F3747F341E12F36F406
+:8050800022328AFA61438EC11F39FB82831D211F31A122BAAB221AA2119AFA12122BAA2B8A2D222F227232E223D222F132723AA3624E421F3454221CA2312CA1332F21D366D926F1243625F24646BE9436F212322F25E76DBF52F7147647646F2653662F64E425F522222F26F774C44F49DB2485E223F662323716137751B343A3625E223F
+:805100002F23F122223F33B2437222F323222F27E222B222E624D223F642622F32F623E32F3AF663432F11F4E1414632322EE13DF1AEA11F3AFAA2A33B1A122CF9B2222F227132D2227992D222BAA26A282B222E2229E322F3321223A7333A66261D322F2213A2112F217112F212266F6BF33226672369B666F994144F23F332466F44FF67
+:80518000D2364F41F356666F66F462466F24F544524E622F67B416EB49F9B4D713AE232F25F443533D633F31F473432F22F162422F23F232323F37F663632E223F33F332322B2227226A7422F262422F24F4C1E13F36FA73533F31F141613F36F422228AFAC1E11F1BFFB3B13F3AFAA3A33AA3222F2BBB227212F212122F2BF832322F2A67
+:80520000AA8A29A2222F2322B332F112322B322F27E326F422232F23F323321E322F21A1332F23F336366F21D366F222266E66BEB46F43F216166F66F6F2F44F66F614766F66F246726F64B552B472E624F566564F45FFD4D42F7109280048002002004002204222420242224602242084020028A02890220010022122822218222122186C
+:80528000222422200222244C428202002880822481E44102212001218028E27137338622214481511218212C011B1400141821002242204881C25111800219A841190A1D82268122021220012188000012242100204112022849810250242840144224622449046024A012214981E416F95314142E124E412E121F14C4121F14D222F141F4
+:80530000212CF141618E121B649AF141212B991D212BD919B29285F292D1F0D351223F1D25F213412AD813A49A1F14E4237941F1329246E12239412E9213E421B941E221B941E221B94162291B24921B242399212F2994212F2984F29241F09241222F1934242F11B424D812F424941CF42496144F2269144F2229F42692424D924AC29252
+:805380004E242CF144248E8283BC41A2411F24E2117241F2126117262B41111AF461821E611F2429F121D29AF42182922E5356E12239D12E5113E132BD51E832A8341CD121EA19B441E31884F38241382F1984FB8261382D412AF982412AF182412AD912A4921CE422CD412E9225E1127D42A19213C5821B242CF951A44D821B348E121FCF
+:8054000064D224F441B463D941B23694819AC4366B29282F4964422339242F41B424F86E1B00003022000000000000000000000000000000000022000000002220040011000000001200104108000022200181C04F532D022084117321420124B8C01190222348032200281846C2842A944200488058416012288A810280881802920030FA
+:80548000122911C22223149222188081C134284C128412A414222A8128B2449886236521451282022E144225F861D4D0119C22181502125829514216084682051A0188004A4286844222046026207211819122291152120000213A22280A2A82A281000080892802241088010022002594821324014904486021502219EAA43F33112422D6
+:805500003E411829D121623430168C2A54214223474203114828224AE12234C6CA12A243212306821683B211826218282260289A32228AA2812828221823048014C1228A028061438A2261411026052A11A6A443D82438142612744422133234218CF27ED620324100211118301220011A01988088024012040020048051114450229012A5
+:805580000000800800001E826021282502290912602110C824800222602220984112482921140200214AF4824253A6141001001002211724408212012482504210C243F024430060128004142C4281E1131428210400111C02822008C0122B2148212419C2122002490400000060644130148800401242F24757282911215122111A21C4C8
+:8056000012A011541A61169088140029A218A0228D24122880420426011931262C82249242120016A22492232588D321824202218A4842A4117042A81241414D280043A222688AA412E6E6828262658F28C8428B411AA9222843A4124E77C3C26214125012A0410018296411241302821400260426C22812190280C221200433012982F438
+:8056800031424800001A1A12011C43820A218828242C41522181401464420020820C1A12942A4C92882CB88A011A8A6266221AF42A7D186011248001242C410217417840092420183282123CC4244861224084021501437222810318890142162284B41122880822248091122B481024217632A4214028C42428002A24A22C25A41446121D
+:80570000B4148421044042C2FA635114496412445416030020213111244820021440022158281B8220C2442829230166B31222024012043813A42400182998448222107E82E582C522AC91112883810A83025F22443414C223421484A12818482C382428E02401176F20440229410422122213012D28681B18428084129984149228184227
+:8057800082E021082411452304483024812210942200800260235642A8482811214110022038144145B812A124001822206484104C044880E2E4329500841200188001004180C23221160100200124441A128402418122824024818A018200004C820800C48002004142442100100200A0944240140421008480029FB94A85548418412094
+:8058000021A3211212188C312123A423A05228447082E12981A146239111A0824A4205241BC63F228146E4830A2741A0282B41132286126422A011C421482E8249F41A24211213450AE08112D49684B1449184B0D224021E248A41B8441842084AB422E2B4333142D02112D24151120040811112E4180223414201000020C2242244472229
+:8058800020D34801204204000000002089C8642C888258422228504A244C82811204C024808284321444492444480222282001AFC703835224812B118112241189962489044C82531B49410481184C022813049085004249C4284565820045044120440245848218E2228148D442814221A28510823124288083024BC21A04B04424010092
+:8059000012411A42024524F584D9C3863432224511424221114281141448024062148824001141244C026410440882805248121781218902312008199848008391188602006C21721482E461C284430100B012422441548242414400A0428C86089FBC4708468A440F4240088414282C420828461214434151640000118012A128118908FD
+:805980008D2880A168440021280000102242082A492232482881100C8584120881210084A02181230480220889E2143AAF12841644089400266181400811148C0120D284612200801281982124008514118802238C02409228831C988885044988512C80024480028081821102200482182241282400A048420000AFB90914614111122DF0
+:805A000028A01244364171446842604418802C829122106844A190182512098908254404287042026C8202220020828A11024908884A01002901184410440442404244840260444004878CB08432BE224A210241142100A043321460222F1284B2310823022508545041441418C0840028E04264480024C0440041428042086908204244A9
+:805A80002311044222C08260428E22A024382A94522A8151C249012D14182CA1C3218F6803236412440070110800000040120140083CC22870418852428912246246440011212F44924810012074250844275890244D1183022B1100244901430221220048441A0123242162244A2401122A04001EEA321C01140018842F146212408121FE
+:805B0000E191042420A441422811830289048168857418811602143121182B4800823022803224200882828A01865224131814122204AC922210321C2A08252402612C042044824822021F6B0310A81185219218411A41110885012031581183C2249311180254222A2248E141042DA860A844002240A24684478486088486384412412050
+:805B800064228598241538241A9248100A8244AB41302248230258202281612210D4426221687C362A8D18CF84F43A2F9F85711F794A3A333B228F9252C88F83F4195885117228588C2CC2372972281411543113F4644183123119555241509885D88C528E8123F16342282058828A5888844BA88D842675263E8A2B8886A4124D192F43B3
+:805C0000F48416166462212F6414942644A449443CA2B042A442AD146F41722252824C11A2616D42CF21D242F684C42FAF092E21632211165281814E11219041457138D51F543239D651A4888729AD22A7222D288782155B1A55F82C6637A8D7821F87FC8C8446E2188A9221EB626B988F2B7442DA23C6492F829622A64CE824C28422282F
+:805C80006D3CB9522890462E49441E1E22461CD882D22A52C249C6CC8AE443A51463B32423924287424A81E42C92222E424E188E628C338F3B472B115145C1141B111CE1B181F175311B244712223AF612313E143B112AE416B454B318F1292525F424644C922447324C0243B624E6627AA544D74192464B78C51434444D422AD482565420
+:805D00004C7A21FCC44A981AF914B84CB116CBA2BADA24F832A92D228CF174363AA3B21AB184A3222D243AE761BC2233246B154E4A6AB514E56591444B11A08DAE1CEE181AF29741800400008440044C04C4400554400444813049104914098304400421811048140911100111291801118841004E184018440884448400001001811008C6
+:805D8000000080D8743DE81792EFE154CCEFE1D1FE51992E192F75D4FA53DCCFD2F63C2D3E14DF57F41C1EFFE1F1361645F4141C4F65E7417127566F6764E5F6272789F242E1AF22F225295F5A782DDFFBD22D52CD6F82F21E8EB781CD415D493FB87C4A7BC97D235F9D4FD2F249491F19F19999EFE3F23DBF8F21D364B284F864586FAA78
+:805E0000598CCF61F216684D1CCD2C8F41415AA2E5E481FB143665F455153F11F1183CAB745AF75A4A45B456E527E561F1C8CC8F85FD521285CE4AAFE1F16E2EFFD3732FD4EEB13ED3317777FE2F3CDFD1F3791DDF45F314755FC4737AF71F1EAF61FD97D6BF4BF574344F71D277D2727626726637A63C77F3D672F663C55D8DBD8BBFDAAB
+:805E800078AE7D2CF42CFEAF77F8262497468F64F8CE68BDE99FE452CE8D8CD798DF48EBC3FBBCFEAFDED18FFBEAA46F68FBB38E2F4B7A98FE1A386FE1F34224A7C38FA8F1161A2F61722E344ECB484F62D256F767477F85F37E4AEB476F22766254244F22E725FFC2BACFACB7FAE22A35FF9791EFE5741DFD1F2FA5DFD97122FB5A4B8FB4
+:805F0000B2F21C1DCD484FD7E281F35D5DDFA3F71F1E4FA3F146466F39FD54741A712F5E6DCFC4724EF62FAF95F54A5BA5F3296BCF4256CCAF28F82D2EF5FE6E646FADFCF7264F54526CAF6CFC6B4AAFBCFC2E8ECFCAF8ADACAFB6F6B4B4CFC9F9BFFFCFC17814FC84864F18F8E4E6CF2BFB2C344FA1F17624C745EDA6C44D16ED268F66D4
+:805F8000E28CF284246B314F41B332F1587C6F45F57C7C8F8456262F45E527E72DFFECECCF847CE6F6564FACF41A7ECF76F3391FF7E3FFB1F31F33BD7FBF87F23F35DF81F2687DDB37DFD3F75D3BBFF3F33F12BF63F5779A2FCDB5447114DFFFD2D3F62C4F67F6E792FCFC5F2F3F92F66BCC4FF8F88D8FFF98722F7F2EFE26FE6FF7FC6EB7
+:806000004457D65DCA6FBCF62AEA3FFCF28F2CCDEDCFEEF4CFB55FCBFBAEBFFFEEFBA6F6EF4BFB96B66F4BFEE6FC6F6FF23E14EF63F4766C6F67F33E12E76167E36B62CBF6CBEA4F6ED242F666766F85F77E5A6B376F83F468466F24E725E725FFC2FECFECF7F2E44F9A3DF4891114089901001981B2488112019128112880020021471205
+:8060800050142126014188450847924243A284200480028E248384021A0216048200481222442A240121220018224A2122044260246024288B94284E12CFD7C4C1212013D124011217821A410128160212E021014A81321890412221222052124117142A0221A012100245C268E08492824C424224C82823C824824423E94222090016427E
+:8061000024614280A144430A2901494318041A2124018A18D481311C1F64F212484E242F9164442F9124F2124943F612494B862D494B929CF42592945F2269144F2239484F2239494D929F44E232FD49244D139F4462389F44A2499F44B296D449B2B2D441F292484CF39649442F9924F2924943F212494B822F98F424929CF4249286F9BA
+:80618000249246F5249283F524D2B3D424F94B242CF949244D129F4462289F4422F9492423D949B292D441F292486CF29248442F89A4822F897424F292484B82BE6A1CB42691486B129B426F22B14D96141D642D129F4466289D64921F5432D28F54B298DC417213D841E21D0496B124F2D34247483F19A4833B456B9217944F426194AA79
+:806200006B146D82424F4329E622B944F284128F44E228F948248E928FC432828F44F2D2828B24AB415D243F29C1242F3C049E4347429E41A6F492414B832F11B426D992F42496942E9246B12639486F6239682E12CB244B988F44D222F948243C359B00002800008001004004840010020080081800000081008002000018000000844065
+:806280000100000000400200000080020000F0B6342884001181D021213444253218212111450D19110128860810C1440026E8180246C1224440091F14021C8849A111B0823423D01281440200272444442224B024410410C425428D84814143744CC84180214402160266826862D35F49EA0112144A91188021C4241C3C2456B288418275
+:8063000082942248601284222F88F22211212C144258812A04222D888041C281108212222298119828442800204428081092418411282210042222212A94282E9485241498226212CF1822F492A828512228841D1440E2454462A44F22C4262CF411C4855A9426613522601881282CE8520F29552286E211840227422A0885E124D211A225
+:806380008815A62216E2214A31E21AB812D341C4624008462114280825E412E441188883821604E3084F26944C2E484CC37841460E246A61A28AE26431DA811E4860118094198001188601804101004222288411842180429829841304508211120020190100110000002124444302100240410411450843021068128800E02201424C82BC
+:80640000783B8C144281011211001244888488222512240100484C1208242024020044604284404802211002608240C882800118228860282824410024A0440022114400400221810010C8185361411321072148121880C11229B111E444212221622846922250141144250438836448902948112B841936625C35418AC488211618E2A8D7
+:8064800084A84B86B222982428230A29982425082820A261116B424126012260C2221226AA422CC21482A0A56A682F2E842ED6FF4606421B111824121901180040B1489324211822214E2200844440028C42048C12219481267421A216459148248308812532888E288A18B28A1884082C08888828282441146C064D41002828410021428F
+:806500002C51248081843122AE248E3D239D16306100422001184D129622210C63018821004D4117425024A0164882004064244284132434821092128024A2418092222229033843120A2420A234002128422250812843C128222C0282842AAC288A44EC21F465928042044086C111002D982041085688C3462A18012492D022596186285C
+:80658000E321820228604890C240845444122100621441482D64884E868C581221194268424A42A424A01824152234488280024A1202A038D022A224F02222E0363DD64842902400478621441A44B1286418904222C11846514A611001800A1884423148290244208488414984324116A485C240014884818846818108C012A12E82231427
+:8066000054482E1210348823088D448042624282411004415F29091012C112002118800244100200200248441061122446080082148840444822522280582200C0A80000000048A8840000008684041014214124240448001200AC3395C062451164213022151214226A864D81A4242628C126E28145A21451311E23512784812628C28124
+:806680002A94824318068334A46C548424A223E441A6C14F18A42800828C98821988048326081AC422211A44E568D484221C348423826424414A9282448E42212245423224BE5D480000248CA411A01146A9110020C124584012C4820060282A2201290480120148430829413112101201008D4121434612440218228AB4245228418122EA
+:80670000250289040085A1188443220420818681022A843DB5182164184812322468C22004C288822AE918240A46B2812481AC4148422092342034214A28A1848062214E81126A880A8821A8282144494815440680D94185AC4100D08204221904443121908221862412C22243C884F0951EA4110000241881342008100284001906120012
+:8067800022004400200224504485421106856A1421C0188C424251120028488002122890288E424CB12886121511430322412C08414122122001E0A83A996051102154212901489604514938881921182138122024384286119421141C6212144B252CF214823CE838A4A41C054968248684A8212264821E4482442E11602821223A3422CF
+:806800004C24A8824084C21113386428604800C90229C2844082822882C844FF2C0F228002204405001220850411428C041912088228824C3298800481112840414818628440422804421028F14242868151114B1210082231245028308C22984D24290188111141281222800281288DED736938C014004200001582014921888142024EA7
+:806880001426038091414B8448182044A12182221088341123282834114800A813982488A0838E4411222445814802144414002120611216152428124402C80024D01478C403222480110140220222841121008048A2128E2240020082E0418108492412140828000000409822D08203812002231824084B44203CA2822D480084112502D0
+:806900002622A28800412249044C02EC3563180012105258241691218022010082844C42014821482B8124244444241642512942862272384414484168848128861141C88114242541024184508210382684C1178241221508008260110024000018F0C15F40141101122012482255114141112140220240010022802802158104802402AC
+:806980008200880044281004008222241285023D22882022C112441022814204212A3814432261A1442351281A1282E4E13F3D202141C12112C4197111022308144668114816C14824254521F2A148221538225B82D0818122044210017912086C92128742001041028291A9042608142848405414C0812C84414D14848292121425C128EF
+:806A0000822860428200223FC4C12A3B8125034846A2342D13F05391182994818F24188A089E812A84A4421BC4112B8C23F694A2614E2411CD174F837D14E2A696468E428A66AE253124EDC1C69868C28B2126CC812E443F1361628F88F145229E33571A19728E5468A6E4687CC598B867458D2AEF33DCDE74C822B12552118E137CBAA1D6
+:806A8000781C039E1227A22961822CE127D2447B81F4982763085D15181E211941D28253A413F466D3212257411CD8218CF8B1282D82CF22C24619F8218225A1841F98C2618F1702144260521B682F38E4387488F14425C7229814DEC4B7884A04CE82AD898B8A65F321121D8A8E2BB012B41282712133B826624229485414412E244F52E7
+:806B0000B428711234264342B627F2A4A26586D844A852242C880ACE444FC7CB112AC11465A1111D511658811F2123C2A1175843F1114C5A7911A14119E424F981261E3A23A3F689B211B7424495164F1AA2221F14F26151B091F2242D16D418FB58129DC2A4E5B212F12328A6041F43522289AAC81D8226D144DC427226C42A2B162CF4A2
+:806B80006211C8EE451FA2F862118C727152932665D86273B326013B185DA82E8443C18629A2A2109A242E5122840000420030448220012301926048301830884883914481108894184181414A084A411158144A41214405869411868421981882188041843581581308800400124081488848088440088440F897611CF12B12AF7171173C
+:806C0000D111F111153D213F2272245131176445D154F554431F1C7191D111F1B16337366F88D48AFFFB4BB7A43F1AF26915DFD9541D1D2197129D4DCD944FDBF62F8FFD877FB2F86B211FB4F9F3232D874D8ECFB4F95B81A792C7C4C7D2F55567ED155FD9F11D1AF7197D327F31F122B4E3D8E2F99C1DFF64D1C4D429FB1311E78137D2CF
+:806C80001FF6722AF511198F917118A1121E9316FD191997298F23F88A9A2F81BCC8B11AFECC1E8FC9B998F8142433F9153F1E1B5F71F131211F11F455471F33F323357D557F59F5B2B455F145457F7494C113F889283F2EF6E2434E422F2EFEE929AF3CF2632B5FDCF848E9AD292E194D2DFFD6F68CAC1F36F68747A7B42DE38F92F88A0D
+:806D0000CBB7226F7A7283D9FFBE61F228618D28DD8D1F1AF81E1E3F1BFB2F2DBFF8FE9337EFFBF936226FFBF814168FBB79DFFFD787DF84F812F72F71DBF8F2593DEFA6529FD55DEF5F41F324266B195F1AF3BF3D6FC8F382AEAF49F1CCCC3E3AEEC84F23FBBCB88FCEFFD43DDCF3251E37717B111F13C45345D131F331513D57577D477D
+:806D8000184D154F71F4C513371D1D319F3BF663667B6C2F24FFF22B35B38BF8E11C5F5BF4A529971617D15F52F626DDCF5FF425E77F52FA27EBF7347F36F9F12A3FE27826FF4D9AFF85D881F448255F62F826A77FE2FB3F255FFAF88F2FFF5CF39F25F7783F61F8871CEFC1FA8E2DC75D5FCAF77CAFAD1F6FA9F1172DDFA7525A37D2D5E9
+:806E0000392C2E154F517995F7B699BFE9E863F9B696EF89FDD6181EF22F2DFBB2988FC9FAB8EE83F93933A5D377E111D311F453471F31F137393F33B693F5A3A75F11F15555FFFDF593931F19F9B1B93F3EFEE4C64F67F5FAFABF3EFCC3CB3F35F7D9F1DFD6F623411D25DF52F26D6F1F1BFB7635BFBCF84FAF3F7EFCCBAFBFBDFD3A3F49
+:806E80002FA8FA4E8CBFEFFDD8318F84F425252DA27F7AFAAB2B7F7BFB3B3AFFFAFAAF2F7FFBF92613EF6A782CFEBDBEAFBEF5C6E6CFCFFF8BEEAFF1F33A3FBFD6F74A4EDFF2722DFD1B1C1F41F323246F79F18F3F7F7BF38E342F29F9969E8F6DBD38F3F2D2EFABBB94F9E4F4BF410B250421200123C141401142084100242004462202F5
+:806F0000004442001081129122100240088482222002264162122C280240028D822880522828244C12881201504211441100230821308249C49113BE81036C014280E19142A2212A8882E1418428A812422E82A01221C828D828242841281C84A348248A646423C2148628041848228078822812F22482204275241228024934C8418160DB
+:806F8000440022114302C0A2A22443082002228644F1E8EC144F2231484F22B149D424B149E221F149642CF949648E929F44A2199F44B292D949B292DD41F292584CF292D9442F9925F2D25943F252494B822D494B924E494F23C9494F23E914F4B4928B444F23B949F414929B641E929F44E629F949642F29F949649AF949242B999D242A
+:807000002B591D242F8DC5242F9D4DF4D2DB222F9D34242F95B424F842494B9A4E494F2B6B944F2B69144F2A3B484F2A39484D928B242CF968242CF148248A38D21D242B414CF212684E2425AC122F9134642FD9B464F1824D4B122D494BD28E484FA229EC3228BC2431C14D8228498DCAC24E34821F64B294B4413A864A32824EA42781EC
+:807080004EA44F98A224966D4625B968E858A4862FC9B468E8D9F424C29E4947A2D6F124C383ED227499D4A4B49B82F459A42CDC48E328F541A64D4A4ABB22D448B982D449FB22488D942F88F6483425FC48942F88B22CD182B42CF933220000200241000000000081100100008400002100110000200241000000000081181110010000FE
+:807100002001210000000022100448C01533511820820124186214126C4842024444601290424140184104D025C4881F8248C841846081241082A44842C08820012002290A44442981A2844082041002A24342A148A69CC42214222C824494124842224A019F56039823D61254A21901241F61C1428064824B4E4B81008018A292F0431240
+:807180008A91823062414844002CC261162348614A4E8114001A94424B2130368E81481C41D12241818421A4229828982504100488160423215242828624718202E0222851A419E27835A68136622226139216123C1567248862678452C210083328823141294933842B484157214AF822849041A9B2219489302125A44248417048C2445E
+:80720000284C228828642F1552485115A224E82292622369482441884B121CC9868B382A4CD214889A262EC2B016A224984C325228BFD24C014218460900221A415422288245044130212C446428901800224850981008E02101298884581182421A081A0123C12140013012A015001002008002804406490200121006244210E81809190C
+:80728000115221121121118081822118813421441186042120015014444511220248004245E12482041018220420186148200928408128882C011014084422A04228321BB4C0224302410088008E24241F3C8E54521A43522146A11127224227221244F0541420012440A442D0227245C6628418223441224BC2884F22092F164811E424E6
+:8073000008C24A82848156826027AAD222C1831221B2223A42A42C2C02371225D51844250400412140C8C648A44582D5236821830B4B863233711235322D111C44323123342212004D114818443082D02402164256423314382590252084084A38461C1E810448240060228198882C8181012E9180298A210251244451512084C2341F2914
+:80738000042982A2484484C0518E128E124428BF35024214002D1124800123E241084E1428111444002084342144268401258282126444A6621126024384D882084AA244188846C1642C02A68232832188222AC444822C8252928419842482020022405844214614D222088C824A74423E1211901C100141130546024842422A058908C616
+:807400000300422480081C21041504D02128514342241225048200488E28624118AAF421821068141E8248A4602228C846024834114C31C282004228604248418C8402F0E8E88448122042C154400812848815044663881013311225050030822412411F22824102904220012302C283321224122412206644C0484911818824215184430D
+:80748000280A4918F47214228428A02620C8422CC2824CC2124CC422822EB5430A000040120880A812444082020041E02408306654180048428115342800C081888C014E12408408401104908230220044904824000000804229514228008860284008F0C6BF1068C100C0521C245128428AE24424B844E122B2814812213C1225314680C7
+:8075000052621124114932415B1685D224B288C144111E81708208CA051249C8882E6290144ACA8523B28244E22609C6AC11704438A422C0C4B02151418CBC2298491E2228422225E228A824A4566C22822E7FD31D8184011114400812608111400200244420881492448001480040111142824422C116F0288221B0120412114C020044A3
+:8075800018002304A94222C442442034241880224224084844C0822084021F1B4421C4121418407112E244C44118144C82A482216140144315021022914121488A4101004120C22224882140A22180024B8821C28200302221C23022201204F022644084628490884951489088481229B38808818EE311812B4111128120C2142100840016
+:80760000008122C04118424D22886042444224004354421110045180240110A1C223042828418008002D1500008071840200CA02204802A840088221803224BFCF8104441121244642041840220410B186582213280890821902480082482621A8122A4611D22109488A542246031C8491823C0480621116031848A0264228412442204229
+:80768000C2844286321141336222138644AA848822442243C15541102481C445164164124821C4C0818621C44138001415182112C182E082C12118114C126248E04904542011012848442241108342026A4181C8131141148502382C081400208C3218162228214914624122902212CD3900114C04418004200188234202A04350422444F8
+:807700001848441721421692444983888201803282282D12438401188059248AA428444430A444E0422488C424122212C241408449042584C8C4C084441AB811082200248EE8422C014904802405239144884988D1240250124501344E84004D2128268188943141124121801684924440042260620080088094BC261924E2480142848068
+:80778000A282B02488642221448041E825C86800248460882948F8247C001008290141A11410120850148128904C004022084814701201218308250200800880022044228208421002100100100420028004841002410040820822E0B23647554285244142216412442544C48425C4851B81821F4448948880041546348141A02122212278
+:807800008220661840018C0819083B8210111101112CB2911241422A098048C28216942400282227124041F1285181A911DA42219518851638888D125F1401584012652610240150320021208418381171008144AB82282358121210042605473286322442B021441104272445A42244116048421088922125C44240141132D345249142F2
+:80788000711005224411206C82100418449C3B34871416C15657144AF411411B243F54868454828F9828F823214D92D43F11AC28AB9861172445F3A12517182B2A8E466E622F62F2424429A5894C68224B46CE43277A2F22796364641DC4F02321425F36A216D061FA872249B8267291E43218E529B214BA648ED4241ED424E963E263A128
+:807900008244444754674E15063D184B3A1F4DBF84B112F48E142D582A816842884CF3B1F2B0447454911845D82594124A7312D64214F3864665F4A2C425C28686F41A6421797442328546F612442F48B19C66E21E91282F1231252EA218472B4722B6213A212F2679589213113835D224F923C12BA2809C4125F411C5281D228D622D136E
+:807980002B612C0423C2842417245CC8664A611AEE261698983F32748A942BCBC6818B1C23F8A882EB838F4ADA2AD828352D3721557254D122D52681D122518456F413144911F122154CF8814115A22A1D855548B41C04842F4252315521E114D411287225956C611571251454454188C2CE52B08283D444FC26842F14E412A8229E842A3C
+:807A0000BA1A1312A4588655441B12A78226B54295244D242B222CA24A244EC157428B828F4114FA18828D9416227C9A322881AB31CF23B8CD0B89048144890481800480088841988008844018C498A014200420081248820011921C24412141A1818048810800004A081440011440014282111009118A02828482201804B4C357C59F8197
+:807A8000F1181897B115F94F7B9D5B1555443F55F488885D817F715957AFB1E9717186F664443F61714CFECE8FB5FB1F176FE7D7E2F25535A57E11533355F49114C7E225F614746556467D265F66D689F416542F28FA12132F28F814552D423F7DE714845844676A1D15EF7313F326266E724F63FB41456F6FFF22216F79F945771B555D2F
+:807B0000231F3818F754954F66F24722286F71F31E2EBFADFD3828AFAD7494FE16A28F93728A56CC4FC1F91A8C6F5FC1158F9535591D7637169D1BFF96F34B7377654D157F84788ADB79F395273FAAF1DA113F61FAAF441F6C7997D6667886DFFFF33773FF7FF88F5FFF2FF226633F777427D745F9342CE76A6D177F21FCE7877D272F7257
+:807B8000F666EDCF7EF914C44B3E3EA26F68F316426DD37BCF1F5458444F68F2E6855FFB799FD664F227A44F69F415455F74FFF7267F62F997457F7FF656342BA32F5AF672B45F4B72247622F424966FEAF3AE9A6FC4D12CFB3A522F25FDF43A8DAAED2CCFE8D1EEF32C82E3734FF753192B551F35D72AF1434F3E339F97F717177F55F535
+:807C00008999BD8B6F637B87F71EDF1E957FC9F1E5C56F71F146466F68584D7FE1F3F5F7FF61F357B7BFF1D533F723635F62F2B5B4CFC2F216167F61F767666F6AFA27266F76F658796F59FDD3D72F31F1B3B36F53F737F73F5BF561452F1258557F7AF625356FFA5B326F72E226F734B647447F7FFD2A287F6BF961F42F35D366F3A28652
+:807C80001F66F654B55F5EF627261B223F3BF39F2FFFADFD3E28AFAD7794FE58DC8F8BF388888782AFA1F1B8AC4F3D49FF4353DFA4F149127FB7F45331BB253D7FBF75F445177FB5F89B8B9DB75F79FAA71EEF59F197B76F7BF6E3966F69F446CEE7FC7D17FF73F7F7BF7FF9F77F137F25F463477F52F227B44FEBF2AC166F71F337C67F5D
+:807D00007EFA27276F62F667DCDF5FF917F37F3DF333B73F79F355777F3FFBF7E15F5EFA85A55F78FAA7355F7BF3BF277F62F226F46F7FFFB6655F66FFF62EEF72FB96754F677537F636A77F58F764945F5BFE61677FD6F22DB1BFFBF7FFBBFFE7FFFCDEEFEFF18EFAAFBDFB2AAC8FCAF28C9EEFC9FBBC4563A414144E12004082820185EC
+:807D8000624824103882400421002244261122020022100422004220042428803241860444C024003082488004002220024B4230241034482224414041020085F2AC4A1C4802474180218461147044012824A0181424228E4244405422A05945D413C42400B084C1412F62084C022D86421A51112C4185E14422E8441212A1981110054B3D
+:807E0000221A1444F8242458400200207841C882114B93158828A4818CA281CC9282221EC5621F44F212481D246F9164442F9124F2124943F612494B862F98B464E998F4259296F92492C6F1249283F5249293DC24FDD9242CF959242CF549248E429F44EA19F449A42B499F44BB92D441FB92494CFB92494E942F99A4162F99B424F192FD
+:807E8000494F22F982494B962F99F4249225F92492D6F1249283FC24D2B3D424B949C292BF44C2129F4462289F44A2499F443A929DB62F89D441F2B2484CFA92484CF892482AF892484B922FC1B424F8F7691CF42612837424F268416F23F14D212CF149642D829F44E621D8198698292B8C8F44B21A9C212F8CDC41F28289443F9C28F23B
+:807F0000D24943FAD249436384636A144F2AE194F4A48270A432484F2AB961F4A492C9F684128F44A2988F4482F849649AF948244297448F29FD2124BF88CC242F9D4DE4B82DD29274A4E499F4348427914B8A2F84B4B448F8B49283F4243683F4A4128B466F2A912447288B249E12CF44E2A81608008002000018400400400814000000F2
+:807F800000804402000000182824440000000000001400000000002400000000000040013F51025160245624A411005901244398121082B214021622C122413A14E25201161804202A84D8630260814246311414002840B28808000000A6220A908644800284842288390B31268224410C278542444642A472F326E12C130830422CB24226
+:8080000081B14632C2489F49324380012CC422282D28F082411C62284225088C98411588C287228821242382486229C082284E125C022C23E129626112129E224624C1421A3421EC412244F4822480094C61242AF944821C4144AA8486884202471488FF2146E421042C26514423C54290142F24082DA69B4119041E184F2222B4221332BE
+:80808000232CED129482C81E128C51848E431C2862422BA82123582268A9E668C1142110E2222224D22A2AC152228440B192AA1423B24241C7861A98424CC3A245882851321A6816B22651422881C53C12831682D443E872241C21334820042E121219C124428E44301224008001842D241428265241840040284411312420011021182167
+:808100000812518220817812842121428408482884440000260843C812214E86124A11A2848A04304444F0621A40C2484140020000122229090082282C0889018344941844002128487048C1A4919210022148008A4801412422201202002002281562422140012008002A18010084182A0422BC33998CC4410024181D282E412D118E22B7
+:808180002B844D12444E224111288E122C9C3423648228552266248D22D041428424A828436424241D221200211041C2688E14A26018218A811862244B482B288A9422512341244264424CC88440E444C2848C98244A4804211A2C748228E841F861EA488501C12424D0186432122A01272128230128F012A2426F8104878146D1829444FC
+:80820000251806574280C4482664C4CA41A212404202422C88280280280212212144882B22244430224D2241702444A488443064418211C6042418812C24A81A4F5836CCC04248001226016028293C2441C244118888A082242228412218221002628888141D22864211020040018CE45831A45012212A280846A248A084281419312240A0
+:80828000041308002098284B2800004AA8618100BF69068002660816240284262886C2222064822248113241430714218A064F41C824E48082046512E1240292884989842562A143A22127688B114200481830824140412858422244124092842AA24C118741C02460440022E0143BF2800738248443118162348E1100414831A14A421127
+:808300002408504280188A014823814433822004A02444462432110000002E422D84904C169241008018928218602C2C81041100210042760241508422A22F2147011001121062810020B1870480014100001180D24241121102804834214410022C042121904240081001188A020042234824840441001490844C01448120280882290553
+:8083800048C09C431BA11226A114A484281826B84AA218188E272E44702122B344821424684410123222EB415449483418423B826F1412166624A01446642C2CEA14E1248355844052862992849262292494424D82201C62242981E228149441411D82A24A5A1412438848A484214849A2428237D80042001A012311011D690024001002A0
+:80840000182684211211148142022964420020C841002B8210021200282991288A11612100411A018200411548044100400443C1482181A0442301188480D6913716844088C21C4341C842A0148424904441801421029190921008A98186A2428B21629845A12100288E11200914881A08A88222004322C28420812481128902490280081B
+:808480001200860482820090822448F06F36A0124602008001004800800848141A922248410048220030822100C0421846021490214B8414221C921220021880081AC9842285458963181014181491868722488D128561224904001A0C2E2444442C376241281AC212400230142443024C018E12E043286848901210042A110220880100AE
+:808500004002822100004A81082C2848041A029882132208140028002124002C282848048308814128401822C2813F640A1012344168184504800182A22944228C02504182824800A0182CA28140C222A82114228C088840180424002041648841005014002088584C831261481844134114234804450223B2880200819C36C68B2C42815B
+:808580008483C1118142904A85C2414E1266858B4182858C618211382AC1C88C61822064142E881E451A043220114462111381260318120000002800803C211001110000280000110082886028A084F0863324002248804489141684524220084180E28112A4214121190122824382024222002002185042D0441823A22840024828C20012
+:808600002888202208C1008682881A821884C828802842088482492844E8CC346E44212C8414024400200482400400004002008200180000008410318100244033228110B1A891298162192148195894129410094D2851151C4C1C514893C24140848816C824284144F09ACFD08282818194222180714201278C2C0222142A2162AA20C46E
+:808680002288100819113241184002622A08004002402484028221828288220022282820C284C021002C010040041C08108402002813C848732B24811482C2481E44630338322A2884084840C8441421882200A082884A116825802808E0289421B088125242100E80644230884882C4110020A428C0248C48A318822C42018E11146C1123
+:8087000048024C0A44816A0845F1B1324888781CE167A145A3A44169E124B143F1E28213AE8A1B1243B4817346C1845D482AB11478826282200822B22E812AE4133242881B8812913C98818E8817681B488D6656A588B028A1381B8888838A82FA841145A41826E518A22B1C7985DC1812998221888283880C236818E04A4824888888F8D6
+:80878000826813F884CFC3F9222E2B516D3A403A2216E891E524D184F1621C667826C4442B884F2802CACCD243522A4B622A984189B321F22812114AF45892897442E42225C2222842241911921129E418B882923227228A16E4826956C78BDA88222A32A92641D59152842EA1415FC8D245C8944F42F3A1241D82855C152E59C57944460A
+:808800007282F828182E88C9B264F684658C749C45AC64A7824E42AD48185F836464269644260829FD52642F4822A1813AA27387221A7A29939463A1538D882F2591684F24A2284A9B182A6D6A2A83D622A92DCF22D1119112282F12D18492332F1869282C38242E18203A2413F1A198F084488B164E888E282651844FA25221FC5881EC84
+:80888000918147711F89783CB526B8864828B844A84A2E22A728414CC8A1C3193448901810088346041068494216042381E449426841204928412801408881840918C0128498841884988418941894494191148691149014800122001084082081B8120429149846801488144804F094FC4CF2245A2F25F1126A18CE5B35F2621B1F43779F
+:8089000014FB298286B981E119FCC1B44F1BFA81922F29F44235CF29F64A3637531B189E411BD6873DBD1227535B821CBC49ED5994973AC89227ABABF4FEACDFBAF91B829D1EBFB3F449DA8F65D2BFF11A2BADDBAF64D196F8891DDFD1F38D1445D541F114144F88D148D6857718D181588847D2D554F6FD855FC1791CF5258AA7E17FB551
+:80898000F5C2435F45F4C6A46BEE4EC26F84BCE862A4CF6CE24A7624C431935A222F21F532722D621A7D13D722F253733AF11B6B2F2FFE43416F49F787A32F2BFF21818F82F8E2A22E292F24542215A1B31D21AADA33D822D255A3E83F1AAACA7F72F2D2722D222F29DB22F6FAF87F52F2A32325FB1A3F3F34F472F27FE25ABB37223F2501
+:808A0000FC15A59F99FB387816F8BCAC5F13F3B1B88F81F81DAC17169F8FF921A1CFCAD8C85AD95F53F38F8DFD1FCFC9F11434CD1CDFD8FD7AEA7F5253EC4F6AF64262444D24AAC6E44F4AF6A4654B88EF27CB24CFA2F77A12AFA3F43812A794D721AFB5D3697356FB79A28FBAB7B9E37BFFD7B66F1FFA81B2AF2BF442345FABF66A3C2F8E
+:808A800071B393F192491F86FDD82BBFAAF132477F27FEC2A9BF88E95FF425944F43FB1492BE7A8F25FFF2975F39F9338A3CF11F731F37FD513E7F11F13A223F28FEF22BBF4AFB14288F8EF298A59B9A4BA91BAABEA88D7DDFD5F22C154F9971B8FCAD2CDFD2F23F8DFF58D8D7F28D38CFD9D8DDD5EDF9C4A9EFD3D82CB624686E6D98CB8D
+:808B0000791E688F68FA6664474C4FD828FF6E6EAF83F75A6AAFA4F51A5A9F95F55A5ABFB7F57656FFF1F7F8C8BF97FDB6F47F3FFD36B67F7BF9B29A2F2FFBFCF4EFE5F53C3E7F7BF3B2B29F95F7F8F8BFB3F318187F76F6C2A29FBEFEF8987F57F7D6F66F63BB92BB72F7FAFAFFD9F993B3BF31F9331BBFB3F7F3F3FF6BFB913B8FBBF98F
+:808B800062F28F827A25F5B9B9CD1C5F9AE842F838B1CD9CCFC2FA7959DFCAFA3DB5DFD3DBDDD2DDD2FDF3898FD7F1DFDBFBADADFFF8F8DF8FEFC9FCE577DFD8F866A42F28FCCCCC8FCBF9F818E7AE6F6AF6A4E5CFCCBCF80F800448120048002321928280082002002880428202284228422084C24821948294C04860828810028826081C
+:808C0000802882288228928128112891008A1221088A1228088220080082C033B3DB2882C43284853212811A444214A8414988E622614920A58285E42261412C088C351824201808188238214A21882398112311F182412E12127082180822800800200419120414154442140414444718914034848182831222C24489F8B8971CF4241666
+:808C800087144F6231494F21B149C6129F44C212DF44E228F94D649AF14D242B19DD252BD95D242F8DFD24242F995D442F9D35242F9935242F95B424D892B424C9494F2369946F2B7941F1349293F4349293F494929B249E929F54E229F149259E129F54A219DF54B292D95DB292D545F292584D242F99D544F29249222F997424F4124982
+:808D00004B822D494B9A9CF43492946F2B69946F637948F8269287846D928F84C2928FC4C212CFC4E228398F1B2427811D242F8156412FC13461278113B29234252F98B461C8481F22DC92F4259823C8518F18E22235C94D439B2C3CF949A44DD3AF4463189F647294F148A46D419DA62F18D441FA84494CE291C6A42FD8E442D892B424F4
+:808D8000F8124CCB842B218B821E442EC29E4C266AC52E8356E4A27851D4A4FC5124ACF949A44D921B34ACF141A686FA413486D869AB481DB64F8B44E28946F692442AB19224F2124C4B822799800800000000848800001028020000000000210000100120024100000000421008110000000012104204120000000000114C13554A1481EA
+:808E00005218331149485492511488421B82891282012A018041029044A186116419821C4122A125142823089022C022218885041184440018460412222644E1120124112008681837C842924044240100F026817FCB034AFA426121450B4821BE1B423A34A22E1B437424444121B22421C4528332641144112248448302426CB8482453D4
+:808E8000852584D4124498133B48112581F184428F224238C269DA1111F22582414225B28818A51425141832414F42348846257415B488B4A1446A43AD4829C4481E82788AF488681AD885C527534C3AC1222A05473184124951298A0258484A42D9280219A12142421221204AF41842A844188682ED21022B5214281F2A14423221443347
+:808F0000E221682A248E42F048A115521C301148821C816222141F2902699241185C58344A42F14A81212C49B824044F2128628C281445F8B69A484D229C54429423C14129F8284929E1521472213D82475282268131244228A331241144112044148938416499C41415488414428999412502D08404C78224511849C282414612948A41A1
+:808F80004A51448130414C984820E4419848B6C448369448218C341448928CA48149F6929CA31601000013441109000015424442840122111411144C020011504800160100212041422806002200442E120020020024441001198214382410220446548200402802F05827845062228C014281702412841212118481810238004E4A18188F
+:8090000040225411414128465942A06415811408144601121F2121120188244B82260424430961A468114219B2429224808894148988A2B89823844112748202488C44E49239E510922200428904816140120134120080031061111100141100851401111904830440512160142342012058424942046301450281662154412B421100C825
+:809080008D448B12828AA294924C1458420081428144CB8C94004126285114145C028002102454842B21411381C2418C140216A4422112415582642285842421124122C214421889A21100288022A438A18811280021102248A4233023004124E02204241A42221882024AC24B430C812820042191442180E4140122150A114002361102C5
+:8091000028009C044601005411450190844002000020A18200412828811A222142820829C12888A048002190488B1848884820012083F4A6462418842410190A4642840416081251AA8114424484840289015048104491141418C6A4A4304423642511188A268112188C020041242C0416E8440225044B44208442044941D188810149045C
+:8091800081401882024442AE736327021011C21100281981181404001CA2282AA11200850411410000104804241219010000242584E1180230148022011004202401490248800440840814002400424008847ECD24841E2834842193D1125428641944E4813145D015328826A23E6C42C441161294182644481489048C41D451A14829B8A3
+:8092000025B414D4420C00822352843EA851182E34C024441A1272628433482E4226143244248C84A8428840C1128A4198C58110220412228D74F0A81AD38902001314023024128848202112921114200128260814004241114501205414181420512121181A440200200800008301160412884E24582840944418451808421283240825D3
+:80928000280400422F1B43A82240121192210020024A02510000A0221400228440011190410041144181180000482002002200004880010084004114402842088C0481452404422084016C345A414021C11142341C6312242639211C846312C021C0444022042531481041082E44408502412813048418834121712801224CC121419C024E
+:809300001420C11400121C82842102E084621400484C2AE944188221648818844A08C84F560B490211131243921143522128912AD2117124018C12011122004048480150418004004952144008184419410828001126180111D04905001A02188001201201104808872400428B1C908442E0A8335E8302E02283F3244547425122286014E5
+:8093800042A0644A744858881D45141D22460117224282F018111AF1324225132742041183042AA33247C24514C46122C01428446AA444878485D8194111810111428B888ABA94A111AF31D422942A8094A4D24948E447A2224742457444081248DF7105490400150100A024000000000000002841001150111400000089444808000011D5
+:8094000040042021010000001128412604002004484800400800C05A530E181028C224C4440000006848488426186112200180A8284C89C1122124902110450828284C4244044282800A48488C444818410112004C888889C112212440018001284AC224444C0400EF1603841468204214050014890144E0840187111001402802118A02C7
+:80948000160121000048808422421404000000124250181021082800288218121002A0424400806282491404008EEEC30720E41202C4104101110028586082221400000088800164000048004828400400008412802C480814000000A88001244111000084B048020000009F8E020000421341020000000000A02200000000224400D01165
+:8095000004100910210100000000280000480080024410010000200400180000C03CA30310A3221A32244954140000222026B44802D11411008022287894311827212912038011C84120223224616100009011424283141CCD111100222886252829711212120211304181A0422243121404008B4800810028226141150122180020E4448A
+:80958000121848912142004C82242828311821211180140100222241410000808122241418481101100820282821111202488400C258222261458824C8E1A30F460214110000008460121800800200201214112444010080040040082004840018180000880000280010044008C0840080142808420000887F7D41280481814001840014D7
+:809600000000008001804208000014004400114008180000008288000000000000412024140822144800144008001002C051534CD88871423149131549114261140012281A012A32242820021A120854446624521D10011C048446618481200140088A18A121A018821200200828002E214445440149425141171410E484018B485A944834
+:80968000230484003F35452464148111181543110100190200181822208206103824224494401411D1148264544631489058842400008412821311044C010080812252144904400C80086014144A9C488118C04200828EE183022304841490485081B02152891826E142020043828102A02230256211148002150117111481201401891486
+:809700000242008A0112222288411820048128412262830200A042424E4881480010088024F8C4F91499A444178487848D1195F911121AD122719242B212A88829A193167212F222242F225244474244430249A2222E4447424E485F44D48874485811171490494A74417848E8187989F911129AD122719242B212A8882B189AC1222F2167
+:80978000F122242F22D244722444342490242AE2427424E484F445448D4887841579490199A4444E8885A8988F88E821A9192D122729EC174E88E414C458878446DB19B1187111B312181282E82888A1116CF112223A72221414140444682AC22C4F42E4467444784C581895114188E414C4588F8468BC9F18B11871117312128281E8282D
+:8098000088AB198E162F21A22327424312140444682AC22C4F42E4467444384C85D119144188AC448CF148C88E8A8B18836921272121ED13000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA30400000000000000000000100200002421000021210000000000000000000003
+:80988000000010021042522225120210121202000000EFD906000000000000000000004042020000250224250240020000000000000000000021002100254212020010022440020000803FEF0000000000000000000040421202004002254202000021210000000000000000002100210024000010020010020000F0CD86000000000000E8
+:80990000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA304000000000000000000000000004012020000002421000000000000000000000000000000000000000000CFAB04000000000000000000000000000025020000005022000000000000000000000000000000000000000000CCAF
+:809980003B4A00000000000000000000000000000024002100002400000000000000004052222400100200004012022400000000EF5A06000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC3B4A000000000000000000000000000024210000004012020000000000000000000045
+:809A000000000000000000000000F0BC4A000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA304000000000000000000000000004012020000002400000000000000000000000000002121210000000000008FAB0C00000000000000000000000000002502000000502200007A
+:809A800000000000000000000000000000000000000000CC3B4A000000000000000000000000000024210000004012020000000000000000000000000000000000000000F0BC4A000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA30400000000000000000000000000401278
+:809B0000020000002400000000000000000000000000002121210000000000008FAB0C000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC3B4A000000000000000000000000000024210000004012020000000000000000000000000000000000000000F0BC4A000000000000009D
+:809B80000000000000000050220000000025020000000000000000000000000000000000000000C0BCA304000000000000000000000000004012020000002400000000000000000000000000002121210000000000008FAB0C000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC23
+:809C00003B4A000000000000000000000000000024210000004012020000000000000000000000000000000000000000F0BC4A000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA30400000000000000000000000000401202000000240000000000000000000000000000217B
+:809C800021210000000000008FAB0C000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC3B4A00000000000000000000000000002421000000400200000000000000000000000000101212020000000000F0B8CA0000000000000000000000242400005022405222002424240000E9
+:809D00000000000000000010021002502224210000214002000000C0F4F30400000000000000000000242421000024502224000010120200000000000000001002100240020000210000000000F0CE44000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA3040000000000006E
+:809D8000000000000000004012020000002400000000000000000000000000002121210000000000008FAB0C0000000000000000000000000021002400000000240000000000000000101212022424255222242400242121251242020000C0FD330A0000000000000000000000242100002400240000255222000000000000000000004039
+:809E000052222552222502005022242424000000007F4E0B000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC3B4A000000000000000000000000000024210000004012020000000000000000000000000000000000000000F0BC4A0000000000000000000000000000502200000D
+:809E8000000025020000000000000000000000000000000000000000C0BCA304000000000000000000000000004012020000002400000000000000000000000000002121210000000000008FAB0C000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC3B4A0000000000000000000D
+:809F0000000021000000212100244012120221000000000000000024242400212121502225420221400210020000F0792C00000000000000000000000024000010522200000025420200000000000000002100212410420200002552222502210000001C34760000000000000000000000401202000024000000250200000000000000000E
+:809F80000000401202242110024042421202000000709202000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC3B4A00000000000000000000000000002421000000400200000000000000000000000000101212020000000000F0B8CA000000000000000000000024240000502207
+:80A0000040522200002400000000000000000010021002502224210000214002240000004C37540000000000000000000040421202004002254202000021100200000000000000002100210024000010020010020000E0380B000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC49
+:80A080003B4A000000000000000000000000000024210000004012020000000000000000000000000000000000000000F0BC4A0000000000000000000000244012120200100224000010020000000000000000212100242425022400002512124212020000C0A6C30F00000000000000000000100221004042420210020040020000000081
+:80A10000000000002400002125124202004052222410020000002FCA07000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC3B4A0000000000000000000000000000242121000000210000000000000000001002100210022542420210121202000000F0CAED000000000000000006
+:80A1800000000024250200002440420240024012020000000000000000000021404202000021212502240000008C32BF0000000000000000000040421202004002254202002110020000000000000000002100210024000010020000000000FF8B0B000000000000000000000000000025020000005022000000000000000000000000000D
+:80A200000000000000000000CC3B4A000000000000000000000000000024210000004012020000000000000000000000000000000000000000F0BC4A000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA304000000000000000000000010424202000024000010020000000076
+:80A28000000000002424240021241002005022002410020000F0FCFB000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA304000000000000000000000000004012020000002421000000000000000000000000000000000000000000CFAB040000000000000000000000000039
+:80A300000025020000005022000000000000000000000000000000000000000000CC3B4A00000000000000000000000000002421000000400200000000000000000000000000101212020000000000F0B8CA000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA3040000000008
+:80A380000000000000000000004012020000002421000000000000000000000000000000000000000000CFAB04000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC3B4A00000000000000000000000000002400002100000000000000000000000000101202212542420210020015
+:80A40000000000F094DC000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA304000000000000000000000000004012020000002421000000000000000000000000000000000000000000CFAB040000000000000000000000000000250200000050220000000000000000000010
+:80A480000000000000000000000000CC3B4A00000000000000000000000000002421000000400200000000000000000000000000101212020000000000F0B8CA000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA3040000000000000000000000000040120200000024210087
+:80A500000000000000000000000000000000000000000000CFAB04000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC3B4A000000000000000000000000210000400200000021210000000000000000242424002100000050220000000000F0467500000000000000000000000024
+:80A58000000050220000000025020000000000000000000000000000000000000000C0BCA304000000000000000000000000004012020000002400000000000000000000000000002121210000000000008FAB0C0000000000000000000040522200004002242502002424000000000000000000000010022424000010022440020000C063
+:80A60000B8130500000000000000000000242421000024502224000000210000000000000000002100210024000010020010020000F0C81E000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA30400000000000000000000000000401202000000242100000000000000000011
+:80A68000000000000000000000000000CFAB040000000000000000000000000000250200400224100200000000000000000000000000242424000024000000C01A830D000000000000000000002400210000242440020000210000000000000000000040522200250200502240420221000000FD1D000000000000000000000000000050F7
+:80A70000220000000025020000000000000000000000000000000000000000C0BCA304000000000000000000000000004012020000002400000000000000000000000000002121210000000000008FAB0C00000000000000000000404202000025022425024042022400000000000000000021002100254212020010022440020000403207
+:80A78000CA00000000000000000000404212020040022542020000210000000000000000001002100240020000210000000000F03E9B000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA304000000000000000000000000004012020000002421000000000000000000000088
+:80A8000000000000000000000000CFAB04000000000000000000000000404202210000000021000000000000000000242424000024000040420240020000C0E68302000000000000000000000024000050220024000010020000000000000000000024240000005022240010020000B09A0D0000000000000000000000000040420240023A
+:80A8800000002100000000000000000025121242024002000040022440020000C016E30B0000000000000000000000210000240024210000000000000000000000000040124202000040120200000000F024D5000000000000000000000024250200240050222502000025020000000000000000000010022440020000105222000000C0B4
+:80A9000044B30D000000000000000000002424210000002110022121212125120200000000000000002121212100000000250225121212020000B0A3020000000000000000000000000000250240022424242425420200000000000000000000000000002440424242020000C09ED3020000000000000000000000000010420200210000E7
+:80A9800000000000000000000024254202210021000040124252222512020000F08E7900000000000000000000002450220000105222400200002502000000000000000000002542125222240000255222502221000000EC331400000000000000000000400224210000004002000010020000000000000000212150222440020000251231
+:80AA000002242100000070450E000000000000000000000000000025020000001002000000000000000000000000002424240000000000008C3BCA000000000000000000000000004002214002000000000000000000000040024002400224000024210024000000F09BEA0000000000000000000000255222000050225022250200210064
+:80AA80000000000000000000000000002125020000002100000000EC318A00000000000000000000000000002124400200004012020000000000000000005022000025120225020000000000F09A21000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA3040000000000000032
+:80AB00000000000000004012020000002421000000000000000000000000000000000000000000CFAB040000000000000000000000000000210000000021000000000000000000242424000000000024002424000000DC34360000000000000000000000000000002140020010020000000000000000400240022124502200002502404205
+:80AB800012020000F03C53000000000000000000000000000050220000000025020000000000000000000000000000000000000000C0BCA304000000000000000000000000004002000000401212020000000000000000212121000000210021002110020000F038C90000000000000000000000242502000024404202000025020000007B
+:80AC00000000000000000010022424000000400224000000FC398A0000000000000000000040421202004002254202000021210000000000000000002100210024000010020000000000EF4C04000000000000000000000000000025020000005022000000000000000000000000000000000000000000CC3B4A0000000000000000000031
+:80AC80000000000024210000004012020000000000000000000000000000000000000000F0BC4A2021010000008004004800004A04200400181825020000381250222800002A02A0424848000000004242888800000088828082820200000088632D212101000000484200000000420048421812401202008022A2111602000020028022E8
+:80AD000002000080A444424A280C0000101212A2888200000000282AB248830100000000802424A44442000000004A041A21410200240028222B132A322200000020A426000000A0442B44212B8882242424002100218E8226722202210000A0222E65B306000000008024044842000000002924C412122424240021802282A121260200D3
+:80AD80000000802202420000484E428028082121210000C0822728251202220000282AF253AE8001000000004A04428004008004242502A011204102242502A022183E1280020080020042A0440000A04480A4883082212542020080B882187222022A0200002A4232AA0012000000004200200400484224242904001A6121502224108257
+:80AE0000212221012200802202484A0642000000422120B48228082400800823A8282A022200000022AFEA0E0000000000A04448424200004A04A04400121250220000A0113AA23127222200002A02A02200420000A044008282000000A088828A0800220000A022BC34421800000000800442A04442008024042004A0111A4112020080B3
+:80AE8000A2113A61212B222200802202482248200400004A84048AA888000000A0888AA8288002220000A0229FAC09181800000000484242800400A044000040C21218210000A0212AA112212800002A0280044800000040C2422C84880800002088C8822C428242020000C0C7630A000000000048424A840400802404484602181800211F
+:80AF0000002480A1312AA12229020080220228228004000048008888242150222100888AD8220840821202008002FF6D060000000000424880A44400004A04800480A11112250200002AA1311AD122A22200002A02A02420840400004800888A2808000080A8888A28022228000080422A290112000000004A84042004004842000000123D
+:80AF80001612020080A1221A4312220200282200422004000048424220242808000088A08820022200008022F228C60000000000004A8424240400A044004200121240120200A0113AA23127222200002A022002200400004221202808001002A088828A080022000020C282A38901000000004820044A24040048420042001AA111242129
+:80B000000000281A2163212A220200282280248204420000484248A0888A08000021212B88828A02282002008022F24488808101000000004A24040000A044400248008011022400A0112A23120200002A020028000000200448488048420200A08888400200000020C2416308000000000042004800000042214224A011242424100200EB
+:80B08000221A6121290200002082A44600000080C442008A081012120200A0888AA222212100008082F23B850000000000004A044A040000205422422502A0111A1102215022003AA2112B220000002220020000000000A0888A0821000020E8280810020000001C3DB41200000000800400482004004224214880810112000012281A012B
+:80B1000025821222020022004AA24448000080843442888821860224403282A0881022E222821202008082F2815C6041258862D4182210B124044392448C8504284005C119111518898102220020B11236128D24230121144420A1426143E28278245984848648412104889B148BB4902888198105862828B8122201441AD24392A28504C3
+:80B1800081324888D0E2313A6B241332264150C11332261A34248D425E28454B456991996414838494484E281E61185D182631154E1449C4141658128712E06241D852D641B624142C831225227C4886257444B311446184C0498B84D04198491D948D911245211884C1188837882BA55D32669A444241841E248826B424E142B45CC28121
+:80B2000000C440C828402382421688941840486814440020233118411C02484110481208843CB42404460138281121C614120C8C240140A1449041403194400140C8889012172822A02140480C814400441C365C291641C2641534111C021A840458452214882102C0441445C82811111A62414E2440041641A1241E2824C02522841200FF
+:80B28000684902987042280884400888436112841F834891144A48842881488814E1A4D21464468280A183221A328429F37A1218242200444004004487121008114800207441018C0100120024201192224002411004008004515111400184849098830400A081008092122C0340024100801444C8A9E3481484020000431284064035417A
+:80B3000040019C14180848001400808101281844430100442240140483869248009413240482481C08008A01001880018841442420024902004A22F4367744000000000000000088000000000000000040080000000000000000220000000000000000000000008008AC1416649229B619941110A221112B48260311282588E24291218086
+:80B380002A943826140128164212A2244481142225411882121114414281127882A4A48890148932142C048532940093868882C3688611C4849984A12444478420064229A42460868D42C29FD90123025351222460854226011CA452411164923042C4182121462492488128608219741121E7833414437156B83568844321052AC4814AD1
+:80B400008212913824D02128B18118212C44724481C9254A444554412A084AE8A258144F81312260848824848C88056948C429D31494292F12F11841290123E18234218651212E41124068484C1101814A711228D61412386812282912D11415887124D86191485D3A621CE14114612219A468848686AE12501489EA18611450288E1442BC
+:80B48000118D118A8234111D6C1186C484486F88914569C24C482A0446D2828406E9548249F47F91302248454241828401244A025C0413D222A1222C24823824212604005022C048221CA42319240163018614080014E012028186021E12442C08CA042441C82634412E24C0A40046290A3A1108848800848AA12488428E21338401205121
+:80B500004100210022121302411001484A0228145014401103801418243424813048100800422118002141282C1882210C218419024058411009130413049143C814008088142828F4313CE044F2523242711642217421722124A18127264FC16422884150242261451231228C2412A2228902422024B224541242C52238824121845A221F
+:80B58000E811B848D8444424C2822032144602187052CA48165132431432414243A8424C88082B428914B246448214822814D41A2F8C21C1221941150221269114189E42363168444001B024041C120317442111004890481024D48154842314420C6084E2211F848108454264284022410240522883445283444881004841823D2889048B
+:80B60000298414428284C884486F2F8884B24645921480942111212860224145C28440847242024129022881282493228204442A243226008328480218001A0845A424002A32824B41C8C012845A9211144C04354121F48461803481C0844C741204800C8C042485313BC904216903106284A0122014A4148F411452121421414005214D4F
+:80B680004290111800232401432254241915C5122F420196C218E024816681241E48C944848844C35247288CA42C8882884C74215842858112884A02972A1008324828A8987048F4A3D700102442C124C024248B4454E022086A42084814A02118006882257473C224248280242851216082A618912442C4606219041684282662812817B9
+:80B70000846041181845282448840816024113242584055AD14A02444008A11C3997112C0200301124841022420100284B423210C442440084486044141098421601830488001904114210082E81883011242D14004810811423044846288484444C48088488480082844442F02F4BD442234204902115B842522C3AC44143826489454239
+:80B78000722131442745C062412410045E241744548001421B461616E841CA882D14311F246C821AD42C642353A6143B42CF81D814B12448F2442218ADC24D448917B1849449484D248B44A7986046856CAED088028568852B15002A3288CD482D48FC374A00642301C012008C44025312A2122880220249119114C0428B2434212C84A28A
+:80B800004881214C0913D412142111081814008116882828022C218124840188522C081011240442144A81D421A8418840848408981074BA412402201213022912018A044021788101411062112182E0180214422D11A083981460824638211C1492824A0820A224004823820A0042218EA2248241424188D028040080054248004C1A02A7
+:80B880004420C413A3142204144008622421141212558202821722281424422414412C840241484DC263042934144144221244C022838184E884A8822C280829542443621866C12230244A888884384822602C82232818422229084C0440C842009FD909C06145D422810444584818414153042504432214A2228200280042221800154494
+:80B9000082C4822221001824882C0400822391412119A24C19312421702808244064421D8122412A1C242262421166A882425888908284E05C3A1E108281E444022200884082EA821C4442028210018056424022012992442C1192244114DAE244015042182270110447842841884C043042224442400100008601205548820041C48800B8
+:80B9800068482141842415221442C4818062244032446C2218850253F82441803522482B48148A042095428088022A6884140042482A0888282100422308824823728484241832844841809144805444460443044B44808814048C4884488833C74C2282420200806212882C088028A8248042011B482008240040814A014280C488435899
+:80BA000041244008002E1A2400182863410CC021424241002C9888AF48011121008210822804428C4412C84488160D001C040041001420042D22007083020022142C84421284A4228092442141214424100220941200C021284601881486822448440210A24248220000888D48490841478400224800C0EDB32D1461244921B122A42418A1
+:80BA800048B82A1114A2848002808434412A08A8116044288A0500228609294222084182302C2159242804801824062280144848416438264483E4524D64226B8428601288212186122208101AF4E7EE2011042002551122F142425011284420048B8410010068146018281210E24424284134914A22146423302CC6210A844924D8240220
+:80BB00004608A14C5821414148203844C23011A8318044244204850422844344287824E84437724662146B442D631E44AB444AB26622B742F214C45AEC325C4D291894834B462936421397238813D2768AB46294612B663249BA82622829B4C4F1CB21AC614A90124427898F42B8922662844D8827186308228B482B226F1CF422462C7225
+:80BB80006838223084239824ADC82E2E4C98E44F2C5462C7864B3846922264A398442B12C048CECC25F68C889FBF4766632B361114213160342BA78E2227214D872C7EC3F52421AA7E21B2228EC2822B82172829F881414E433594641554123BE74D445B244B467F28F244246F19EE4A253A42C89A42E2117282F315882E4A181CB6C47877
+:80BC000043F5A4242F11941663EA22263C668B481D4245A14627545B42CEC53F11141524BD44948459B494A844499C4467848FA4544225B448C42A237F21042C7255941628136231E03174C151341E2428A6622845D451D821081CA546C24A26AA22241A212884F511826B94DB32C048ED4529F4471545F622428DE28E68424B4C2B838EF9
+:80BC8000646EE22CB22239822F44DA142CB2C478853486C76C5F48C4C2474426247D8981269AA24B2C8AFA28C259B684F46C884DC82C88AA8CA2818BA44CF46CA51800200100123012200110040000800110044110041880031880011880011844214440041130210000200222C024C0248002008A02000080229824508453D85193411F60
+:80BD000011D133D456F141411B261D452F13D613F435E42BD8182F1CFCA2832F32583246F3226A2F257142F273F32F27BF21FA43867555667F31F6C2C61F52F254945F77F51397FFF3D862F5873C3F2931A42D522F24B592FBA2A2AFEDED6159664FCBF786C23F58C4445F31F387874F6355314F66B284F4E4674F64CE222F26F263A34F3D
+:80BD80002C74436366EF6CF645551F18EA48F8A2228F8CD822F242466F68F886842FEE54422F24A6222FCAF6262227A24BA8AFD346F135332F27F222437F26F443455F144671457241F3432117761F75F891A63F227A43F283AEAF7EF44343BD522F25F222533F2DF7F2211F2EF6A6A7772E27347F2FFCE64357464F72F667577FF9F5CFCD
+:80BE0000866F7DF83F1A6F27FF76466F67F454966F2BFDF2C22F6CBAA2E3437A64FE4A262F3EF645B26F27FA823CAF55F46143BDE24F6CFEE62CC7EAEF62F666237F4A7CC6D387F116CE6F34D413B484FC84E66FCAFAEC86276C6F64FA66E64FAEF8AA464F64BCE6F888C28FECF2226EAF44F8AC3923F517473D462F47F713736F74F54314
+:80BE8000471B623F357532F133517F6BFE92C24F6BFAE6C73F3AFC21814FD87846F7A2A35E122F27F1A282EEE21B8C7F2CF823A73F32F463735F1C5C355F54F865456F69FE2F3D7F72F4B76C35FA76723D636F65F4C2C62FA3FBC2CA1F22DA22F8B498AFE6FC43614BE84F295F641FB343F2E4A749F4E4624F66FEA4861F1CF2C3874F66D2
+:80BF0000FE47235FE6F3CBE25F76FE85A14F4EFA22266F62FEC2E43F5AFAA6A6EFCAFE82EE2F48F48246AF2CF482486FCEDCE2F64E42B79B3CF367136F25F224537F65F557437F14E254F771721F33F773377F73F543F77F2EF64327773A3F6AFE8EE33FACBEA3F772322F21BEC2F6E2C11F6C74A2F7A3677F34FA23E51F5EF663C55F7EBD
+:80BF8000FFF1F66FFEF67FA77F7CFB2F9EEF61FE66437F24F546F26FADFEEAEAAF3CF332166BAD4FA8FE4EE22F7EF6C1B37B2B2D75FF4BFCE4E67F6AC2666FC6F6ECE6AF5CFC61837F48F6E6677FD6F67EEB3F1EFEA3655F42FE64E26FEAFAEEAECF7EF665666F66E2EAFCCEC64F2CFE468AADE28F6EFECC86EF6EFCCE8FB32A24324141CB
+:80C000004270418232418211446048B082024448238194222A042A14C241212A044F128468128826B14828B24118041088028A122808008A02004C820460481C140221840088224220044E82200424602482F09193D04212D12241410218282981D42288041756211429A82225022C889281100124221904400425A44410110424482B882C
+:80C0800048881904488A281282D2221CE42848E424280230C2414247424A644A482604274883F422244094482B88485088884D483F783B861D262F81C4242F9154482F9124F2124943F212494F22F81249DB929CF42492D45F2269144F2239C84F2239494D92BB243CF949242CF1492486F24924929F4433B29F44B392D441F392494CF3FE
+:80C1000092494CF192492AF192494B122F91B424F912495B922D495F2249F925922F15F224D2A3F42492B3D424B949C2D29F44D224F1492447289F44A2499F4432929D342B491DB42F89C4342F8944F492482AF1924843F2124C4B82CFD34AF126128374247269F824125B24249F44029F447682F2692C824A32D29F44B29A54483F89EC84
+:80C1800042F21259442FA924F29249A22799222F95B4A248F924A246918483B42438484B829B464F22982D889B24249334829F1622F84861828F54B28AF428241F88D4416219448F9924F29249474A3F91E449D89394921D494D8294472246F1848293F4249283D624B84CD224B948C212CB248A3DB6000028000000000048001814000014
+:80C20000144008184002000000004004000000C04440081400100880180460210000000028000042181F4F8D12D252816481008501242E48612668121422A0A2244342022604142C6214100200A24954418B2418284148A0243512A8884282CA1282D842031810068BC443512A8B441447444815644458191434444A1CE4485142256424F1
+:80C2800088811A149844688931268D11430421116012621213691239C1914A41026035184A8178818233128440046D6113E4148225B4249883859181A084A909A02C43A6212D2826A218274122801224EF243B1426290624122280222CC28833A81881C9E11804C0448084082719449F6344022384334285845219421A7121B863F211112B
+:80C300008F1A851643E8227611A313421D21443223812C125522415A84B422444437C88D11824B2260442C92414CA8248E88224E128694628A628166A4616B4827499B14C7882FA6044C149114CAC6C2E0451C82CC4849D81C358429127444AC188C4884E8C1C257839A39411D14100180022318140200008241C0822308401902E01214C4
+:80C38000611298411BA49021008AD42889042F8822A241242B2822122444001828181B24002C24211211446412816F18842188114284440242489042427F5B072A02232104000048290840711242110220522240229241108122942442889F1444C64121140098428820C861212AB2827124085382898201CE412210548800414220044205
+:80C400002F48082381240800244092282719237A54F341181746314D43296124242F14A2A41446B481962280022321C44249A2422D45B01482624348153C4141114416B22124E252342242831431A883A4144C3A848F2128C48129D8280826C2C68626D22C79C3B88A974461511CC628D9621813C181478530C44A38264E886B4820E584E1
+:80C48000E842E54208AF8C4DE2116422622542221142224443A48C194211021121002322145752A0261146F56844440043D4225214424A8204184A0AA02C45B641E821AC224368B88092A2412BC12E11A72A8E462E44401421625483328111982B84412148AAC8828024314A4F27F288128E8D333D658C311513344520143221CA22044A0A
+:80C50000128291222418422346642242223860410014621493E81491412C322531C048131838C812882A382A601125C8A480C94286044CC449894958A4C045830242181C4C0C4E94C82594484604800841286F8B8B5128200423042880724552418820E13681C845218412A044A04C6068141260228B1443D26CD821014880A4294DC869AA
+:80C58000290245085100A02485424AE48143141202A2A021160522A3218809A528218108681A8102AC094AC8E343034E1511284091241248802E8402488908F0842811D0213A242CA18288B042512C4823819422582214800C48442120E434A848184D21148954419614289C444AA24289823443888066484F143142412511044128B04225
+:80C60000312810A44141254868E320042624014602156222408101C2280012284A348216084428111004100128A04480129212004288404888588A432101A0242028D82404C34104422C04004A848C823C28232504F0488200424035713015221842142642912217642EC253A42800B383D841B484E28284D821CD242BC14C0A6134252C2B
+:80C6800064841E6426B287C45214428E2224188F24682A40948A8718188A92191091822C644C2A9CA42D6483C6C42591144AC2252F48364890442378C22CF114284E324A1862858C140247858724827FC3CFC816E21444042142182A042601A0914A82082C0118304222830446218214042A114114A823488084A94641481248821F4404E0
+:80C70000851D528412C74212281E184123042D182242A0414091844218138492488280218481A218422348C8189302002A0460121448800C13041100142828424822A2C0241C264245043082243044C611082012088100488234876480012482821D848608160884214004209484121182282034842186228404CF3A8B0200800424281D30
+:80C780008222C08220188204860A19228844012601B081C42100804201910011450888881B2428243012871CA254288022043AC448148C51245170C64164284245426124431802414821124064411E68E37F820822141001488024222692411128008004118142C906199244492A244804A084004496246418B024C4211355411424001B8A
+:80C800008226322120C21448131141C51159410500881114881081C8428684918210042AFC765A40124802640048002490212B48A62138A1C2C240081628A8488001162248F2412100288E1180028242220020440520810869288212E241048A180A1842240059588222214246841804800488E0F12A8C422214410210011A460224422390
+:80C8800008814882A08560243C2201522C08120021246146442446011921242804842C281451215422190C80E1143812950420210413111402D01C814184142284088800542FA10E42008004285012280062001828A5912215810222A028002A54136A04193414436282200444282821112A1A922460834C0A8811182CA8251082A14428C1
+:80C9000025022D81882121412C14AC844002866222180000DC29034100430448420011800840E2240280682225810860442C08184445922400902124C048112182205881A218888881292101006B4885C488200884444C2402114C044027084244184230224915F84EA3F042C82213844482023022906229011362212A48A2221290618199
+:80C98000488150414C04C044481C04192241044241190484414994442854488019D244082220045145441284428281081C28012B1890832002482424418AE4C8338D17888032421D22144C7414022414144022C24140081C042481248764218825A112121682488418048169082884543A048215C25900F02844218483C811003092235504
+:80CA0000818814194144A2682146112C3444250428408404003F4685D2281828D22144023CF445416ED22C5E213F24E415FA21822B262B48C6B3A28486F6C2682F82C24A1F8A666B5CA6423D218E61737184A24415D1225141464338C45F13F841799D886ACA684AF49465EB482E164E41CE96C932236B21A6B298E32BCD411F54F94E4130
+:80CA80002C6C2C25721192444D97444D814B565D2225D8417481C1A26BC8467444A24824CAC64419F5381C1373417288B621D42394417C8466222642D32122F281832F24CC1128AAA14A1B18A0381D495AEA82A4481B22184CF644621A1254147F4186DA44EA5C92944B2459480433C2415D81379A1CF633113423F8292247884F125864ED
+:80CB0000AAE22CB424BF8C98982FD8D5DDD1DD53854F24D3154C2158244DC29BC44F41B982F14686495426C246341242E0496D48EF1F43AA264A8424D216C46118242862482A22C2218653813B422C32AAE65121F04A8125944E53F443A7925D844AE51434A42F2892649C9248D31472484422CE54CB8A2262F0CAA14789911F3CF19493F7
+:80CB80002EC1110069B136D4C1A11829C11865F141822163E328F4818344DDC3AF14B1463841284728982B812B85251646E4BC2808444004000088282C08000090220010221222122202A22008430AA22018287848821288128802124228811A0228A0218412200190441004481004000041180044001F664F5D6FEF34F2434237444D42D9
+:80CC000025F3431233D133B913DC22C2B11B891B982B891F38FB91833B788B878EB22F9DD4B9F8A3811F487D9CF524124F71E12A7C82F575144F5DF6E5963F59D833F9B689CFE8E868BA2AF8C8898F58E537FA831947599F78D687F8CA277FA5FBB84EEF5452531F11F311426F243B1A646F797643DF13F411573FC97238FB133777123DB9
+:80CC8000224F12D851F225D31E8BDF9831416F24EC2CA8684E86672C5A81FC84242AE581F98C4393F76B2BAFA4F427472F367646D666D433F472732F34F4D3533F2C7223E32BA9881F2BFD8181BFBBF9C3631F35A5CE2F2B7B49F9C9C99FBEFEF89A1F5EFC32355F34FDE2837F78FE14944F66FED6927F3AF21716DFD2F2CECD6FEEF644CC
+:80CD000068D5FCD1D435F379F45F925A778FA27E5DFDB8B8E5FE4DC75F53FA1DBD2F64F6933BCAFE96975F16F51FD3DFD5F45F1F4FEAFA11177F76FF85C74F627285F565E57F79F1CD8D1F3DF491873D43E042F284846F49F99292CE824F42F2D4144F4DF913A954D3F26822376657161F2494271F227553D231F5D3224EA22F1C31331BB5
+:80CD80009ADAF881328F23BCC2B773E424FF926BBFA2F8AAA39F7AFD9F454F6E7556F734466F52F8E7111F55FE61B637777F38F13269CFA6EC6472AE7D69DD8CF11CE33F9CF5D8A59FFEF64FECEF2AF712A65F8BF4CA2D3F9CF111219F59BCC5BB91A5EDFEF33FFDFC87511F15FCD32CC77ABD644F43EC58FAA7811DE14F76E5F1F84D91C8
+:80CE0000172C6F21F444424F6CF462466F24BDD4A185CEE44B5A4FCD79DC373D9F96F24C6C2F36F646673F34D472E412F272732F32F633D33B623F3AFC3133AEE11F2B5B113FB3F3C3E37E73EAFCB2B297B48FACFC6BE9BFBFFB65A56F77F3E5672F7EDA71F611555F5EF6F6777F72FA1312DFDAFE8A496FE6FE4D49DFCCFCDBDA3F32F209
+:80CE8000FDF85F8A5AFFCFE6FA9ADB6F5FFE48CBDFFAFE32B97FFBFA66E7AF33ABAE7F6FFB6C59FFF5FDDDDC8F2DF83DBE5FF1F1E7664F68FCA5A557585F5EFE1717DFD8F492C37F69F9828647486F6CFE86C62F48FDD2C22F2CFCE4A44F4DFDD4944FBA8B9422142148211C14E212042A14621229288228C28222200222138432414413C3
+:80CF000004134424044004441D414448400148889498942C48817924C182412C28E22418D42141542150291061481180348219348248230823883492488248CC3CAA838C440260181022820214904213820225812404C04889824C3424B024140111234242A124200413442882342454422D284210388222001222D01415880C49018A446E
+:80CF800004881C442441C441444846240823081644F15D41144F6331484F6231494D129B242CF149242CF949248E829F4632929F5432929D242F29D441F292482E242F99C5242F9DA4222F9DB424F213494BA23F94B4A4C9494F2ACB494F2A6B144F2A39494F2BF949484F29B949E228F969242CF169249E129F46A6199F44B292F1292419
+:80D000002B491F42F292582E242F9965422F9925F2924B47422F91F424842F94B424C9494F626B946F2269144F223B486F6239484D928B242F21F948242CF14C2C8E6C639B316B414AF21669282FD164422D494B122F9894148E694F22C1494F22DC82F4249827144D99AB244332894F229C232ED28F44EA22D14AEB22F449A6329F44BAAC
+:80D0800022B4493A226CFA32484CD892E6444AED22D89236249E6947222FD1B664E8D1F624C21E614FA2E811F224C38F15F224829B244D921B252E82BF44B824B949F1A4429B34B67249B4A4D421B192D441E28B44F69668288E4C2E162F8924F2926CC9F88C3C40040000410000000042100811240000200800000000608100100400009F
+:80D100000000001001000020080021000000000000008C32B68B414B2460642C05584E282816C2122912A14140C3114AB96221A442121C64252226C459268214C44400264196144248461C08008CF128444B3820129284330212274842611741472124B3129412131408144121A01819614112CE1200A042892529983E242E82400100271E
+:80D18000228092A8194132A82A9211242082E1228856231C021321B42254218A24A24A156188492458492E221711484521018601129B444C08367218840921221AA842228D24484B31151488328445A4188A28B5516482412338444CEC2124098014C39E33EAA1346270648201382D24A02117292AE122A8141346D238A52513A74286C336
+:80D200001246E334A212E011E221BE4238424918C18126F4428415A424337628445C148038194B618BE148430A874D271281299185488666548544E291E218731A24B12418D61468682B141CA496178129082E1243D4240D22424282875260420019148214B248429228249420821181082981E214248201193424A714004B224A0494409F
+:80D28000684120B1418401005058002C211212248992122818222371243442411C0481001A0812D04481B41428240960841E92C0811242004301210013944230122482002682020042004004442219220820442134341129941148898804A086444A688819081522489228A02526614118282004A8A0240082004265488404121821C11F4C
+:80D300007F074B314611C445144E181B221A41A86A3948A1423A52119081242AF524881883B255786492442681B24114F1442180C43A8428D0232244324818238231A3119821812A5244924F61A2452A3584224D4241244E441641A442D328F4C8148E492D42284E1427162A32144A2418A241824AA1867E45C389A42144181384042212A1
+:80D380004032922521120122A8268286084E154B86800466E51432248A02481A1281A6212E42218D51488A21A438808EE188E482288A1981A624830556141194424B21114C3645228E484C1783A4421A362149314EC63442A0844890248FD78711641444443494321E412C32C813062A24291211034C018933480069521400481501C042C1
+:80D400008181146501460228A11013413482401491146D824391224B282868611212420083288C885428886480220480011AC1225A7948326812422228004B4215022428178212682042041421584C524244281A18841118544230831384C4648CE4424812C184280040112802484901C51124847134F2228400490646A4282CC111222DA7
+:80D480001C89044B41800200A244444AE242545B10484C342843711106A0221140221AA612184C0727162E848800250883CC251A1C448A24A21440220813F494144A111442A4621A18C4828C44EC8408B6282181C881808524F2924840C821AB4110A48C491122086848214421A112D0D2333F10C21218003028801108441941412208439E
+:80D5000088C12220848418B42944120114002800241800001002604220011164482818422094248C4129014110082800803482100880012C68884F1B048121C32211F411222493C231702889381463A112214F48C4C42E222CB924D84414B242E842C145244DC84145942846A3341344A44CA9614A25B15449024C023E8149128C444CF89A
+:80D58000858427134E142A012C99456D14223E642B5185A42483F828484C4274D294182D14CA44224A18C2821860212AF82CCC738981C412458801422012022826C26111288CE18142228184024484836482194201142008482C0217449A820222408204E02268812001160442D8282A28C44891004111160126A8840000484A02222518CF
+:80D60000A44846F26DE620011306460111222A28348382511064C84011080011420010014D48203A81304494428410B14808190414206541164212B8162162425E2286044084A418422280C841A021D044E118818224880924890142EC3C53000010044051420080044122444021123D484541621441203481004822811C0441118A128169
+:80D68000628487488440D514829C8188C0844222B02834244C088100C819260128008428004E144028C5888071AA880200111100100400222800702812048218460240014F44480886E214024551444021022B122220C921302421D019044081191478148482B24109601440880200856419469841A0414440C41284E03231CF64124C14A0
+:80D70000C2422126144312043384180180188448911541C141100422800444704128484804239E2C20089C829882824A084D1816E518924221888115522800102804188428004884C8824420648882832243F461CE202502804201226652412908001C0822218A21088004450100888018848881080019084B18481948018291171823428C
+:80D780009112141282298448E19421E2158441283221E6C118826011124BC8802402818024089C3AAB0080C2240000C81394418842284488198805582608208494244842132134414008103144100517464442108121A1819860824E88842A814B2808590840A11800143A28282821224128A858121A0488F0BD6800004001221004821429
+:80D8000030814004003084D01422982241882F22888418862894814222818800818822C44C04650449D28288082024840420CC1C000018423041421410888101908400811E5823842201402102592444082442800800341C491101800C19564110043034A2308C4C1961248136611510E424024280420445024C03E4F01548181418945811
+:80D880003091C6A942111142800140044841284A023F4C044A022220026304808602004922B411924A90412A028225052018F214281002484111114246046A04412811824AC86250821847141008B348111202008228131198821A842C0342482A182482598448188AD28435592323322400175215C22131863E853F14B281082A42A19AC5
+:80D900002AAA98706134214548D2629825221F6E4252D1844843C68C135459879DB04C928983F591614D81C11B624D246FA518F494B215711E5A2A1F2C386687256D884AF4432B4A18C5841E588B231CA61C8CE919B421B381B251C8112AAB248E141AE58C01412D988C3F14EF66462421A1242D4213342226912645E228324110654C4330
+:80D980004841D21494134C21D2895515174A19545422E0882576841574C1BC21714D34A84D641531C3287AA64170ED7E8831811AF1B42A5D84EF1D88BA817174B874EA857F24F5A22C9EB95BD79E198781141F14CA198F8A55918A8125F954948C98194A44048AA1596B8822F02487A3A4641AB24112514160162AB444F644414E828EC268
+:80DA00004A7241014F48DAC452342D4C8AE918DD4C82FC46444AC4415CD416F4C4444B88CAB4E2B891B2E1B484289C451D442378C67D8589B8A935E186B1C2F481451F3E3441A3C3955F4143A1892DAC2C51DA4C04544A641442882E411B686AE31CE48234849FC4BC5124FA34C8C6E44174C8F888588B4783AF12BF530A422842244224BC
+:80DA8000423024000030241084045843024124004C020000288140080084122260822141184382410843C21222890185120444810010280100400820014038122628C949E3F16222481F12F6614157441D422C64146D43BD8B4F626E1225E21CE848FAA1A1DB9B37363FA1A5C4437648F884C1EEA3CE821F5EF24465457685F7677D47C846
+:80DB000055E555F18D244F45F5A52C4FCDCD44272E6D435F18BC817881D555F249C17DC39FBCD535CB121F5ECA1A1F7B7143F326B6CF44A51ABF3CF819578F8464491CF421218F83A6261D211F17FBF8AAB6F121215F59F8558C1F89AB738F897914F4484884CE182AE682FFF4C4FFF9C1222B674E611F327423F646416F14F2426335F4FF
+:80DB8000414FBF78FAE62115D312D441EC5EFAA19DCF3FFCC3D2BB89DAFBD448CBC65B687F42E848B6A4E444E65BFC87A7FF4BF88CC57BBC4FD9BA84FDD4A55FCA7DD5F145C22F7EF8CB99DF1FE71AEC58F8ED2197343FDCF4CF513F4EF654F7BF4EF998B1FF297512F7C7A6EF28FB8B491F24F995488B958EC89F19F739288BC7ACF42A90
+:80DC0000F82E78BBB31B3AA6F515C54F14B339E7C7F32C144FC1B1BCE121FC9A1A2BFA8F47FF749BF3FF12421AE316F242237D4715B562C2416D47BFFAFE26A62F36DC22E41CEC4AFEA1A15F8BF1A585DE931ABCB47E49F18DC11F3EEA6CF821A54D655F76F7C5475FFE7ACDFD85854F5DF98C2C4F89FDA1684FC98DF48226EF38F8C9D5CE
+:80DC80001BD81F1EF6A1A9BFB4DC37F8CD5F7F3AD764F52F77DFB1F1B51F5F1EF6A4B5CBD46F6AFBCFA3DF55D19CF891158F51FC39219F94F121611FB8FE71399F9AF3B1211F12F315C157951F9FAFFB8FCDEF48FD184C1E482FADF5E2628F8FF7F4548F45CC5229A32713D64154141F34C62337441FF4FEEBE76F3E7643F342411F44FA79
+:80DD0000E4A55F5AFFBC611D9A2B8D9EF44F5BF465C55F58B667F8C62153F245E55F16F887F5FFDEFCCDC31F4CFFF4EDCF4EF9D8A19FCE79DDF545827F4CF889F99F1DE31EFEE1A5DF5EFACCC33FDCFC5E333F4FFA5537BF67F199377F69F773367FCFFEDAFDEFDFF46D97FFD9F6D9D15F8DF4DD719F9794A86EC9BF8EFEB15B9F1DBBA191
+:80DD8000E35FF951D95F9CBFF9E6C6FCFC544F85FFDC884EDAAFA5FB22688B7F4E6CE3A514221304111001138412A12815022018810280444441840414D0140494501442418344314100B04108118634414413440423088684C4248C64488C64491C04260848C0419848109498144A014A098B848008F0A24A8822004880024210B482A8AD
+:80DE000044800241884123842209871410D244228498424C88840A88934404454429A8249A480947122C81E228490D141243B212012B481013440152881188812A5111A24A840B0049092CC8281A61441BA863D341F236484CF21249642F917421F2124947222FD1B625D892B425C96D4F22C92D4F2269544F227958F424929F45D224F9A0
+:80DE80004B242CF949244F22F1492486F24924B29F4432B29D242F89D449F2B2498D242F9954482F99B428F19269CB122F91B624F8126DCB921E6DCF2249F924922F55F224928B254FA2394B4D9A9F44C2929F44C21A9F4462289F4462899F4433929D242F89D449F292484CF292484CF1924883F29248CF22F11268CB92CFBE416162834F
+:80DF0000E443316929F14D21697148D822F16D2586724CA189C7462B1DDB26AB59D9F282585D242F99DD44F212CB4B229E494F4AF292493AFA12496BB28D496F224BF134B287844F237349F8B4921F86F42692DD284F21F9696C1E129FC662285FC622F96D2C23BD61F29A52DF42F283481742AF39A422AF193424AF1934A4AF99B434DA53
+:80DF80001AB436D89AF4341285F1A49287944F227948F8248287864F23F944289887C425F2682C9EA4630700000040021008004800400100181480080022000044880040020000002081040014000000880000000000000044004212CF2E857211E822220124282C4428434272210100198281D84407406224CC023D24501714281A9188E3
+:80E00000841E2E1870316A1120D421F218638D285120B9641124044C021323128421225821245410818228021686D4A4A11C2440021278403422B4A30C861298112114148161628F1AC114278813224322B124042428222210A1140088411908C061C8D9C48A1CE2C528E1850818482815162132119626C11246328428431AA11276B4A996
+:80E0800071686181224C5A411814441C8461124CCC488C7854384268E0C44281B4C2C321F02232381164E0225488324E838F31E1320848D08122F15481498612012726442A3C134951138692141B1889C81922274E9FA462291B224B1D4E1D8E1A2E689441241D21F034414C341216AA421DA141884D211AE142F21182ACDED181034738F6
+:80E100004B2282111E4748478113E5A984F2885E30422247C726B422C445338D4118082414115024282244811CA21221800227418002400922441021022054841814894109487012218692944C04128890142B21C024228028E49201102102121004C0A249040012422004D0330440080000112122290818590280082D4228882A8228A2E9
+:80E18000110000001001001400218492810020824901142100441044019F1804461114014882481E9284001830942001002C3436412F12114301312480D2144811062B861441411624982890514E814013581883861468121D24224C5129478A4E8E472888C50120C4891348A118291134B82B8260482CF12218A92252826C2862411B2143
+:80E200002245C8848989C1888658C14921A1524246688148A48C2DC1484F8B0B1C2102400214282908442388758441448411E4888682A6282088511848220011171222412584D46C8848128428411801A01B219A3289221160211E245084448A5A59460141DD848C21A88489A18491003A44788408123018128F343768412195120111216C
+:80E280000059420370212202804812021631C1222D11401888448812041215688A29180191406884821C180110849182244C186282A428243480A1432601001A08866861C9812124A114124225280CF02E44282128A12688714A1C0218289422C362A215C186262804255822001A4A84518616318213440132A04249D122122802412C02F2
+:80E30000242A0442211A4221482881825118188021180280B41182034321450547C41245028881A141D0F42B249168B0414302124845A124440029840350141001002481984218002D24404A2804C4828044041140C1218128241A442C332850292053812A5114C840912889410511B428202114021004C84A81F88F161054141602501150
+:80E380000014841042010080829484806241A04411224840084061111800118114A4400820018400002001002281815502644420898288112295288A112821041889087C3CEA26C22819410289D492811425678215922C29B41202639A41C0428124184D128A64544481192C444C21C31968484512024850281C127822813148248582C3C3
+:80E400008CA01212278283A1129B21367811944724146D28C3B4158A3321BB182C91444E184B1A41184886088BC1984CB8C501474146B8227141D8221105001504830217921011982410348228809218282305258102248110B1145198A283021124001C062818001922010014003088004001C01448281416C4482C1138224052482084CD
+:80E480003B4122226100158A460C1162801801000080042414464291121C1101202808D01841048821882608004100822C4808119018408809C029162802812008411880180400488446440177581005200424450280483348484001118F12821401204101818AC482424A0880968228418F180721242C1414428142011002172540022455
+:80E50000C0221424C02260A190140065012908E18221282130424423E4D83EEC004A022024C444244A420824222602131202221B42482084044800188004841694181CC18214881425012810816828B4178222D812CC0836B421483428980010054918318442C8414A018246A4C122826854444F460448218431511014210242685042400A
+:80E58000C221100A1002C06400818902002554214224460446024A18344530422483040080C4215A9484589048A054415C84A84415C148188400004800202402D078376F4B48001342421402205841222A0817420013082128222428000010284411021601002490214002848416282881C488002A284201208108C1106811128E188001E3
+:80E600008CF4C41812002A044800424F8D43A3225145122412081122282481148240220882C22028416428128A0860186042008844125048840088331212040065A2252512582250221137B841650225121432848644B24158225026D022928425825122D022042D848304841902C100000048200421002840420140420460241C0410519E
+:80E68000412148C01480046018424062148088081328081E89924120880214002004008282A0480000890888F01FE32454004A142A14A442200611420021482044C14A144A082C34812183028044A1845041100840322441104112B99421B211016113311281211127181A187214544B1658426051181D116C9449A4D0618154244A492259
+:80E7000051244115F244CE330642408412C224484011010086B1258C421AC22182288242208389C4182224002220423222800244C490218824214088446898181C88A62148182091C114988824802811180142884C0244008A62988FD84C9183114A52239D44A162416813A244814A74C1621822130833E81E3223230C482F48BA14A48188
+:80E7800085F8838840611C2D645D4235C8428D844964284D4526D21294881B44441D53D1984CE83A53A42F29E1ACD26269352DA6CE2225F2C91627B156F347271F3514A24547185E936DC43F25D41258A27F41F952E62B842F2495522F241C7E2676C3F886179393445B267C924845944866D23402C85352394092216413622400B048C2F8
+:80E80000828A82F45268128B642B445AB2412884C8AA444B781AB86253A1822D8986318439D28192838A9D1289F948118D12171786C214ACE84B7811F298C49F22A12447322E18248CF894811F1801497113A8D8214F8D98823042A229123842C6B582D4CBCF2243F24E247CD4845432249CE4246612C89F22E224EE1AC2245D8215F22291
+:80E88000231FAAA26629E43CC2121B4517245551232113D1182204267245C1119A53DD6F115122B042D282642279425283E782297A825323A18B88141BD19F8A02137739F11194884B18CD1C844D8C45D14CC198DB48178841853CCC4A1474841424AF21C624E442D4483A2E41240010080088800800000084000020224108A22008AA845A
+:80E90000A14AA04AA048800468801408801228015A12A424415A025A42A82520044A1184010018004118302820048EE3343F927469F121222C74C6F64A61371459C6C11F4C7EA493A3AEA33F6ABA87F881222F2AFCC3422DA88F88FA88BBBF2DFCC3A1AE21A6B515E111F7A8E1AE499F14B4C1A6AA3FDAF84CE98F4FFCC4E6E77E5FB4FCED
+:80E98000CBC77FBCF44B8B3F1CBCCDEC8CB649EA2AF773B137331F617198E2A1F222412F24F7EA422FE57D9EFF5F9BBF76FE673EE76B7FB5F1774F7FF6D85FB45464151D5EAFF5F4474EC7647DCFBF64D1667246F646C22FACFDCAAAEF6AF8E6862FE6F88644F3F343619F94D655F22323FF74DCFB746353732F24F24161CFD454322F2EC8
+:80EA0000FA23236F6EFC81819FB2EE1CFCE3ABA5FAE8A89F91F5C2C31BAA1BA65F59A8111B761BEEAFACDC11F861A31F3AFA8949CFC7761DF5B7BF7F78FC4B6B75F78BADAD421FDC5C2397B2BBAABFB6F7B3B33F39F95753BFB8F8B2BB3D137D974F65F57A3A3F11FD97F73F3EF64ADEEFFBDF57F74FFFAFEC5C7747191F3DFC9E8CFF7C9B
+:80EA80007CCEFE8E8FF7F96F69F486E66F6CFCD6F6AFAAFE8A8E6F68FA86E66F6CB88EC1632FF6F44D2645F62643FD43FF247222F323633F14F441644FB2F88B233F36F883A63F4CFAA122ABCA3F2CB623AEAC8EE9BF2CFDD3A33F1AF6E135771B3F31F63B611F96FEEB411BE46EE67F12F6A2354F77F32F37FF627FB77A6956B6FDCA2FD8
+:80EB000018F8C9A22F88D249FCC812BF1173B1E27171D9F313A2A73A2D367FEAF7BE122F3DF193723FF9DA7DFD571FFFF8F7172F7FE1FC4E856B8847C9CDD667FD7D8337687DC7FF6DF586866F6EF444C26F2CF542CAA76C67466FE6F886C173F36767BFD4F623253F34764FFF4B4B2F26D237F263631F1EFE2C2DAFBAFA63631F16B6A4A9
+:80EB8000FCA5A11F96E81EFCEAA325A28E9F96E43DFDA3A35F56FA71F117313FB6F6E1E18FA6F641413F1EF6E7275F76FA3464FFFFFEB3AF6F77D3BAF4C6C6BFBA784AF287CB3F26742BFBCFC2BD1B3F3BBB92F9BFFBBFB3F3B2B33F39F952D3AFAFFBB2D2FD9FFFF7F87BDB7F72FB1E9F7777FFDEF48E8E55F7D455FFCDFD9686FF757590
+:80EC0000C3F3C6CF7FFDF5D6442F68FC46462F4FFD1252CFAEFE46266F6CFECE8EEFC785C4241C0448C041E01214E2820410022042220222462232417041021304422004131402400100142110022959142D8294100480089800901110089100822098418211820048828008FC36B8282501419100400211204651212514314200240021D5
+:80EC8000E0410221261901302460139526C212214001302110414842C1122B2898142C89C2922834238118032182111211928D8249542923A814236844218931828054381FA74DF1241287846F227149D824F149282CF149242CF949258E829F4422F9492523D959B292D441F292484CF29249442F99A4222F993524AF91B424DA9AB4A470
+:80ED0000C9494F2ACB494F2AFB41414F2BBB48F4A4929B444F28B949E628F969652CF1696D86F2492C929FC4B292F129252B591D242F8DF424242F9DF524242F9DB524F2D2594B22AF95B424F842494B929F94F4349246F9349246F1349283F4349683D424F948291E928F46C6128FC6E2883A329D241AD468E211D648E2117428F41241C6
+:80ED800043F29249222F88B624E198F424528E484FA2618C4F3231C84FA231D14FA2B1C9E222F151842E8A1F44E3A2F1418636FA49A423E3447822F8419447834E822F11A2A427118F46F812294B842B294394224B921CD624CD614FA288F224CB89D2A4BD19F224DA99E2A2BC11EA229D398E422CE32894292F8894292B481D242F888442
+:80EE0000F29668282FC834282F8926F612288B82CFB2048800840000000000A08400101102000082001012041200000010040000880042001001008002820010021100008420020000CC3764184C5224455128602283A2412488811502841140662462B638168C1159486A31486210C919364586C12116D21432184410B812045283A2286F
+:80EE8000218C01121288A08480982822850430449992A8118845A8184371C4118445048301121A06235148DFBC43F22492142E4844524A1121B824C622281A828202222A0296148806214B81226082484B283084401261811124462848028722855244848C02E825B8849221123B144CA22116A111308345911822100412114D284668118F
+:80EF00002C9244A0498887816E882C316893A8C4E39C244B281CB225F4164843D42162821E442CB42248782102460881211B8566C8194305C48F482237681EC84E8439F284115B21241961113D185C32182E8C10927A8514C4281038184AD884C9118B6129B44169439E219381338E4113A83493811A8359498A91244E154423C544181241
+:80EF80004D388B12BE48899592C4877AF0121210160820A128208221022A021B2230242149622822AF110100204208814490220048210081244823D18462282224222022180100221440480426140840C4481A58184C02888C848804282189C4F4B309C01421118001E0810200278113A221410021301234211412260A0026088042411466
+:80F00000D42801408941012006609149681118282021222122C118004441008184188246044225888124045042426FF541C1281C042051184827211772183F42E132810665C212112B111820E242A2186400D018820651605A83D118618A33214616688124703A484AF842222C828252281412B0288142C8238826DC211318081518815832
+:80F0800042464469415E1448444632188331281A84C138D2148443156211801112C1112D214962211AC4212C7115120218006C0234182481114284201818F1219471724044C1183483032E4A2784288733889C43820116288361822711830816021041092398148283051A944844832125022924F4AECD002601404881642122E3A21150B3
+:80F10000A1268602206121E022E112885142008302222E2141A012531288518821901A81002508002128412031212800222860538183121C0484102854144D54442458304281811684C13C23038483824211012A0411204286011814001A922222421C414186815541819C1124140148208223448648089042841223E1411405BD24221351
+:80F18000410849040083210418A6240412424C02124A12242121848A25F465C10060112241A534223810524248202284027125098439814406822033282A0600856812842A01A302418112C182D12E22C4608C822E18425E49804211781C0881508244232111088B1240480E4922440810048DC74309422C841128810120A1428041031D9B
+:80F200002224A02130180040481101240026584118121648410812844A011884224A01003200004C8391122820840242800446241C28218404814810488892123FA10248288911518C1AB122A23460212A92442911C3212572211463832E182619A2411511162221362885A126814951893E5194228D1848128931C883518486B462F25815
+:80F2800032C41E148A3298485B413E4816AC21B44744838114082B448118438E84A9164E2484468C5484428044AC322CF41889B306844E1210511244002521044981021284842412242848128415440145836281441C04100838211002901810091002542229022022818142082E180044304841818418E02401441A9418848848F0A7EE6B
+:80F30000A042213400800122264181428121E2825222242226012219921282106214000000000000002828848064814A02482004002001002840280100421AC4120048414A8404E04444397900C014212100C012204201301210112121228161114042942480020021336181218484250840022128182518214108800149810184841598D9
+:80F38000114440041212C0441200410012904460826F6C0C4110118411010022841821001B1228001C012400240088002A94142161800110120C002912484A0810041B1251890120820244148480C3180048430184202684011248008C39E52428285041804201142221143618460490181825180110D214021429121524021144448441DA
+:80F4000000161A51814444C4184400C04400142200202112081C01404421024A810400008002C0F41024212202240010C823004845C2211428214AA142260213011110D14401282480B2121178147418047028082824400850484400280000184220810110120400000000200460446C367800002C3222281C02001200A0416021006021CB
+:80F48000385012502590112814000040082518246143211008B04292111840420880812101890140CC14812C01124084525800281A040030488FC30400000011142410028011420240322100240040060040C414171200002444214008004219048185042004001044384100830120011C444802444841004410C435D3071032129024214F
+:80F500008B21141B41230222140000180000601100239122302144198101261642C2848034184508C022211621410884301C18532202124428812884289024441A2241CC444A220180022220E2220427222200434211C4240060211A012665841B2187811041038942544814824412116541040044281220024501A1004110044218C110F4
+:80F5800001508441B01424094741100F10040049222402490410843BCB472224282425B42131211119C213211226B121A1141F22F2311123F1382124282A911227129224516F53F422A170212162213C823114124C425ACE451858592584722814F242454281409151C1184524B21431387024D88121021A51984F411191441B458F8146A6
+:80F60000024E442001803444C974660F412A8211544327221B3295C4338F147222F213112598316332142B22122B512E212C11322125331B451257421C3125706472144572247836568C2F21082D185295922A8B228121A96311C745C18C64444118383A218134181A24C21C2641F4281441806243401AA82230445AA2444C0649F22C46E6
+:80F68000839C222347B32711144282631228B029923212616711A5D83152822AF11A111F1462A11B3141771210516143D2441255142F41711143D8287114584C7022A2135028E5C2288F4155A987111A538C4D26127E1840810245741CF819158F11445CCCA74218284B1156C4144E145F44E54634144324A415484C8224F47C96002820CA
+:80F70000010012221280210241182218C018228C011800000028200128200100128460424084C14800400100221800281384428142214181420148290200124820022E22B3ED43F112321553731F515135AD2A44DFC1F343439F81519BAF82F328383F3351118F31A112ACA1463AE184E591B129F3121E45546515D42652544511F5111179
+:80F780002B23676165D6AEF12626AFE858C46FA5E78352BB84A55A622FE4F424331D1D4D1C45DC7754513E2845240245E444F42C38C7449F13731CBC28525C8FD1F131274B2255D551E442F2252165E6475144422A8254444B66843F1CCD361E922F1352333F727115D5A5922B5D3DCF13F4413B8FB1F32B3A8F82F33873371739F21B21FC
+:80F800003D21BFA3F45A2AAF22F54A12BF91C111DF71788753129E2517727551516D133F31F233166D266FE2D16AF3268EE74A4D56EF9772315969C57E2ED22EF44E3D3713D574445878F7145B31174349B131C3144FC1F5442C8F53FC952117D3DF9972259E175F51F235351F43B114F55435DFC6766C9676324E144B253A34444A62421C
+:80F880004F7434313E362F21D322F212321E1225D6AAA211CFC1F372522F23531329F133336F63F527251E3B2F22D132F16A4AAFA3F151739D139F23D3E4D14458675D164D224F72D244D2457215F134346F62F236342FA1F132246FC85ACCAFE5F43B3B35FB24246762AB22CF85F425719D4D1A5544658AE112F314144F4283D344F14848
+:80F900005CCFC2F36CAC1B661F12F32121CF627219FC34345F53F364644CF5683C7F36F226661E744564457A82F424244B662E2CAFF1C8364F23F932233F72F1171777317D2AAF42F3313DCF13F751321E333F23F332323F63F372177B213F33D3A3F333622F27F332511FB7F3233B2F73517F77382D832D233F1232277447525F51F3343F
+:80F98000122FE1F33C16AD3ECF62788CD6A6F65E3BB7B33D228FA2F22A228F62F54A3F3F93F15D1CC7C1CD477D415B657E144F51B234E342F1145C4FC5F23C7DCF9BF778A88F82E2C27226F91C355F43F324344F12F55535DFE6F66E666F46B574A4544B653E444AE246F66424CFE61A442252211001241081128102101112912200301284
+:80FA000014211421142114501440C112D02811542841850219018582420281100840041604440041100484001084110400008001424483F467FC2001002381121221012F218182D14112021A012C21022A82014004004B22001441800144400210080083B212614400581180824184018D192A0228844901498284C14824702424044A04E1
+:80FA80002800FC3DFF1F44F332484CF212494CF112492AF112494B122F91B624F912494B929CF6249216FD25925E214F2239584F22B959D224B9D9E232F949242E139F44E238F449A4B29F44B292D449B392D441F292484CF39249442F99B428F1924943F2126D4B822FD1B46CC94D4F22C9295F22E914F2249283F424929B254F22B94946
+:80FB0000E222F949242E139F44622A9F4422F9493423DB49B292F441242F8BC4362F8944F492486AF1924843F212684B82AF32C3414F2312F83416936621DB244F21F141441E125D249E121744821B242B1DD7442B598D243F89C124AF9C6142AF8DED42D28AB4A4729238342F95B4A65B924DB246F914B646D1243B484F21B169F4A4926F
+:80FB8000DD284F2139692CB16D62285F9426F92C24272D9F52B2D8E442F29B481F42F292592E2427982823BDA4F2D3494BA33D496BA33D494F215B914F22FB4141493B496F2238684F23B84CF414928F46C2128F46E2283F2E848200880000480000004008140040080041002400000000004400820000000000000000880000000020043F
+:80FC000018004400009F9981681124811D182C01001830B122486C11383120722224222281C421121512A84650111C42A123150118402A8114482898214364822A024B222C9234414426044301102882528828462C420C5A84839111183014481A04A01218CC3EF7224B48221604468892424C3224242C98211222804315041624722284D1
+:80FC8000430A4011122425119814A3450B4B1250A41860216C420A4149211C460822200281CB250041186C0414914014884484862464A181241A44B8243C24175D38884F24D248C318EC012A044D14264122B221A47181844C42A7229015244362841B82248D512C44C25120F329243C45011E34AC428C1188581E45B46A427824A4432AE7
+:80FD0000C622452C4391244524514852812A48E8433142261314994C8460531AA4431A7214624116A2144688AB34386240011480042122E022290850241E212A4101442A81021AC21211800215041112194158280012244820612200008654248480220200260840048148890230144248008014C84800224441BF1A0525429812810012EF
+:80FD8000800821841004111AC124002002106842100440880247428400242001002110322121490200602141428018449824001100181C1444082003000021C0537361C11922421248C2882E188C61814791231182614112212001837112443822128911181814943400178420C1161841814A81012226180513338A2C118112C422C024CD
+:80FE0000224485419411164442CC2941449C52824F8201433246CC612812B02284B61432681FDF8A117221682284803188818B91F4008144121112120000302216285184450420022285841108508420043022269122111B81AD12000032612250C411841243511281831284018C3124442CA61141211248109264DC3F9B851442628110CB
+:80FE80000238402831122443011824E04201896163814028120840941481C06500472118211812120081449022442814284421304422804814850241111094293D4C10284214280860222A2443F83B2C101824814148AC184008854A1842E484121238243841D0880121248A021284240016048306C8604A40022941A88244488A3482427D
+:80FF00002538822134420042588A2408182614224208102898482AD1260244214400D44219C162C04826841106C0121222126258C0121CD11281C424416042244A2881414A14036814124341AC212812440041002422221AC4142285819821421480312498402841C24420382C49414C128A68428143024012F8EDD110420200881200426D
+:80FF8000400421008244221823880681400400841614084200128084080089384119A112004180524412244832222502A021242092214125014E421A8401A0118212898884A284D3C411438281941460811260A112244781466241842B1853E242816369C15A52482142411012CC11C45A82E4840384A8824E1482249014892C68621A86CC
+:020000040001F9
+:80000000480429622243E922C4421B124A8261211880622249D2146242A948CC1C4DD846CA524D826C3188288143186286DC4F582242218118812100460883122242229218904249025028222428121008814011044F41812401002484702181018622E621112418058004244CA24C608100200414224221842A0118301200421C3FCC2428
+:8000800022400412120084411004800218812C428241880228C028443880269824869428842C8121182242240222412248B60222A082A082A12441822124008198812A784C82846442436E248028840830848F530D1D111001400240C2222481D0226482001012044C22016B814982588280428E5122245024C02200241001A018641244DF
+:800100001815245848484C1402A01100882122000022146311084508858A44823498BC35A3C022144044140800000018224280014140024008104204104802002048048041C41241252408401642120A00436A442441202268121084026168869642100400442C02FFE6894291284912411208850441008244400454220085084141E048E8
+:80018000C188160821000029410488002422840082A042202421221104002E21490886514221106D2114200142002D2240942A008C348D241210042421448130224400248100AE1422004C814112184C044484001006168C01230180110888814918928400809842460240A21400009200824222212B68826881202438822B48347BA9403D
+:800200009228251801814024524A842582D182022129012514D2821112921210121218C61440061A01402262414C42522524165224400241005028002002004114100121441441AF11120444201218884684C8D3B211901850488002000000120000604244002800801208A012002200444002008C0821A018002088210241411911020098
+:80028000264201102808120000422554282001DDAC448810088210082001D08201812110028901411412249044000084182014048818222240088220483284448C048210420826A22200C08170160451882A02008410020040E6D23B3383012301281244844014C824280048288440010025044188800124C1100410446462281254114C69
+:800300008102280021686484400100481428292884A18224006044104114C2242444488841D0CEC3216DB81F82312326B488512810D82C518245928A4542F8162222009B21459414ACE241F11416A4814578886488434104A686718448D84281B2865144212541688183D1440161884147422886C82448C4814D152EC3137284D22226A83D
+:8003800018864DD484B2265E446E441F27E2482C5C2884482DC460C2513C393B1CE1A831225549D462411804C12E2244C0181E288466B612712216E222D1886121216CC384C72265542A41508827A11E124592221E18A0118A280225668123082B28414B1E4147214C64289646E268143286221E12690215D132B223C39411D0354E044F14
+:800400004476227466149442818C4CF6B2D2611F214A4A43351841848C7212C824506CC42E2229D122628421C014A67C22425446CD21214C128226B12CD288932467844B2145E244524445F2368626E62161321B32176147422F2A28FA8E92A6F28612271EAC392224BE4246A222282E426B2541002DA149188D9188828D7A2F31D3861863
+:80048000032784E9728A7248DA22AA4CA86F2834ED00223084180044C02400A02181001E244044E841021A02288428800238C02200C09200A0122022A812822A21A812B02421B8240410E212041002884511088D822024A284200481B0480842825FE9CC14DF21D1293122C14D1A8962828D2C8FA2F11A24A5D22A7222B81812D2223222C8
+:800500002D96AF89923873C3122F13F223242FC3722EFE2E682F26F222222AE183F22A244F42F324566F457224DE28E2434184F112211F32B233E2A2D24AF8241CEF423A342D926B132E2C43C3B54F433264EC722CDE5CF33713274147222C6434376A4B131E1D9781AF4852A6C7465F52784554E487644D422394C2CD242E141E344FF1AF
+:8005800035E26FD171327A3AF2282841A7E12E2285F82C28AFE171225AE62B2285F8127A2D22AFA2C2123FBA5AEC4F23D3A6D166F2353165D2EAD8AAE2265766C5FE18388FA2F21E1665B454A522ED1E2F22F384A46F69F114141137312F23722AFA82A68FC1F2A4B43EB29E761AF22E3E2AF2939323F46425A5F82E2C6E644F43F124A438
+:80060000214AA528BFB853D915F584A6CFE4D244F6646537724F4EF84E2CE5FE464EACC44C4F48F8D4544F6BF9DB6E5CF1151BB57222312D4D124D32324CE2E2F11A262D2AAF227222FA183A27852D22A7222D963FA9923A67A3AD3AA751572227C1EF68D2E2747E528AA963C1CF42B11CD1427774DCE4D162B336616A2F287116D331F147
+:800680001336E5F2A2866D2EEF6998346F63F9D6266721AD366F2BD823F442422D266FE2D21E7213771674A4D232F451823FD8D89FF11D1557616F78DAE7F66C245F62786776267E6ED684744CC8CAAD6447666F68F396C333F11717AFA3F32A328D2DCD8CA7812F8343B824F216166762EFE2F2222285F83A3AAF22F2222A2D12EF7BFB4E
+:800700002C2E4F63D3E6F136165F11F33232257626F2466E2FE252CC3AD18AF23E3E65A67785F41E166F63E349F996162F6151333F337232DAAAFA8686EFE2F9A2A22D862F28F824142FA2F214942F38F866267F665222E5FE41417F57F5242425B2427486F6B426155551EFEAFAEF2F6F44F674656F7EFEE4E4EFE454EE2FE4E4A4F4C6F4
+:80078000C84F4EFEE6666F6BF92F22201141040012844008410020020041188041044481000010080000200100001004411004006024004124400200112890221121118284002110021EDA21181698281488250884410028301281008091224181412100008485048524411642648144214C1802901484888644022C082048220440E844D8
+:8008000062220040811A04414A08B0226444210042846A285814BFA54BF1243683F4241693D424B149E221F149242CF14D248E82DF46A219DFC43292DF42B292D545F292484F42F292594D24AF99B524F292494B222F91B424DA9AB4A4CB494F226B944F2B6B146F2A39484F2239496F29B949C2929F46E221F969249E929F46A6999F5695
+:80088000B292F929242BD95F42F292C84F42F2D2CB4F42F292C9222FBDB424F212494B822D494B9A9D494F2BD998F4A6B28F94F424928B444F2A7948D824F948688E928FC4E628F948648E8D10F13448446F91C6242FD1C4142F9116ECD196948E6D89E9D1D628DC52C69A2FDDD234F15825ACF85324ACF958243CF94BA4ACD943C35A9FDD
+:80090000646A299F44B382F449B41AD461FBB24864BE496CFB824D1F42F182484F22F19249CF22F192494B169E495F22FD92492E9A27DD2E13A7582ED2B74C4B128B2D3CB44BAA929F44D324F541A616FB41B416F941A6278A9B1427898F64FA92288B2427498B8623B9687892786CF2DCC88008120000000000000080111104400200203D
+:8009800004100400000022100400000000100800000000200100000000001004001883582481A302801163A2002128B01824410298C022A88C116CA4184C44512810441898184160814A512440C218408215D24831924416049223012124A0184302220044A81088D186C48A414B42E3C4284A084842804A04B73E908100A761168A81013E
+:800A0000412B914A91182C424A682112241608882A1342148242041481002901239185A921A41148241A68432842232862282E1865C884244C08B0841414026922E482460A4494414CA462848840422411A28A468498214DB3335B2586D882322845321C39712842C41229B82821F148122F8441981A983122289827C1A421430C27411098
+:800A80000E842588612117C156CA441823917C212D1458409C92C0124F8491182C11D2E1483284491D02202A62868E2A291164818744236844CC44CA28AA143444A28AB484C284443E8700C0126021800180240120C2120060A160882A82442481528140018118100488301200A0812644223692262438242948240800C024C02429041024
+:800B000004501845C2484B22E0422844021682040028CC327A00828008008800000000000000000000000000000000000000000000000000000000000000100100114001F033C324228C22714C140290412F8542524814112A6488C5211191824B4A6C618150124A088D14672211E08498282A415425A28C62418314068219E48512584241
+:800B800014112A7498D814011129A85A12454852125A88F128221013B4484AA812455421822E2812C74421A0181AE48412D8A23B3D6180F12C486400548B5422554A41A8A88344C41311214D2C4AB8184112D2816428811A5212444887884F12622135840A2AC14445428858124E522295581480B258494C5121218EA4426B11850219244A
+:800C0000CB38255434D08824A8221656124908182E44C50A88E024352284EF7807800820080082000000000000000000000000000000000000000000000000000000000000001400400110013C33C34E14612C0118140011211892818021081A02006012110022904483048126810A38148901400128428A02824123280241120060410036
+:800C80002A140260123024444323042022D484041A84082048F22A6A1001101E423122601226012269289124A36141C2416042364498122E24644C028392241C8244041958244C42841841088C382218497124123814EBA1611230264F828112CA24295148101C684490885285042E42484F61036084482E685885C8284D2313CD116123B3
+:800D000041140215021C02181A4826092622A1D20028285C12A82141002E48C3048712488214921140041088B2428832142A4122D182612A1218414C62818506292254244508130489C254184122219024C4A0144284831448ECB98714048421121902406312281048243198504400184124116022433224412042213224284502C303132C
+:800D800018012889088845D428D84442440428218003D08422018420129484302C4248384F2424212494A8284A8148E2A234B38C41C2441A02418001350860548006212E481480129128222843092A1112C14C4800C04110942884A44352284812262482238C8522012A3841A04800442AB8228411322A0088C3042598224992286024C9FE
+:800E00009418122B48F0E51A546014200200003028405824428301A1134208228C018C08221A4CC4128018A8122100442239E448081002402428221414181441880149120882B0111AC8421654A80022E084AC41221A48042880C4C74314023200302280011C01880023A28118186028882901458802454A942810440140042220012C24C8
+:800E80000100400840322200184B842004214008000080A21443018011041800E082F1249450234A122401100216423821144648E2A261221A8621C2A821268213D8448302ABC28C9214CB4488815052C02444E081DC22247212828182023AA816284D1290A418C889084F8402C04AD0210A894544E24894285A91244CFE18481A11048FEB
+:800F000084012AA8542E2C218D14B04101402422019418908444008823010013E88201261808444512014414281242008495028884421004C908102202201424055024282240880281842850282904002B4818801112F85BD52C84811181012A01245232118002280012431102100288200482821744C02118004002281225026382123C18
+:800F8000C41286246141444C0100882288490681814302A260826012424B261827844245088244C07C235A498D223012A1166852280012220022982840889A84002C8121424203008A126449C024E02184D484043228868802B022082C88180282200200128880282804828016240858850424008A26C468BF9341A844C48C04688036167A
+:801000004A044814480000422266014A0222B044446422184A0C4A222808A5684121C08800428429C4122644A422882024018044042602818122284116024498484B11804A1884818404C064E38612850261100117423126042E8440C44249491C08200240028440C42494141621810422280029C414A23024848C48C28210A89220A284A5
+:801080004928020044290820088B2488822C866A284441E081C4241A1204449F9144522442121212A011800580E12802A013822AA2C1288218248014D4248898424D248844244C014149E344423844C8C08800A6C484801858842E444482456441284400001A92142847882C423844284932424084228408205141413018682692681400FC
+:8011000023030048112A842C6221420044421C410422802108208404180016812206C81008298401A052248416022200408402818C114202890847883018874200C028A44381A624EF3F87814241344180041128457112B1840243441194448150454211000080820248498182020020041042142208001004002222001212222800824171
+:80118000448E1400848001420000A2D02838391014024112484014C2264044424402260644244C5221404611644144114C28225842482D18454814042B819013908441830149E284123C14884800414122128504408A4A942281A2241800844002441810F49C1D384044042A8492442184417084014130444291411944324828188B22E08C
+:801200001A02830123024844A0122200228976840480042800284282838318A52890124902182B2A2001210018830400A01218492182021C358C2D6C4D7C4FD3F44E51CFE1A4641B634AF21664665445444F48646647429E94AAD164B474614E17427F44A4243264174646E428C2A8174487164EC44B244B934B21A5D444B154E11174486F
+:801280009C1A182F42928A8F82726874ACDE64FA84228B8712876B4F449124A24F42098A92143A124CA2818E22AA88F222248F4162822FACE89BC76845A8A446A842322B8A3E142E414F82F24115C43F81072B126138111D162B211D172D1237432A626113666225E4262641A4C8290235D122711864842681882B76248438942B424F4593
+:80130000133A284654444A997A4A59418D84828B5E1A89C2844FC26A283AA9A2274D4AC8242684732432144F8462818782C7484416E82868C88E184741822B68478383915445B828E1412CE882A4745272359211222991184AE112E424C17822CE811DA120E412E241E811D2C89262499C282991324382BA267436556649B885EC1A32117A
+:801380002F5C043883F3222666026AFE82A24EC28E26644129BC22C18425C83C4B8460414C88C2442E1630842EA82D282243F21264AE848E4A26E84CB62466446B17124D46C1AD12184E2C685644743E4E4468419412841226114201148814219092412911B442184488C21844844C426848118614E16982E421021E2448802489243824B9
+:80140000F0244830243024184118800880020028814C028A12C824489E2448288480240192005873B642E665F466464F45F444445F15A4421D555D2595DD6552455F47F547456F62D27558467F56F4171E4F6418F66D491B111F92C218DF96A4443D2D86FC41418F8CF6C14517312D442F21415E826CF41151486F28A5223F7B718422F879
+:80148000A4E48CA88943BA849A886F63AB4C7F288DE853A1226F218143F42C242F21A121A5827284D44CF216162827ACC7C32F61D4CCD288D4C474126A82A7A847434B1789F28BF57CF7614DFF67F476476FE7F4544D5B251AF656755FD4775D7626F584F44F4FF446246F36F185BEEF51F64365FF45F6A2E65FD2F64D515E11B1CFD1F637
+:80150000C94CCD219BA3CFAAF66E24EE417F74BDC3FA367666D26CF13E223E5553C39A4B944E517F4DC2A84F48E8A8FCCAB69EA62F687AE2F8842EABDB4EB73B2E4F4239956CF31224167424FCA43223F138AAAF48D242EAC8D2E4FB96288F68FC7E744FACD3CE721C78687848DA8EF318AAAF41F3C45416FC243BB3A2646F657426F6543E
+:801580006245F651452E211F11D344F25C4C7F73F3A5855F43F165674D467F52D9C4FB65474F77F746844DC27F16F459583F32B218F365E58F86D4517389F565E39F8CF6E4647EF42EE62F45F5222427833E461F51D74CF48AD62BE63F3BF1AE268B2ACF4AEE88E969BAA4F884EC26F8369EEAFCA6F349E84BB924F216162D266F61D14438
+:80160000F81A1A2E38AFA8E8287A84D44CFA961E8F88F6D282CF83F21646CFC5F24A6EAD4EAFE56482AFA97A34A4574FC6F2DE361CF76537FFF7F77F5FFFE5F55C59DB751F65F753355FD6F36D366F13F285F54F7FF441244F52F387B64F7BF7556C5F65F6A4E56F3EF641798F37F323186FD3F66D644F54F225895FD8F6EEE5EEE75F56DD
+:80168000FDD7A24F43F764386FE3F13E264F17F5554C4DDA2BB57EF73FEFDA86FA84ECEEEEEF6FFBB6A62FE8FAAEB8CF61FA9AF44F6D7BF3D454FBB4242E362F63F332366FC3F22C3AAB212EAA2F42FA24A4AE2C4FEAFBBE2CCF6EFDF6744FEEF76E744FE3744EFE4E5AAF85F318BAAF4BB3E4E547F62CEF224A01240000A0140000008ABF
+:80170000021280825442482141904421418084884402184118004002200896048E24A02160482008440000844008410042A0844142000020C424F0743E90248D484B114E4861681642C51222884B42702414423412267442822288A214002A0228E04842C12442966684260226A4441889E628C82890248E8283840888C1982A2214042A5B
+:801780000241124342A822B084028E24814F4812A8318518841484A28120D144D4611CD949F216498D342F91D448F112492AF1126957222F91B464F882494B929CF4249296F9249256F52492874C4F227D49F424929B254D92BF44F224129F447284F249A443F949A4671B9F44FBB2411D346F8BE444F3924946F692496AF992494B822F45
+:80180000D1F66C822D6D4B922FD1F624922FD1F2249256F5249283FC24D293FC24D29B2C2CF94B242E529F4472A4FA4924BAF449B46F8BF449246B4B1F64FBB2498DA62F89E444F992486E122F89B424F91248CB827E45844F627141793462964F2131454F21F1682D2D121F44E628D948028F54B2D2F94825AB584D243F88DC44F2D259A4
+:8018800045F48358443FB9E44AF2914936F413486F4AD992F4A4361D484F2B7841F114A68F14A4838B466F21D11DF694829D249AF16D6C272857469E12D744DE12DF44F28852DD243F88D941F252DB4CF2D2CB222FB1B1A4E23DF434A4A7916BB22F14F4B4B687942F43A2442BB995F8A6926E486B8BCD6867218D242F29F1482C9A3F34F0
+:801900000000008001008100000040040000000000000041001002000000000000000000000000241024040000001800003E54D031F144228114125622011B911F6214A1B8B014A12800CE94488061224064214D22438198812855B4510A3B2B441B2687118199941281A6028DA288411AB1848919249114A02118E0440248A0228422B062
+:801980006462818A82D14422A448C836184442A24286F81442688F3137CF84001721A10023712844220248221C0288004160C8832121280441254C44886281502884485A821D049C016A98482AC12228460885042A14C6182362828AB112E2424108493488840016021638244C038245081068261615F21166841D1145A222211D441A4197
+:801A000022F135211E278025B814A6218C88C49548C0288281988865F21414A486521443B251A19235C22189A5129F8473C1C2148C6822608E2336241A98449E448664C1E0578113D88206BA91428881384B8489921C8C18321216F8442418622A5244442C0287E84E54F06A35A306291468118D124002812328242882928100824004163D
+:801A8000C41212414222501488844C6288282668448428604484190181829829A2128418840024A0121084B2248122120842222042248318A49486181802482A1182F19D130000A011001902C312621690241880480422230880120114008214004C091240840460213012430228988001002542C41810080010048220014F4181044618E3
+:801B00009248490840A488842D8223344DE711274481710023210410422C9981295A243A642C90481E24407A4C422231282C34441382014C632215D44853812483012C028127882F84C31240A618274249E1228839143268414988422C2342044914E44631C223E86261214846142AE1241902411AF8E795441D1181635428110039420841
+:801B800028239488436122800B422AF48234400815028422102432112031841371180161812450228BA18902218048F4221428E041D1420383C5842082024504824991244F45E14C889242258814B846A84182252488C1DD93CC48610049810118424942025430819A1286D442088100212E4E20413142C811004C32324126140858A01282
+:801C00000064AB141222472918126028230820420C5084122200420021166245122C1414082301308486FAC1EF103C4410544A0011909828184C34124A9212A08287121A45240A22AE848B441661814A4222654216012CBB41E28123C8348840282212924400967254381281481C96848418B046C8248A22244104F18F123812214A120277
+:801C800028C0824482850C1ACDCA53C141C0284A024A11022812214144281A5641304584112C084018212882614841648D4448414C02004E2800881241811C1318848294848CE244684911281A8484C828892981F588462824400418102188220145420160424F77010000001082944122850811411240A42145044A2221951610144808B8
+:801D00000099021200A0414820060021284C140222002AC1442121490100444008328420018148842148C011C0C2C0DFE34B6544284481401282B211841964C12661414D21124F14624838969244128CF68423C16E14918B488742E0C2941114381303A6C81843A448E21A322481176248224D5243A18230448AC5344F24725228A4488137
+:801D800089A31449F48844C4366582A3C812522312A148A418299C8284848AC42477B28C048420941243041190682183C2124B242C01802251444AA82218800540044C214434484742482B38202124111414480212858428D222912C884C820482441E1249229824002122814C11018400000018442C81F4913E130D24006024A44642C2E0
+:801E00001424622CA2420040148884011210E8440200A081444014D448C1C4C048818904284120813284188381219294244AC2881824709412DC849122418058848C9844214332861A1432142B6848824440F4AD8E28200211112844002308448213382444821F4818B38428624848402888249AE210021C8809C014425044884725842A49
+:801E800011082094222188128C249164842848488092824884448904A08180017048289228814820D87217094A822204201498419C8402188001C042800248102401142042146482180017821A220284182604848058241248460C4446424412061AC892A03420014281218D1221608100608180C4483829C9811E9C1044041014118A028A
+:801F00004C48020082483281324C44A8228E284426014B184988012488602200811A11212288280442432205218A1A183288A60820422402218E4430124112408861143048490922D022210289D512379E228168144180C22823A2612988C3124931142889889682128812181284418002A0411818519A82A51800418280041AA2182244E9
+:801F80008A0124121880483144444212604124410011185684E1441A04AA9182008825C442415E1F6440022114210090116018882CA2184F14A211C112382D84201828018098428A828628224841038E51208102450428B088048170142A3448281152234108422028048110043024848490442A020087C4D06834751014412404800400B4
+:802000004122140044144242110000222A04800244441854408C0410A814004788002A411412084142418120014C12440848208141048821422C31480081202821F88CB52488644200A02480C2142A010000801624A3145014F084410020524E221241224E446042118003008841490186048EA630841C180486022441822444244C0120DC
+:8020800011042A1D4214825C82422518729214E1C538B9100643A4688C44448244022D84471818424B48148C021444001A82024A4B840142802241828A842A8802448422283084A084368404A423E3B8342241248A41F2821888811840421812120223012149124284448842F97C3E908647422F42D45158141724AD68B063D341B1865183
+:80210000144B5B3A711644F994246762DB4B4F1773A2E445783468418E2113AC22C0364B16AE424F41E112C3916F82F538194F1AE681419C988B63467488D8C8A3B24F48A24186F45C1EA7EC4F28C58429FCF2842784CF6CF412A625C6862F8CD368D1A84232424D188E1184EF21C4822BC22726AB44AD4A2B4867A8AFA6B42AFC5AC42344
+:80218000F68F148E4633392467AA623D444A44BA6854C2429F2484D12458268AB8A4E848312418CE4232CA248AE8834458C41D544CB5A2AA884B4447818AF98485414F52DC847184B4C12421A4212CC6244C9914CEA84F4B64214C638345B6527D15F46AAC2B14360C8B854C728626E2447D44D484C418658458A46E146D15C5B41461C2D7
+:802200006B484A08297818F418518F48F41199242A443245C04220F262222CF834A22EE23A5B5119A422D81F12BC418348B414B18841E582B334A46244A22D48284B212A126423D6C1E24A213E114538849AC424C8812A11E621ACA8882F8328DB2412C8A12382A1A16B551256781614426841848F6581B154A1388B589692945E188B21A0
+:80228000E08442F298862E42AF9135CE00224230411048240420011200480012206982122E4120022A840118221890982213048128422889210882421A122881B492C2482B28A021489A42A821484008842C011880019800A0820082EFDD4154848942938345BC69E284A2244F24FA44B6B6D272D316F881222F4BE999FBB5D11F113AACEA
+:802300009EA673EA487114D981E948B424E14112E4CA3C8C4B414B848EB55F28FDD2E4CF22BC2EE114A9198F41B9A8EA84F22C24CCA1292E188F4973747A4AB692F2881445E278E621E468F5114446F4342C8B6236522A2F83F12C4445B41C61917129A5746E2887C6C7C4CD5883C8441581E387E983F178181F9934DC474285D831F463DB
+:802380006744EFF4F622482D4E17723F58B494F986925F5BF891916F28BC94F9959D1F1DF5B2976AFCF6F69847489F12E34AF945A51AD744A388EFCEEA42F572669EB45F5AF8C3C35F5BF2DBB72E441BBD1AF19CA4AAF4682C47824DA81AFA3C1C4F4B7BCCF81EF6CF62F8961E484F3DF928688F29F962626F61F36EAE2F6DF92CA6CF21C1
+:80240000F34C3A2724C5B6187111FF121C6F44F4F2F26F62FA1252E7E12F2DF386467D662F26F252DEAF4DF35A7AAF6DFD77FD6427A2AF32F627433F525C85FB242D6A6CE274FAD1B64F29E278F3B5811F2A3AF28EB4DF39FF93B45BCFDE9223A938B6F911989E611F1EB111E261F8A6ECEB1E3AB464C8B11F3AFDD7C19F28FC2E941F1EE1
+:80248000F8E114CB81CBB8FE2AAF26D28EF398A44FE2F2BA322F87F1CA246F2DF298128F68F582E23F69F48E76EF63F544244FE1FBD8441E148F29F2122AEB4545D8CE71147915D626E144FB649CE785C785EF45F5E4146B41C994C3AFC5F83E9E6F4FB18C3D416F42F22E2C3F72F647675754AFF6F42A68EFA4F664227F3DFFB4B66F42FD
+:80250000F3B3B11F19FBB2B23AFBB5B53F3FFFB6F6EAFAF6B64F42FBB4B49F92F3A49C5F56A6734F42F28686CFEEBE34F576644F49FBB5B53F7FFFF5ADAFEDFB34751F1DFD141C8FCBA9FBEFA67626FE34B84F4BFABEBA6F6BFFDCCCCFE3FB289A6F69B954F4F4B6CFCEFEFCB66F67F63616EFE6FCF2B6C5FC3C1ECFE674425648CF41F142
+:802580001B1DAFC1F156542F2FFF46A6AFE5F51A4E2F2DFDC6C6AFE47442F2F6EAEFCDF25E786FDDFD1CC8D0424211820410E212948210521429180426813824108401000040048624A421604815A82111828400001024011884242298418843823124188041444204004489144268418C24812489048C341245C81E130E20141401830474
+:80260000132228220912604818C0D2DA12849284282E1846641244260222108461184A521419A14120A18428E088322482184CC48286842144128A04201C144822048143011280A4840041811028882169243FF3CC414F22B348F424129F14D424F149282CF1496C2CF149648E129F44A6199F4432929D242B491D242F8DC5242F99CD246A
+:80268000AF9DA522AF9DB424F25B494BA22F94B424E994F4B4B285F9349246F936B28F94F4B4929F84D424B949C6929FC6E628F969649E829F44A6199FC4B292F129242F29FD21242FADEC42F2DAD92E24AF99AD222F9DB524F25A494B822F94B424F948494F2A7948F9B69287144F2339494F2B39484F29B949E228F969248E928F46E2CD
+:802700003839D39F44323246F414699F64F2124C87422F11346825BD647912BD44F812694BC29CF4249A46F924D3A7154F2239994FA2A42D2EDB9F41EAB2DC49E32AD569C24A9DB42F8BF449348AD469F3B2489F64FB96698BA4275987442F99F66C822F98B26CF18241CF26E911F62CC21E614FA2F9D2294F32FCDA214FA2BC9BF224C8C6
+:80278000BF49E282F511A42EDA1D348E5A1D264FA9F448A42F91D461FBB4486CC1496CFB14686CEBC1E462F892684B822F89B624B85609880000101408000000000000000000001002480000000041000010040000000000280000000040080020024100113C3EC87611382646149112133348488212836881523688026B4982A392481C3A
+:80280000C2482621618326C945250136858685C1344B1416C14242D8908240A4242C2888012E828A2243C4322C024931222CA882004400421C24E218644C42924938144C18088B28C88982F18E1E248908C28542113848248E12A016A849021008E04284321489A241004A0120568144842AB4818402871441448D118AA3142818822CC21E
+:8028800028212901808208B849227494249644222890244521C112D0BC018167244821489A9843B02814E1AC35A293358827428F4244110C46A8841A088949A8144E381098461968E612148B612A04EA91285223045CC2464E189AC4544B4117812D4122C8493182C0244A022A5882602C2A38287021C2224143A3212A88280A1A0269B292
+:80290000119441124B481F6488B44218D24284D884368226A84A2E49E05F0F23820CD022D1912601258226C124922230289828C02487842214608170119124158111A822142820221464844B8119A61180092728281682220112432289A249442F28D4448204504400C022941885C814B08401490919688480E4A939AB000040010021413B
+:802980000000000090140080010090281009810012608144140000000040010010040000006044100820014840080000007FAF4201804504422502A0A1106A91181428402401404201212A2104000010018082082024024D12200848B01242341224124A132204400825110440042902469114898218222114128211C81FE34C012045C44A
+:802A000041242430124B8220112801280090141002182004C02800100920018C480422000000102222012410040010180260441048024A0189052588012424C018F0818D0000000000400A144001004301001410A212000010090080021214420049112208481814244120A1142322040000510044800210858208480000C01E630A0000D2
+:802A80001200008112000080024800408401110000000000120000008480042120881102400848C04800A0420000C02246024200000040F2FCBA00200442100900800182440000A0220052188480041084F41414C0281A110400124280A1820022220040122402224C225C4400100400A0442884001088880440C86D334F01200100000048
+:802B0000001041010020411202288400000022004001400800100444901441188002804402008002000000003800000000441F2F0E11200418100840081800150120828462210043A51385188104003014008F12011284200140A48120C41644881AC122440046A2424CA248C5840244620000246E42222200008200C42533360020210414
+:802B800011000012200844000080420200000041A0424C011841000042008C02442228000024288400420000000020046081421008800400CF5E0500000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000048
+:802C000000000000000000000000BE1300002210040000002004811001000020081210020000002002410000000042100811000000822001210000000022100400C01F830900000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000047
+:802C800000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B833010000000000000000000000000000000000000000FE
+:802D00000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B01000000000000000000000000000000000000000098
+:802D80000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B13000000000000000020040000841400410022000029
+:802E000000008100000012004008000000000000200100000000000000BF4C015024000020D21808422200281228122884200100480081800800004332121800004282400200400228000048220020044420421124840100100810C425938A1401002001002149012A581800004100898201218D21400426212106855182200414904290A8
+:802E8000122021022410022200200849018002412A0818469442800821414280048880F419CE48442400800122881904320089228122814288010080044481A0821200402432121840024820A82150220021242228008200222840A4248011E422045142002004810049C435630914000000814042048A12010040046082121062920040F9
+:802F0000012A0494850242100142C0120000000000000016840400800890440088C0124100428008F026334092412C1108423028001822248008002012888201120041420040280818118210020080A4182A021118282B11220023012C0142400215280298100224A0188324010012688E8A431648381A504284164213B8A811D89448AAF3
+:802F80001C3014328A22F484584B21166815A97428E4E6115818AC62524E38818C6415681AC6284325911529B848A1128D166220A481282C08412CA8241249842327249A19651801421D841E882E442E18688B21C9227484D224048C014CDC4884F159258434105A480027912228105821812120210298890185A116184C154A1815482857
+:80300000018B14482A61821584C1140020B11402A0138AC28280C282122280828481CC195014145048822890227028084C240800708418E4913DE940886521218C0421848E18F08438A01C908418A2486674288481714862C2288160261D244A4208930C48325A083129E88184428A848C2442011816868284715482A11229840285420295
+:8030800068118CB994943842122D24C827814E16C0182085A4C24756002820524810120A27442289016084241E4528C501B2122D12846B8845025240420849086A417C4204224E4143A9428424C82821203448904818178A66066228A028872D4AB6140430122632189288224A842C4284212405C0B3311463044982414184020000384B24
+:8031000042B08402841121608484228AC2481824100282498201200113036112000081829A8442081001002084888101422100A0434711202232142C1804454282F28F6B00224084018014941100481718208121321244841112220000808104501110822208001688D24215B822914841000000480012810022282012084800288844848A
+:80318000000048C03EA211438612C4141911C22A4624941420B181772461816B381A9232B09212B948B12A112A3248100218463884862444426E4B20B5113C324E1889725CA22CA34128BC888102A028624626244128C45816A2244223122812AA84181B81688AB444C8142988A44125C442224F6C0A2400840000241902810000485504DA
+:80320000441810C224824129040000142A132121041400002110E242040080041608200222822A229424481880011A2234242042082001003C31D514001A42C11248409AC24E88881C2801242822402204214283260248200800193268A68185810800482828882A240524C082128828241ACA91221A24C14242431C044148C14B488412A7
+:8032800041616021188A42144674560B702204110089020020429268A11124CCA611848E8244184C6188C081212FD44219A2826044408402A09421430690222F24A18822120012841638843A1484A12828214F410229011880218681A2A40041892A042988C465F33A2200008994228914428822842124012B8180C84820C49881A1C03AA9
+:80330000408848082D18840021100220140220044082C212602266420287312C04248140C24C48828972923412702458C22924D4280423642228422AF86416001A82840140028004A942018246984481258431228122601241828B82122958228564422969428A8891244220E4410B28C2292288848132842A358810242808424B484184B8
+:80338000821A881104882C03880081A84A014A08D092357A3072190548144289028C18928823C28993820300781A028249842104601240018091884D4249048014041E8200408228029048B011C288160419898A02260200584C911820E424113888108424088008DEAD442608241220022189111208A091840022881508820088E0280163
+:8034000023092818208881034A88880480211821888244024223324828118E489018428216A438C11200A88410884824218488023024226C3259002150852C9138009084388514022490164641C2C4230123914221004184228038440040824412120244212081654118200820312828406224244842828002484C0200004002C22C44CC73
+:8034800044DFF7011428129B5400183024005A0990212025E54122088781448100688541012480B928D122014800821A01200100282846B12201214821148421A08122321012042602504866443258104A02C022C013F34F0129048C92484442002C12422248B411942484435218209234229029394AE182B114C22284C94282A4242C82CC
+:8035000042820222482A08224C04001A0426EC28641125084002468448921842244638288232B01204842816485428484288DF278C0283F1411236911489E224C128488DE82B168E818F22E8117818F121848B352E818D64ACAB89C0488F47554A3D122551235F14381213D24861418B12812D12272F6E82272A6CA14D6E962F41011BC8FF
+:803580002384AF562B15B08229F1C4928FEEC4288372CB91482B557626B444F222888A8C217814E826B9B8D3823258214954224B442D322F22EA28BC42D24C4407541AF662121CF4181183F618282E624522C888278A43F1598AAF137E3212D226A523AF894FD8286288459238978E89B2287AA1C8811D882F22D2E8E26EB186B7723C4469
+:803600006A21842424A1868A732282A8969841224F1291282C7361E2E3EA28F8D924AB942BA12F68E88DA11247444AD444A52443368283F44C586B24EBDE6F8B145C249AA918AC12B4C4A6C85F864EE322D243E112944887243F25C44885D2A87182C6482F27329215048B314B426C34546D446E128FEDB3B4D1242AA4221D5287842FCA7E
+:80368000F22C2884A88E1A1F8CE648B835D244014A2CD82222A1248AE422E2223966282E422F23E122F68272A0811E161AA291398A82F226562FA27948160E4F81B128F79E2441AA9114CD48237948D8A8B248A44C4A72247282F224E7F304001D1200602410283848922492241E2424C042822412AC041400882601229826880918200433
+:803700004A0198108412044110044100164428092022410880618218268821822152284118288002F039D15CF224488F24E381F418467D4FBB244AE147B224F11826472AAF445895BF617217D3C9F216646D36E5DECC75BF788A7A1AB626F6346AF7A6AD4897F6F79897121D288D8645F426662B3226D662D322FA42822981A4D44AE25277
+:80378000FAA5644DC62F4DFE94644D266F13F881884B896F38FFDCCEABA457991CBAA1EA4A788614D486D4243882188CF3228227A12B564CF1289AAFA87CCA425EC88F2AEAA8FACCA64F8C3A488EB173FA2726AF85B432F249797771FFF1F53818AFE3F52426AFA9F164848F82FD9615BD89FF58FF293B2FA2F146143F17F46CBEEFE41A67
+:80380000F2B694CFC6F36A36AFF65EAA1F14F7A585DD269D218CF2B616E7CBEBEF2B6F2F257432F262E22F24B414A4544F4FAE235F5AFAC4C46F2EA6BF7AD4447515F5929C46F4F7958FEDFCA8BC9F94F571F1FAFB94964F42FB12128FA4E348FCC2C64D14CFE4F44636CFC9AE34CD28AF89F98E868912F49EBEFAF88ACE49D6AED444F85D
+:803880008EBB545D58BF37F3515BB7435D195B258F86F1582E4F22F11A8E4F2CF14AB55F3A7891F77531BF42F21C264D765FC7FA6EFC4FABF3888ACB19CF26F63E637FBED2BAF6194FDFDA782FD181D268F88414EF6FF4BE34474E4F47B524A886584B652EF22F47FA94A11F4AAECC4BECCAE622F352A77F29FA9AC42F2DF8A5CEAFEFFAA3
+:8039000096591FB6FBAB828E564F69B184D1C2F45486AF48B886E5C4B324FB186C4FA2F34E1EEFE2F9EC8AEFAF746EDEAEF89EA29EE88BAC8E688F6874861AF32525AFB5B632F65B5B5755BFF5F5622AEFA5F52E26AFA9F1ECE4AFA2FFBFBD9FB1F8BD95BF91F124364E723E35AF46FF7CB687A3CF4BF97E7E8F46F3496DBFA2F26B2BFF5E
+:803980007EFA8D2D9F92F228286F2BF3BE6CEF4FFFB6246F67F774242F2CAE4C2F61A5546F2FFE34243F1ABAE4EE4FAFFF6F67F636361F3AFBA2924B9E6F7FFBF8FEEF6AFBCBFB3F33FBC2926F6CB942F75616CFE4F486CA4F6CAC55EFC7F6D2BACFCDEA43F75C6CEFE9F78AFE8FE454E42FEFADAFEFACFEA6E6EFEEFC46861FCE0229923C
+:803A00004180244138122288849826196292182218A01422890181108802449182814C0290481A0280043012908241212AC412222C2182012C21022AF248920044464234488624C4248B442F419248160427480048238884B824D492260250211041086824844602A02818004C02C6048A024684912920E422041489024A29C822128084C2
+:803A800008A0612A0888484F240920088AC24282849234822A24C1422008221848880026989848241E48A0282482F06A93144F637148F1241293F414129B642CF1496C2D929FC4E628F949649E929F44F292929D242F29FC25242FA9CC242FBD45F4D2CB26F4DA5943F213494BA22D494BBA1D494F2A4BF9B69297144F2BB949F4B4929B7D
+:803B0000444D929B249E929F44E629F1492486F26924929F4432929D242B491D242F89C5242F994DF49A492AF2925943F21A494B82AD494BB29CF4B4B285F934B287144F2B7B48F8349683D426B948E221F968242CF168248E8913B2491396394F81C6322FD164462F91F448122F59B2687192A58627D92E422FD9E4A2F8C22D4F3271CAA8
+:803B8000C152BF41F224C23B2C4DDAABA11CFC4934AE529F64683B9F4438321D966D491DB44F98E464EB99E264F2824D2E942F91B465F9124849D8D2B624C9495F22CD4D4FA269D44F327918F524D2974D45BA49F224929F45E8A2F841148E1A9F6462231F4479B2D849E38BD469FBB2488D146B696CF2824C8F42B192362C2B61CB82BF34
+:803C0000430C00000000001008000000000000000010020010080000430200000000001001000000000000000000000048C034318C92481912D14124A142AB251A044814425845982118C621A8282AC94811486140638446021A041827925C82711804278412812CA881125721422122842C0A8A220432288118468461838D4423120242E0
+:803C800011504A1E4C50246C2588440229A2251887223FD44DF21112112D1847248588110127821E121328E58AA2982628B124B212618212284C4A98A21E4281448428818E34158241A889F0C1311886D21821F41123808E222891784118E041810223A4882426290341268402424588BA42C423C028128A14921881AB8C56D42A84E47845
+:803D00003F45B42D58267138C44541112E1223151823A1A48B1C4F8C1239181996318B21A2421B28872486E4884461C5236482981612323A5BA188596D122E92124E111B813524F11281A2218143A4863028481362242A988829B12C048E18663C3226126244A0242D449D14D082E2216426D02C3182EE128726528D22FF1307321121173E
+:803D800084299168128B241848921304221AE142C292A0886081260428272110028160144B12141028112871481812989222B064848182312829019A11842102281C01124302414840C982842C22C414B084C848C048406421488EB182181481142400004424002840542182A0240026B8188281024484201218860842224200208402C4E6
+:803E00004602428A961444004882800282004074248808008848181048F848822004838414F4B47C8457C22B42474129D1291521711128758268894C36915F289A8930341D241664488B224B448684121E7828A8444382B41885E194725428D31101188ED145B318C2438912A4882AE1264194228AD842E821D12183B16CD724C1A145F256
+:803E800024413E6425A42442D04C869A7425B214FA142249A122882991441A092D828C612A8753F30B25688511991122311184218420A728134A642282444964824C2214FC2814288446B444024889B512C4CC1811132124514113212426022C829442C84C3B864B8121428B846A21C1842F42B841819644684C1224A428788AB1A4B412ED
+:803F000082C128239882125890828B2127833DFA18D752264452241452005E8430928565481592881C511438A844488C0A322189028508288341849321890422A0C8160A22B504C3A81C2A811206C01138291354242E21804214024189D84842444214221124028D1C424A484228644CAC33634400144416C241181A24644140A4412A04B7
+:803F800088184E28118848224C842618E242113441004D5822841C44A4424459944180840482244D48E08124220261114D22B8262812E442A81218C0482C245848838888D428054EA2482449240890144F470C13C13820721204108892816A123A281CA12482442A581C4427421120821A051A041C0483841401800921C08C14284121A0DE
+:80400000822321A884D048834B014E4120448224081A061825041819A431800A26823484201588C851122100840080322810085215488261220020E128228141042A0483C2248C082018311442002088823212141A220448209182002810044400421149085181824682120252C4490121849042422F39C31180039D14004287832AD441A2
+:80408000F248288C7124E82501A286A4C380E14AB4230143742474210248CD414183084BA515C1454442E245B4415881222E542229A9622D4241902892384D84322E42475216A8224544A4124681628C4A3145C5A85891FE222C34182E886524642C4A488894824F243546641008242311014A818219224431211226024302452228A22198
+:8041000048A0424C22C2223C344884428418801102484CC84124140089A94818E022082400CA820424422210048018C482A014A094482C11021E4800189F66CE1129D25117428284C128806211128718428308190A82800183381183E242042A4154A100214D812A86088A3825C820840622241CC2422022018E62481288182002244400C7
+:80418000231201202622624800844692884285280ACE99130B21D09204142800804291842712200225044242338244018148130241240020D81802604881144814812323C48481894112B844432902441190212004444448200610C3288C448408004A0110F418F52849054042220184264A321C002212224D844E2812004C0C423AC244FC
+:8042000048418042324482C18841CB444C140883E84232984483424404628280018C5424841E12848A4818440845B824449824844901C5024632484924184244A8248D9C4307441422440019144441816412482A48281181C8216A2814110411001B181B24248982C4421800404106004D42467128944A224D93C11C4D02E1388C97444E7D
+:80428000244612127122B82104608820442114012880021002002F2A8DB844C228100C204164C440E48834128C044800000081108872184424F44844008126F4682420021282482014744186682210015584260823044C18928400141A88122608288214230C8A0A20840192A8193CED1C219552154241416D120041114912A1284845616D
+:80430000922214702821181131A119681A40C218858488081119084A088002142422421440011221234291120040C1424624943112243082C02A3081242C845228C881891402CFCD8A02440046C22200A04222814C08102202100282260260244820024004880088C100100DA08842818181243422448254242211304441880030244518D1
+:80438000944441490210140C81274444A2EC1B8E4412084CC4148190284B1489E42432884C1448480882682242C4288C08C420028F4824E483944CC44843024084048002408298C4222C0B43818122842AE42C820429D2240280A248202C082D28C72840821A2838622A48B4B70A004820026508150110548200421018111101C44008821C
+:80440000A03549122202002905271670211411161161884014D182718538448293D86111615221855144812048B11A44B44242444184E41285429488221084C14845C8A3637311671D2D271563244F14312285018F315612755DD43F122AAC22A644B518A224CAF249811749D582F2416844571459D684A5416D486E44C302DD218F42BCCE
+:8044800041B41938449F146C2697122F12D23CF868482FA8E454D212D916D81A73327243F11C322D282F2252911F44D2B3C8449C7464722378856AC285C448A5D481724295615F8312724A3648A318E281A4844F1CA686EFF28D46E213C74A45744403A71228C7424F51D28CEC3AEA429C3CA6D882C4828EA1284A82283281C18C92412B96
+:80450000874B675B6843B22CD444084BCAFAB4848DF2AAC457A443082216C5E176F2264C45FF8AA126E151584C1BA32CB2447756E5249A14444E448358A42A3C6559E542A668474A2AF685842727D7881B246F4838C86B482F8AF888C22FC1F36222CD848D33D395742E46CD588C561216F218116E28D97421B85887F448D289548815F817
+:8045800014215B4288241E412F82F44C682E619F833884D78222503AC3FE28228F81F8C249C7C2A6922547483081419CB444DE481492841BA2F05C4E87CB1E828EC41EF61918F4D8144F21F726CAEE243378464234142B226D418A16A44E433828C37EC2B28C2652848CA444818E1C89D84872D4031112840012844039128C84C8482948AF
+:804600001802290821B04A08A1100A008110682881861268688561288124811008108284011880018C018428A44008A428844088022902002184210022882E7843F246263F21D49156936D441D432552914FC27236732356937F59D5B5D8A252A2AF62523137A8272427349D8375537F6F68FA2D25AF217155D51196429ED48D242F65F17C
+:80468000AA46AF68D4D3F6185EC7EAEFF171847D4DFB282A9FD6F2272F757DA2F86ACA5FF8784DFD213DB7F26D167D53772AA5FA1E599D89EF287841E9C854EC2F64D6D1F8838D8D4C4F4CF8CC4CEFECFC8125DFCC7885F595994DA4C7C86D4C8A64882FA9F8862627E4CDCCDF99C5126F76F756255FB67663F545177F35D393D249F22C60
+:804700007E3F74F3434FBF3CFB7129BF2C78424855593F28BA23A6421CF6CBC7FD25DF52FAAD65DF3AF7136557575FA2F62ED843BB2EFD18A4CF24FA4623DF9EF95BA46F62FB3786FD4DFF12F263237F56764DF38AAE8FE8FECCA99FD8F69FADFFDFF28D9DF77F3F6EFB9F422F23F64619DFDCF9E363D77EDFE8F4CE4AE716CF7BF8AD6E68
+:80478000EFC2FA8CA44D866FD8FAADC54F7AFAA7BD9F4DFCE4CCC76647C4C7242FA4F9C6A66FEBD4CEFAEC8D23FE23371F25D6D5F3436A35D373F12B1315F9252C1F91F16D357F96F2BFF57F96E8A2EE82F2252D7F12E23A28A422BDA15F365E5D1F1AFA6BE39F55F7413546F124628F8FF968241ABBA8B6EAFE2D231FD5BBA3F211B1BFB0
+:8048000038F4414D3F127261F12F27FF5474AEDCAAFCADEBFFEFF6BB7EBFBBF1A33F1F36F5A46146B456D119FDA7DB5F32F88D876F64DCEAF26153BF7AF824468FCCFAE4E46F6AF8C525FFBE7CADFC97D96F82FACEEE2D8C2F6C5C88AFA9FC9E2C67EE8DAC5F6DCB377F367572F53D4FFF76F447537FB5F323299D25CFF2F76F3F3FF6F632
+:80488000EBBB5FBFB6EC78AADA5A7221B781FAA2622B266E6B9FCEFEAB2FFF92FAA96BBFD6F315655F52D4C5F62C9CFE4ECFC2FDFCEEEFA6FEE42D7F1AFDB9AFCF32F9F38D1F14F64D6B9F76F6636D5FD4F6E7EC8FEEF8EEADFFDCF6DFADFFFBF289F3FF1BF7D3BE6F2FF4367EEFF3F5D7D5BF7FF6E74F7FEC744EF226E17FB6F8A76CEF84
+:8049000046F8E4E44FEAFE8EEDDF7AFCE7E77FFEFFDBE48FEE7CCEFE8CCAEF2CF8C2DE2F6CFFB4EEEBA4CFBA389B462232410000208452218E24424C0228C024808204944494F02441F02441B024044F822474240800100142108122E44812E14812E148024C82C424484420C841212A1442014880041048314840028B84208432486F83AE
+:80498000C3C12E241116D618846114702901C362218B249029828581A8228082842228422802402802884888484CD811A4820042F0214424C0828124C3E421511829012384B2126142372C43622440822294A48022A4881B442F420A25628420D4224128A8241B6833D941F312498D342F9144F412498B162F91342D2F91F46C922F98B426
+:804A00006CE999F42D9296F92492D6F124D283FD249293DDA4BD59C2DA9F44C21A9F4462289F446A999F447292D849FA92499DB46F89D449FA92498D842F99B428F89249CB922F91B425D992F464921E494F2269914F2269154F2239D84FA239494FA2B94BC29A9F44C21BBF4462AA9F4462999F4472B2D849F2B2481D362F89C4242F8927
+:804A800054682F8964222F8934242F89B624F891FDF0361297846F23B161B424D18DF616129D2DF0416C2F29F9496C9E929D2D2F2DE944F29A929D243FADDD41F212D344AF3D2DF25A5343FA9A4943F312484B8ABD414F2B51186F2B714979B662946F6B7161F8B2125F84F282921FC4F692921F5422F149649AD149B2D2F14924ABD99D86
+:804B00002439DD41F28A414CF29A43448B49A6F49B434BA38B416F4AD91BE4625B182F427A48F1328283F434148F86B4A299246D928B242CF96C242F883BC20000280000000020010000000041000000000000002800000000000084000000000000000000000080024002DF7D8955822D2A1AF412110087821E318441304A1185C82412F3
+:804B80004416044624BA2801E26568156A64C2608C88E022195841221B86A0148A94418C468504C129D12262452B31C0142F44112204124944544246A4444C126282598202E08482518225A41948A9B288D188528226E85232431782430D448418184844137734321427414B528645A22122242D1812461495141648121498A1C44B1A8BA0
+:804C0000125B8449B26801499923194104260823C434809884200A44206C226AE822E42204CA22221184888411C4C48C76160846A82481C110E22C2254128AE48CC91213F4543A38694184024A7211FC1124648F2511F5784845F2141860518C84CB64441EA4182DC823A15687D28E4A4F88A883E0AEF8244136E412EC2398611AE1584484
+:804C800088724802524958628AB412A4231684F41283C9B242242AA142C829A81449052F2AC2194D24484B2A89C12818814E284B188D4CD08A57826A02261C9328250848911289618141682C0140948128224C4232124181145245084501221094384581410841281444200653C424818081D22408408405B042D2240443C224484441421C
+:804D00000020D4860429D428224114A282822425B848F8955E8440B11241412204222522024D4421148022014004E081050046084241800118894434416100480000122A94820041D044A2844488A0442846322423042008224200290122421281828110D8723E2A46558110C444818903C15C71249142948A218A82B822982429982A27AA
+:804D80004140828311111214F124589BA12698C1172245A1121A04271C2082AC28CA2264642A893612822088C8241AC26443A3A1230841444A322442444CD1527844BA6DD828B64C7884E2A8C4428424A64442FC864494458991114115A21440CA221E21C042209921803282412012448A8101842524C41800884E11441F1491144210820B
+:804E0000044228CA21B426A628821A08800CA624A3621AA18221251482C484004146536424CF24C32882465822008824D092272A04243044848922424415D4245485A082800B2229582C1682A1142230410015B444F2A8118B1211AC02626190C18022A82800422C211442044C38244130C4414AA8422624448422228432148289B42198F0
+:804E800048439486CA6184865882494248FC8AD8100A008180028525119888E01121942141501800521290821A02160217848C82AC8290888442A042438128C1C82100882E4420042044418498441A54128A72910819481298281822805A8C422A24422404A02428EC389E5445C2624AC24446211201101462414829A418C0111618210937
+:804F0000428F24432418823184602118800253028B14280081802284C2222781824829B882418372118492114422A084424C0128248044C2142128522C4244924E708402F0CC3118002400182124412A018008001A240285028415042200804201C4142001250484002A04A092A0484123C214222849084A94422140280400414942448894
+:804F80009A24184243A8180028008189C816C3C311612C42C2444836322145C83412A44B81D216921126C42140C882181CD42C6242180086B4416211264868128C41417A4804423038422D6822822E82EB34430A2C92826F1284C8544992551E4422841CC5481486249228806268322B528AA6682C1464248904AF4844A828FF95411886ED
+:8050000004460851411052C1004081081A0512A041B018052128211002811EA4428230A44212844311348420A824126028429841128902F04282C04230C122104418044B12836442844748811A0180120220C22AC32D41024916C14128848084082260684044F11422001394A1854212B11212C2824188800424A0815812428A048A044243
+:8050800052242B684800604228244724C82442100483A882818614081AA28449282222140A2128842469F271E824402206000038822221CD2423684328601A442821002621110842A05488120088272144800843818108250200504244501842280082828E424C840130644E44220020220481002200C9C4F8932B022504502821C02422FA
+:805100002021442A04183A4408D8001A248806904484800714923840824C0400202122044004A28088044448A20021440042822E944120481A122204B048226448814FCB053048101804204412914420210400818A05406411489044412302004143A14222416262200340044C0400280029624410A12C441400A04910028148003C044167
+:8051800041244881C02248248EBCF30242844116410C8314A418C2411004411C1625188201D04814C148149200800890812994142684384400C84218004146022184448324088282481324AC4144260420028A85286282488481482160C228822F4CCE1828686081400840410466048358244423D84814428112612450122522081A212297
+:8052000082480112901230212A8424118484018228908448200800001998146038802408004121810000488518028D44EC3C2D4184608480810100185082682322028C084220850318201244828424868161248800800844200824B022044034242048020022226420A484804214080023140800200400BF5B092672240440428202114161
+:80528000422924012821194568211E2423244141044748814884380049011B4251C04418442A2106222141C200A0884882498CF282224C1212242401809884A08428824221202224142204212B2C8D7993170884C02411261C2412A2122A810A884881658866122032441A02808886018D82004120B224041228184441420024882221483E
+:805300002484401121040022294898562826221884048344C442212884260448008FD38B7118C826E9A41445D1226182803534A22B47BE482B82222E4147121AB6FCE134F852314C92111F21711114342841C6A4964ACF141219F8A3D46F41F334124C7A112491744AB8548AC552412D2270621664484CF24488472829F266224C94C4AAC5
+:80538000A49216E49114A64E4E488E44C443F1D442844A54282F2494424632488FA2A6444EA24B448D524185D48486341484C71426CA6815B4A1A84D43741AF484C81E46476287222F4F0A4E224168C237264562847762234352886A93D44C34316AB122FE424249A3455E84430541C82D5249A2484922048676EAA2884B24C282822E823A
+:80540000441D844F64D222941463BEA4A8488EA4C24B2F486F24CA424B268D48A180C428E7A242AF42FCE783282F22D6826482C7521D128588D44462223D244F21C3248F24D26462284C7181F4419E35B214A7421B1147C78F16CCA93B54C82F26945430882A084F316114A06843A48842F21AA44841F052428ABCC2022742B0A424324116
+:80548000CE421F48E42EC8211B8446A25430C861CF42A22283248AA8A89D2E431208AD482C160226FC8A842F82160D008B14001008118220112808009220C1411226284101430280091084298221820900884418008A02002800A0282048211824111408890888222C08000000244400EF36CE624F24B648524C47445D1EBB218D48C74442
+:80550000142AE926F26296674FCD2445D4E47882F1C325424CB145544147C1CFF2754CDFE7F4424266F242688FC6FC44E46BC247181CC1E55122459191498122E644FA24464F44B44464248E444304ACDA4654544D464F2C36412CDA56F265644B262F42F4444D9F24FC22C8CFC2342C4F82FA2868CF86FE28226E284E28855AAAA5BC6AEA
+:8055800024E286F228CA4EC48F1832216F46A464AD6E4F4357DDFFD1A1138F4434241B834F49F242624F4AD9E4BAA45E645FBAFA31B34F1A81F1447456F16414DFF4F74D5FEF64FC6A424A07AFA6F65CE44F65A39C1D113F39F297672F25E443F311A196D444A5328AF4E4646F65F454542F24B4A2FE6646499484EFE2FC64844FD8FC44D6
+:80560000446F6EFE44C42F66FC24A44F4CFC64B66F61F51F1B2F64F862664F4CFAC86EBE348FC9F1A8686EE82FE252628F82764AFA4E6EAF82D6C854CACF28FC84C29FCA8F7644966CCFC2F5741CCFB1B11FB6487668D435B1376B484D966F2FDA6C7A46F424A2B74A7F6873F3F424344F14F441154F57F4771FAFF174CFF6264647676D17
+:8056800064EBD61AEC44FD94155D566F5FBE75E523F666C51F479D544922A6AC2E125E446F643C46EE44476663D444FA2CC44F429C45CEE44F4CF6E6A46F5AFEE5644B36BE422F74F453AEABE26F46A4C2CEEC8FC7F2FCAAAF22D8A8F2282A87A2A7A2A5B84EE2A2F66A2AAFA2EC4CF8CCF943F64C6CE5FE2A6E8B7195FD1B1D2FA7F5640A
+:80570000684F52F233A74F4BF83414CF4EFD2EAE6F2ADA24F2A5875F73F9A6F24F41F3343617151B375F74F74D5BDFD4F463676F6456226E6AFABEF2B7D47915F5D7E57F59F212462F63F395D1474D5E547AA7CCEAF652424F6575C6A6EE6F6654668E846FAEF86484CF4C7C42F2E2E24EC24F62FA25E51F1CAC762F21F14753EFE8E86EF9
+:80578000F6CCA8AF8EE64EF7E8BCAFAEF6C2CA2FA47448F84A68AF24F4624E2B22EFA4F46664EF6AFEA6C6AF63818442584284801422024B42182A44224222C2124382014A21C212457448021724440042124844482B214825842481240100214904400210E424084E824902200442284220044A84820448218C0410828488D4623ED68657
+:80580000462804111628C628112319044542988428118249840242144C42116282801428A82480611828C01482002008441823280645024B8246844C044A021D244BC212455242430841A843992886885284508200C0684048F12219144F22F148484F22B149D424F149282CF149652CF949248E129FC4A2999F44B292D149B292DD41F2D6
+:8058800092D84CF292D94CF2D3D92AF29A594B223F91B424D892B4A4C9494F2B4BF924B246F1B4B283F4B49293F494929B248E929F44E229F14D249E829F4622F9692423F929242B491F42F292C82E242F996C422F996C423F997524F412494B82AD494B928D494F2A5B984F6A69144F2A39494F2239484D928B242CF948242CF148248E79
+:80590000FF321D346F81A4242D694E3427D187422F1134652799222FD9A4829E4D2EC29E4D4FA2611D3CF1DA254372D8F424C313EDA2F959842E839F44E122F149A616B2493BB29F443AA24CF9B2491D942D684CFB124D882F98A6962F91B264F982292AC9694F22CD694FA2E994D234F9C8214F22B1C9D224B5C9D234B959DA24B849E3D3
+:80598000B8F1492696FA49A4278B9DA44B418DA62F1BD448B292C6242FC964422F8954282F41B624F8A9F700002002410000102208000000400400004810022001000000000000002004811200000000001002000042000000007C3F42A5C1284285C348211429E281C4488341B42481014C022AC1828F48224842942132639125C0288CB7
+:805A00009448C5011D181A82151162C5230160114225B42698922387E1A80240943490442614C484125632152221C244411840D82804A3024842832129942816A4CA441CC82281645884122861D01614C2463C43A82116E5440380029B4C6F21180460745014181C016F22542489A12643C44C482D182B848582840143E46804154A2202C4
+:805A8000482D228642A2522E84A02281478482A04E2CA428499CA44D4882462838848142ADA4241B488EF76317C4218B42269A484F21C4112CC25489045D4243C3521F24E382B118E242F4211243228832496163682944128C324A1C44287113E464E3A4B14133243E446994462D188B184263F48422D82B3C27448B2C8592224157824621
+:805B0000C28222224B8286A43C16B414948A296C444CB442C824C3C42A84AC3228484D48128E124356284CF47B1994218121116184C02821C423011004411815E4880824448E512A229124194414135418435181220048218528810411216021411814210020C12446524429051682122902A8800188484B884A840843C84810A8882296B8
+:805B8000328B0040B141810484224820414204302444008844A413444104420080482144E1441202846088111CB6242988C1284054280029021004418021042D241088C48422002C426824484C0820012074F14A09479245221144392215D845825423842AA211412A8168452BB2F048825CE1288801272526D84214411489D12858C870DF
+:805C0000823128299114001216C8144C084A9482421221708186A2844A53224AA44980140AC1260462CD148E428118214D1A9042812442AAE821D2C43FC8142654143341012652819CE24284448242840149817422048E484552822111166622466A545094881CD18258C146722843528418821CB111B284928441004A181A028E2220426B
+:805C80008431445842424226420C604A85349481238241324280042C842848F4884C1008814C2164841144003116186243282830942892881C994413A8410000008448C024828001108844A811881A7428229414001410A644862212A21800A504B0281424248214420A47841666880012221E621C3D8A28444185145228608421125C44DB
+:805D000028F14D1212450850422C912258418B28D2433A2829150C188594AA430850588CD4243A188724981247226048166218281E688400502129841C15429284A1604270448224348430144618A44230488B4860E141F091DC3412182622E244942100818844E40049828896818F41124811C844F0248181441B214024A4442800221AAB
+:805D8000122452144C024A04186A0442424E1240614486A1834332340087868A01878186240445184238442225C828C08440082648843ECD0021008004422011021002230280A481221A240100808802114180012662310010C222C05485C1882C0290242B1812420021A04300442A04111609400281808A08402222C842F05E483C02186F
+:805E0000502C944AA24448811A7941DC62911810F428228AD421D944B16A7122E141E184B484E54212493142834AE411544C86242261A2363821674889D422622820E69529F6C8C320D488D322A1481928E4237864621749F24248224542E842A8421D458147244425081E482DA4892488E82418B8285846214D87C38611C426214221440E
+:805E800084241004D0D2C4124480424181B848021A9284608244412CC242F02248880045E1640118944CA161454214341222282A4144688141216048204112D88421444826018C8498448D240084406844B028C14870EB0324404A41124112512422571842453241411441114190142229022D24242048091D411200188CC82128E0810120
+:805F00002E88244362244D8825A8489088C72182841908A21004108418241804214400842B488482168848C29440D4E83F1C8C45C84410C448DC140842100222002021E112E8240814469244141904438462AC28902881800482860844121282802242F82482481024021213A8A14B214B8422481024440200218B41440081481841808929
+:805F8000FEAD4120022200414504148100404101206484001922581984188C0422303880142426A1821015A44228292401A012428083A12481880014424840A2442220C842004001422C04824398148A014289374BC4489041240040424441082484C4210046068B4212008E428D814D213054301844208102442C0148444840E422284455
+:806000000490C28322E424285421428024218408004612840442210000182004008F4D82E8819424481442F04821E01446884682022880C31128C60183088C14E224047041022C2814083068007018841208484882128D424880210280812118A41428008842E0880448A04844101414A4C5A041821AD4F13881004008400180280C4651D9
+:80608000814021410200295121A11800842148001A441848C488308140088C4482080084C044100400800880882A81014149514800182129810100008324F273844C84821401C904184609242400000000844E444446210610245488309110410210824122081044028127248002502224602100121225024142482001442005128502238C
+:80610000818104A0983C3F4F104401818002148C08841810912830220012822A08118100178220F22881003220962490444248292204899218982140828C02484A9811230440020050248008004200482044D8280470630A2B225016482291618508A0245311F94418214248D125D881488301848611328811162112821431444904882042
+:80618000342210341480044502412846C44285A414114800298244A22860218A941200422502184CA8842302412144E0413DAC81869424103841A4D1218B2C3BC4B1A9C568188C12D2414112B48AD9A43161AD42CD8BD028549C2E6857111BB315E95594442F86A224AA3A242C3D9442684F429742422F82E8897412042AB2A2B832E562C8
+:80620000F242299A2581F841142B114B4C2C3442888038544B15424964218F25B41664414F4D2485A4555E4E8D429CB5D8F42F7D188B212A521685568C5D2119334189229C6825D1215615BD24111AF321518C7AAAC13B4E82271A26E375F44112CD21C6CC6A8CC8B2C649C81C60858304A4C481AC117A36E28CF864682E888AF44E82CC83
+:80628000F132C487284C38428E832F1BE841B98284A321226966468A2414744218C44242F0844281259A164948A2C11A21E81B3CD14F66F64C4A1F14F448431F14C44A8B44A49D45556B581E6D441552489115F442424CA1444E4CCEA14F116196428FA27841217441C3689CB44803668C61C323F481A41F59E2E4A95266A884524368240D
+:806300002D16AC177A4844C4224B442084E415A4422E4424638C3614C263A848A5246844822D11872418A9A8988B9488881E84C664C2CF9A47022440022428244C82C825C024C024C024184C0280890241100449021A020028B0824221012012429482261402200222002490812810542849223484200100128123112811080044A0821107
+:806380004FA4D4E2528AA55A333FB4F62A21AF717127F741612F66F6681DCFC3F14C616F437325F535155F14F6363E6F62F47253DFC1D2CCD811B29549F44842DFD4F447437B3419F149288F81F54C44AF25F6186C8F88D666F2C2432729F028482E444741214F82FC125EAFEDF5484CC3F2BC92AA29D2A1F4C6962F31FD5353DE944E12D9
+:806400006F23D38C52AA4534844B144F497818FA8888E0293C18A72116D4887D1CB49CAF898FE9F5941CCF896941FFC84B742AD2AEF22C288712177477361F14F77525DFF2F28FC9CFBEF43F3DDFD3F6435337971FD2F37D753F15F57B88EEBCDFBFF74ABEEF18D6537D9279C5FD464CCF61F642672F11EB98BF9BF151444F24F45228CF04
+:8064800084F848A66DD6576F4351848F82751EF6468447488D32CFA3FD5E4AEFE4F2429C96BAAE84D469FD96922F2D348249F112762FC7F4AA6CEF46F554848E442F45F894442FC5388C2C7CD2EAE17456F81CAACFA7D9C6B9F4E989FDCE94CFC9BDD8FBF4F143F56E68AD2485AE24D5FD434C85FA313915F9EDCCBFB4F64F7BFFA17129FC
+:80650000F51A799D295F91F161442F35D722FE72D24F69DBFDD9BBF2DADEAF24FC4D45DF54F54B478F74A6589F88F25D5C4D4CAFA1F6186CAFA896A13F35F616464E448F82F43A586F45F446442B82EFA4FDDAD64E468FA2F4A88AAE88272646F3D4542F25F113534F49FB54322F63E32458644AE54CE46CF894D487C18F8CFC44449AED6C
+:8065800085A45587C52F2C7FD4ECCDA55DAFA9FDD6D88FC5AD55EF9FC326CF22F26468FF12F4214FFFB4F64D29BF56F55967FFB4F4EBC99FFCF21B7D9F95F46712BFD5D25DF719416F87F4536EEFF4FBFE711FF5FFFF699FB2FD974B3FB4F442499F34F666797F96EBBFF778198B418FA4B57AF364CAAF16EA3AFDD38E6B4D4E288FC677C2
+:806600005AF242C2CEE28F6EF7FA926B49EFC4F22E8EEF22F22E622FA4F442D44F2DFD92133F58F9B5542F27B77694622F46B674B884F444944F6DF454CCC74C4DD2272DAF65F156426FA1FD7CD2EBF1CB9D9ECEAF6CF9D818CB358F81326C8304831434411001930413847249821201111A0282489294C04940011440019410A4148008CC
+:806680000042002024010012408444842481148204488004484008200424412400A09482429F298E3C143024101408838678214882248112128804212AD2288402D0A20448288588AB441210344822812A1911344830282146E8282842B2488298242190127082812298241290422A08444800201482D4420898C0824218D0413AA51D361E
+:806700002F81C4262F9144F6124926F2124947222FD9F425822D4D4B92DCF4249225FD249256F5249287444F2279D9F424929B244F22F959244F22F14924472A9F4422FB493423DB49B2B2D441F2B2481DA42F99C4142F99A4122F99F624822FD9B624D8D2F624928E6D4F22C9294F22E91CF22492AB244F22B9C9F224939B2C4D92BF44A3
+:80678000F224129F44F284429F442AF9492423D949B292D449F292498DA62F8954482F8924F2924843F2124C4B827FFE42F1361487142B1283B626B14D92169F44B212F94D2525F24D249AF14D242F2CF14D248B58DD243FA8D545E299DD44D292FD24242F99F584242FB9F414A41E4169DA9AF434A2944BB146F126348F14F4828293F6C9
+:806800003692DB244B8197462F29F96D2423F86D242B89D7C6237561B49AFC29243F81F421242FA9EC42F291C94CF21249AE24A79916F45249AAD892F4B4164679A462844F4B7849F8B6828F86F43492CD284D928F84C212C3E48838EC008081024400000000484088010000000000000000000040040000008004840000000040880100AE
+:8068800000000000484400006FA3816443151218180819048302824C12D114D88842220284C4004542618134141414844412871183014224C01418282C0230282021280188004C848206C044704161662C684448200450884602400C1820E22412C438B356289242457112012494744E8489C63421230625041B52235A424093118945BA13
+:806900002231448141438221F2228424C227824618B1445829881724521502964858426CB48292129044C2A0814447814C246921430181901454182469D112B128E58BF4C21C2421A9844144914AAF91CB483257214E281D183100C31485C22416D241C4498E28A426E115528200311B1146B8136A314E118541E282816261A681C46289BD
+:80698000042926981C8E222C3614B0281848A41820E28128E41468444A89C414814AF944C21B111F265184272C4816112441EA31B148F252A81A32DEC1A430344534222534DD2410180450211487228E448B84302429022504288825548410140AA1411054414064818D1282401811D4210113041502181648D242C48221400420C22440CA
+:806A000004100440142404244140280424214A014230486FFD0C231318425824950100812C3148001211008422A1437248081A845282451442044C024C01430120040028302820328241100400418E410044484400200200290922100688422400287C312583C42484139112C02883D44AC2214F280225B86C581A2B21182A98A288168478
+:806A800098225028A5049028CC942849168834681156DF2855C24283F411222C636924C62288C4222514E86192462326B25262424CA842235424904827C4C06520388447244612944884AC4428887888249454EB82AC43582481151688129128253128636A846012871122A0A2848CC124302AF018462440F2244820628443C24860812996
+:806B0000C14681841CD222012E22898C220821C41022448474121124682224D0848414841205D02201444442844242822141E054369E48288081114B88140C70124872C44892121882242A4886881448428852488444C12604481E24544D5127842084248172940224E024684261B02451422E4222A84A422494444304402A22048243382F
+:806B8000C42C0625484832882068884836F4C9513CE124418494488B110022443024C44018840850582032112222881024518818495418128118189042225048A0144D84212342421432448818100148234AB4488422082902105128800800284200C082001EC4B30F44298212420246082004487818114441CC588180448441210A6D183E
+:806C000000284D1200841094412D242400120000A8C0483AD8C2014716481A124804A58448842108844C0482488A14C8428742444286120218226F9E0241008014113811C012100A4100001200504182160423044400C8250216042082911C296621004A084C0483420410024B4261414A0244288508442008804208211002002021E8F8DC
+:806C800037776C654122830419011C05412944D248A4414C41C184A018004844821443724254868145C824811E82248C011242C012A4521E424463E42802297A2448AC828E12298166444F2483CC4466586843825228A8448C984C20A8488C542823C44244488602121298AD27142410C648272147844183024C2211084782005044844954
+:806D0000C211281931241200001829341417840047411427624698144902A081004C4402184504850422A4430241424481002131248002824014084145022B8828FC295282400800C04C81224048942C8140744441038501269414006088201838451828484421412A08211830A42B844C02822288248A021C01882488288210C444214841
+:806D8000886028002008828C1408822304285FF4064661244287840024201428D124024200402842241104488148248C08260400418440010046D1446884402108180000C1184421388091148A01100461124120841284142442181408829E57934312092440480441490410A2828A010010081508888A81122812C288C44094484C81024A
+:806E0000484220880288002C0840C48241888824144644840C00400420282402442008144244004602FFF2062A011240324422286041440021100A003781008B22A5C8C82182A05200812410C844812285921400C502C1F04824101A9248288C42B841D388021508845088400985088480022842209224B03402121C3FD48A2444CA4221D8
+:806E80002462269244268201480000C04881400822184C04248400C0411200420042185280024261822A0420C84229041002212748211004125C0880024542121206242450244E86C676C109C141C484410085484826448854844400694284449441904480028827812AC4488840425422908260288392264824104652442460A4400446C8
+:806F0000122408420043242804424448251458482011982210881448C8E7C1280020048004188184002400428092120018401802000089118405006548058442542881303988529B414981011EA14A81213114181218804103248100608284002081812881F18B2414244444A0441002238244E28412044110149154B04444314E4280C291
+:806F80001C2A0229042024012141498408412AA843A0428200418240A288222A644A8642820465220423142414A4844B4425028A3846886528D682184258848C3BC418450880426844222054820025082D442541C84225058011121282081848241942420A0029042C2274424442821492C40022C828362845432163C88884428846C218F9
+:807000004224C22B8218B0280183A2843840048128F07EF72CD4DCD8844458A8418942B822C21C833452CC722C1C5EC225D4469426CCF11E5815C56C67426F832CD482E284D28472AA9A4889A4141E2A4642CA4A5447A44F68C8228B5426EA2EF8646E6EC485EC6472218874126A8169B21632518F2192278B2A4F48321829F498544F2431
+:80708000F4484289D48824D488C422835644895A28488D4A169A188B121A948849C1F933DB29D1123512C048422C66844528761CD44A14A2228648041CE48422C614874460831672688CF2122A82DA5C4885784BF414188F4574249444628E481CB444B82134644B84C0C4218CE823CA84144B92DAB284E225BC413D8243A8441EDC169429
+:8071000018C0465C748164442D444C8884C1A48F424AC486228183C8422F2585FD9E16286A14D86EB44644BA46C4224F847466E2235448812F24E4CC414241417E4342344A919F25247818221C6228282664541B8242611221659242226B182721AB914D283958322BC26B8847414F248AB88A6C228E582F28E2C2E942F15611AF21F8827C
+:807180008424212D8445C413448E829EA42B481E4AAC722686FD4A86C24847262D268FE868428FEAF8288BB33D142441100400440024105842101241042341013012842126082250142C01508450942C5814181C42C22D4089410D16091E2419B482028D24F08A2448A141A1101814381481434122D12838148143612460223028E0824767
+:80720000F818131E5C8F857448582C8B242E4ACF84D4A8345847214FC4F44CCC4F8C788C58884D414E418F84E1C5F55D45CF64F17ECCCFCBF8DC888FC4D42CD2A8B8287828B84CF2268887888D1A8B4187E4C57D48F544CCCF74F5434BAF16ED85CA4F7F3CFCC2CDCFCCF99CC99F1DF62188AFD8FA85755B312FE1F41EFAEFCBD1FCF1B517
+:80728000C4EBDA87C98F45F55444E3D4C8F458C11F8DFCDE9AABBD4D68AB233A61612C6869D6E882F11828CF42EBEBFBD2B48F283EB2BF3213B948F4626A816D244AF44A4CCF46F472786FE1E5C4F42C286FC2E28454824D4C5F44F4226F8F25F55C549744AFE5B55AF15C54ADC84F44923AAFA8F882AA4E449FF2F28C8CAF84F416146F83
+:80730000E454AEF7A45F48728FFD55573F23F1F9D8FF5AF84FE59F8CF8CBCA1F5BFBE7F71F1EFE888AFFFAF8D555BE896F6EFCE2C49FD9F11CB44FCDEB8DD988F84E4C4FA545F84B5B9F9CED2CADDD878B6AF724348B995AF9CAB2D8CF41F32A288FE8F8F4F4AABCA4F8A936CCF36C1BEFC1F51644C726E5F24C6AAD6A8FA4F66266C357E0
+:80738000646FC4F226CCEFEC78CE5C6AFD473F64F4473E4F67F55E455F64F157FC6FEBF8C648AF6CD4A6F21A828B8A27828F84F628C337CCED424E4C4F6474487643FAEACDFF24F5564ABF27FDD2E5FF66FCC68EFF28F996A33BCACEBAAF1FF883B4CF69B792F7D3C44F2FFBB6186F71BB9FFF529A67696FADF55A446FA5F4464577D49F3B
+:807400004CFDC4962F4EFAF46EEF22C18AED964F27FCE496CFACF44E1AAFA1F99AD6AFEFFDFAD48FB438F17F735267E7E4EFE4F6464E27C2AFA6F66E68EFE6F47E7C6F61F4464E27A2AFEEFC8ECEE57E46F74545EF62F27E726F65744DF57E7FEFAEFACECEAFA4F46E2EAFA2F2AA82AE22C5FC6F2DFFF9FC4E4EAF84F44E466FA47446F705
+:80748000CE8EEFECF451573E31AFABFFE62E7F5CFE8687AFE979A8FCE7C7AFABFF91136FEBFBD672AF2FFDF4F4EFCFFDBB376FEBF9F6D6EF69F91C1E2F25F54452ED46DFF5F4C5C56F4DFCDEEEEFEAFF66666761EFE9D9EEFCCECE4FC9FC7A5EA1EFABFBDEFCAFADFF9E9ADFFD44088480048440084B425084702408401204201424140407
+:807500006024100883442404100221001082840829092122001800221880080046024230419A8284028024C9484028018249843E83C6029042404882662425040048006014241A4218094AC2186082208208156481C0486C11044B4881128082C8244A5842412188212A488428BC24014929840918212420213492301420012319082019E7
+:80758000C4441CB8AD48F1341283F4341293D424B149C2129F44C212DF4462289FC4A2199F4432929D252B491D242F89C5242F9944F493592AF292494B22AF91B424DA9AF424949CF424B215F934B646F924B687844F6239494F28F949289E929FC6C212DFC662289FC622F94D2C23D94DB292FC25242F89E442F29AC94F42F2DA4943F29D
+:80760000DA4943F21A494B82AD494B928D494F2259984F227948F1249283F4A4928B444D928B242CF968242CF168248ED823C8366F91C4364F91C6261E4D26E6916422DCF42C922D414F22F992494F22DCD2F4259A46F12493A7554F22395A4D91BB2D2E82BB842E929B34AE129F24622B837422D169BBB294292F8B14F812692CDAD294E0
+:80768000982F18D628F11261C9D812B6685912CBC22D252EC82F8CE232B94AE282B88BE2A2952B4DCABF44DAA4B8497384FA492647A99F447284D869F286489D226F8BD468F884684E2627C926F68268C7228CF62882EFA40800002100000000004200000081140000201212A4180000000000100200000081181100200100204118020075
+:80770000800400221004005C219D4141261248022C024843446282471280618210214208841D182F8152488D41C02410055120024B16920012128460921C84C114B04211D44221024429614836544229928424414C14084141004DA8C724E9642200C04A8CC4423084CFE20D8885012508C042149450281AD482B41442B214810125E62186
+:80778000A42945A4C2284425C14220486488CC985189783C8282514B34811CD18286D1668214C66821412942D651B34204456821131451241126224272454408CEC83D142004842C6844304A242012D17239AE1954482D21265A824126324213645425382A2F14A2144AE381921816712152482C19BC15E2A4D34872C441614588258408CA
+:80780000118376B8F43244A88122163814184E2851594294148C744432464F2112D661D585C41686B4251432242748233A2256344621814C744842344847848D42288E42414D2830486820E8CD0F0000000010884104C12441002C0142228908A44022424144D94418280118142741142194218C7212A24423819212001C0222008F21412C
+:807880005421104104105944A088111EA45042842140E28454221042D4B233E64A214114428204002D44224849082C1182012001122411459A2918150428C0148485044E124818128821205121C01244118240542128882308408112440444A4282287440022811601105882422042081D624421691112641121812B1441824F1149F11AC9
+:807900004243D81838344CA1126F429218ACD8842218C2142538214C02818146E4235581257C214445429442602248BEC81E488C9C1249C4124D812141416B24899A244E4849B1C24C2244B842724518A484444A0A5F440628A38C348284864AAA2469F43C95332851241200213042414964431A38982C183284002A8182311484504884DB
+:8079800089034C82024C157C1658282F4214544112882428212A94982C815814901486511422C8844928544988C60450284652842A14180448CC4411022F881488147228922E43F2565C486941522449511246086021827041D542048F2113E141616218C1A48A1A12D35271220151848480C3410093A114101226848119638446B84681CE
+:807A00006824642444642CA228A0425823C242414841D322829C44882E2411221A34A84082189848C0481E4353490114296325241800802444028189DA4249621880824411D24212022004248C0418C04829B48284C34118800443227844022448490A404162434014328289449A5C902841688C6888450820A8284284848008882FE44C9B
+:807A800066421A012280021684044B22DC4284210420541850122810A88818481244228248104145480422615D22C08442425188430483C4824D552855044A8404424282421821421524010084623068412048141872283CC848244A023041293448102A4108884004444C024314840110141204481244250444000089811848022991489F
+:807B000018F044A941242A010023682211284C110260480084142712C02812C41622881C12C8424A08FFCB81A21425E12481159231292184941A4F8486524D80B284899484434212D41161224486C4124C046820394C0045344864E091314428A5E24448F412814914F2C444855428AAC351604225B4528214F56292450AA35444295248F3
+:807B80001528D5A142082A4284F58A448E48A4D06804A0E2D35E614138002D4446441804224022981884451202A04246048126120280440690461901112D484A08249641044268836441F0822140D4244814042A384200484230488246024C6288191814E88194880086C48490882B4889F8F4A35024A42604288C0190148C210818830425
+:807C0000200824203214184512484242618844118021044E424425022142230423D11201144371442102114A04284084084480C4881820028E410084009042C728812825021C3AA540081092442A046082444148400418221800104802868158480086024C42843824101104881169088A84E821844843042186424282082C08298892825E
+:807C80000040942264209422330C2748842486440240B81E0420140141100444192122B82442820821450288588110220128112144850428424200009012904838000000212681480220082B4830429048214048247468028188002190424140C4B5430F40581221128429942240182418A192302420084D12C0121885C4221842511322C4
+:807D0000018A011200B0140412A0414D21C04141222488448601008064144304002185A1848664441420080046C4442200B04832221F23CA82418126042800004460149842268102C2658221080028411E2481C0112088186411004229440285082147442004A21460144120582122410020145844481008A12004420083082400DDA5F281
+:807D800089210200808142A44A221C9228244D1249C212228C01224B288C61481818438228628A6021221AA28252428848881E84481AC8141221704482B44282C4261002492884082C0864982024824208855141A348B288B48802830C8421B0A80200000000878200008001491108120086810800840044441400228008130100268141EA
+:807E00006118441111A22848000080820200008002110015080042488148C03DC3D22801451148D412019302008194AC022301004A11C4280043022240424428850142402224E1442104200423442402412180122448130229A44229644424488084243622853388906822888044C4488982F231474002142122702464A44C012002114408
+:807E800042301A10015084002361187018012100800182002284432114012400C0244AC444811021A24800113081476400356488214B4848A084214C644221412122C098735684AB28245559225AA22342E9F231D8C0E4179A5A7384342226B46218A4156B288F431358288B822AAA1283D251788855444147424326945524514CE441D196
+:807F00002694488D8229A21A252291426DC14F187224663829522423282A3CC24F286C284F2262245E46852C5454F043483762348F24C48A29F684C6A97428E8245884842792A5F897EF8469C428451282F215481054C62E384F42D288D434B2C2A3131D861AE1A139122961498E161E179634181B112A58898B228D181A3114AAB114A813
+:807F8000352E82C84EC42BC11BC49E111AF954715B141CFD41424F4C3221291256311C4422645835324243C4624A4496818521AC446E64C332A6871A8AD28C94C1D048147E42BA48D482E28294224D9CE3BB1241DA91425444218CE1B26682444F884181529825D244E92192241062428CC488442741276125D447562219D29138C21AB1BF
+:8080000081A6A1424A4432122412466A844D124F3494144573917461344129BA64F6A445C224A82A988523C4A129C444A167248E142AD8283C2C8F14F44A4819B883D4A828A6886F4C28D8427442829624DBFE00404804128400928482200882200882430210C82400C084C0844004001041140111402158142318A41814822018044011F9
+:8080800044814201148814A8800A10010014002002263166C485F82E252652623F31922817542AE28CFDA8841F16E498F8A2C22F6ADB31F1A4A4CAFD878C4AF494B1AFA8FA96961F18F884982642D2CCF88684DFD2B38CE86CEC41F185C5F0C1814F68FCC4C57F5DFC95813F11E618EC95E51898C23B894BD84F58F915114F69F987826FB2
+:8081000038EA14DC64D844F8868417145F5CD833F487864F5442F751C38E848E81CEE54F68F241A1BD8567489CFC82CA2E226FCC7482D4A618F148482287844CF21A71AC518C85567537226D1773E23354A54D588B344F12FCC1889FA8F26A464F15F883BCCB4D4E17DF21E4657AB1DAEEF99A173F21B8823A922FD1F11C875FB8F89B1CE3
+:808180004D546F44F884215B767EF11F4BF8C6445F74BFB5C4564B879B59FF45FEA6564F2DAC485E262F73FDD4B66F2F52E2FB425F4C74CFF486A67F2AFCC2C22F38FCC3E76F68BCA7F4475DDF3CD427B517FCC1CDFFE674A6FBA486418FA8F88AA8AF6AF8EC8A8E8F6B8C972CAF84E2A2548B4FF236C3455EA2EFC2D2B952663F71D18899
+:80820000F64B4B27A26E5CCF82F2EDE98F86F279596F62F681932FA2E2245576CEC24F62F2A8A84FC8F98983CFE8EB43AB311D13E5F6A9AACFC1F154544B235F5BAE891F1FFE82823BCC6F78EE68F892C69F29FCD3C86F5AFAA1611F41D877F565741F5ADA65F4212157B22F1E74C253446F4AEA26FAC4C63DC22F18F862A235F648529DB3
+:808280004D2CF4C1644DA4BFB472A1758EDEB9F8C1CAAE224FCC4EF4828CCAF44A482F22A4642F62F239E6ECD1AEF22A26C7D295D636B317F2786F9F24B22CFFFC34CFD3F66DE99F9AFFF9364F17F333F6EF49FFF61E7F21FDD2376F83F11C8C8FD9F11B9CEF6BF2A6166FD1F21EAF7FDAF32E1D1F21FCC4944F5BB171ED1DFAA1C22F3C45
+:80830000E464F9B7557F21FFC6D9AF7CFDCAF77F3BFD53577F79FCD7636F77F445A76F2AFA8324FF22FE65CA2D846F78BAA6F4C2C57F5CF4C4E21F28F6A2436FF4FC574AEBD46F5CFE446FDFEEF426A9DFE6FC4E49BFBCFCCBEAAF66F8CE8EEFACF8CCC2AF2CF4482A2FA6F4632A6FD223C21240020080022880021A02448002002B21203E
+:808380002122210226091418222082010042008001001582022890220000004800400800224078480242908860244002F0CBEC8C58241424100416628450441294604400214124004514082444242284004110A4440025A2444018C225257244014225724401101204F082820049B2C20429149442498254248D414180588125829484002A
+:808400008D2824425453F341342F81C4246F9164442F91A4122F9134252F99B424F982494B928E4D4F2269984F22691C4F2239C84F22F949244DD29B242E929F44C2139F44E228F449A443F949A463F949A46B491D242F89C4242F9964442F9924F2924943F692494B862F99F424928E4D4F2269984F22691C4F2239484F2239494D929FE5
+:8084800044E222FD49242CF5492486F249A4B29F44BAB2D449BAB2D441FA92484CF29248542F8924F2924843F212684B82BFD9C5413E36814D161F169414DD214F21F141652D929D611E825D241E82D7545E929B268D9259F2419A5D244E89412F25BC24F2114B437A917B34E495B4A25192472A4E484F2B51114B1A9374A6B46934B2D9C2
+:80850000B692F149642B888D642F21D948F212929B244AF84C24ABC189F2534A45E4B924629D4B22279DA6F4D24943F312496B3A25F9843646F8A43242AEB287844B92626F22F94C282CE94482F1682C2F183649000000800100000000840000000088800100000000104A02000000004840081400000089081840020000000040044001DA
+:80858000DF8305144A92184012B1215182490122474413A22123C8241CC22421884008C829C412501848004004152464121800508A28C4448829E8140882148E22112CC484140021444450142B448654414446A842459842860289048181A508816D56A3C3554B1A6433D42801858282416824178183598416D441321221888D2225CCE555
+:808600003243D5845112260561D42A48D1B46115AF469121B9416A64A3C152482B94342945B2441368642118221E44428CD282C2463B42435FA5893442814D282226A814861AB42A0885C3484889413241C6C1144E2782EF724AC4512AD2144742C62824D08C8146F55814178A4F41655AC42B2315352290621B188D14984A14D1832158A2
+:80868000621B8440B314D4117414442893792C4124F148CA122536584D4648442F2C24C8881366158C4444E3344674A251844E424187386E8276C94448254C668425314A4A12684421A44644F863828C36991B1441851292181415A221184002814082022188A9D28448242254A4214B125014812211844C7122B841521224618129440252
+:808700001302249A92881420012D254829E2A2480452A444405484302418478828A608828582941884871486911844419F560F8004001100200441126021200100001A011B41100214188CC4148400002004811008200130210021100200000014444004002C022084082400848084323648848504400825E851541A202362A1411244292F
+:808780000183654D18412012942100008022B112046245588218218440E16442C24254492191225042820047114684042242288448E08284C6498C24C8822881481A18021AC662F0D1EB4048344840085052148082A11290142504C0481624094128484511020084008B4100622442100850614AD122448411243122502400D04484042016
+:8088000062142608C0482A0485A88424422289041280321823863E3C48002840114488D58204160485820518291108421218121C012818501212423604160250488C224142480C28001126810424A11C08901100800860414241209241260288A02860682120044277DB40285124124088145148445018414212214144215A528400230804
+:808880002E1820041054441526420884415081211C024481A01811232432146301C0582009B0240144009180921A116044444A840448128C2244D4D832B41D284C426344608424811246618800884014024224805242489942080011000052118C24468834416024421129042CA8812008888616042C160446122814024814200420184220
+:80890000480285120888A082DFC887218404441001A0244831605424002002001C066021104405304119021288004002A0118911220481260400001200604186012A015042848280084A0100128824224022C2DE53CE5987412D412D144194A146914847148612C8451B841264212242244922D241429229504840443141109436421181D4
+:808980004648C84184302129D51424446831290986C416A018E081E421C414493842185224D048C4883068924248D0843452807828028460882F5D012A024142200481122E4D001014420444290584B0420C162AA2411041449124111884824243022532411E12830481298822B8448201884421418822C02415280241250111241400964D
+:808A00000680449248126886E242823626000024108802002100201121410280A24200002141448021010080014088210180211808200110A428000049014100854448044E24842002009242214008AFD20A8C249248141881842411460818891142112411B414257224C21829C11122124091484084542416892102001813542211167430
+:808A800011782111022F4101541800800463E688044100114841828800918724128602308800489C39EE201208401868C221002418244014892121621226C25A18110029118404180011001200206121185361912184242041214109209446404C142401102A0843086084180060880081421F83013048682AF22324474145041142818437
+:808B0000A0414AF4514887C185591717558002281A288161811F61512225C6441E1284182280A2222E3C57644505002213081AB454E484548C855D11130A20A2184AA8888AA9111FE1D162546280225498282428AAF222B44D444506002C3C4B41008100814001003813410224000000420000000000001800301100148008000012122492
+:808B8000000028100559024004000084001008004882DF560E00206212C31214050000184A2134588191111100008A084B18301221212840440848222243121404008800424283141818318100008282921223111202400480242232244141005C35D30020A462400480048414004A04850814120000858428830124008004421A5481280D
+:808C00008416C411800100119248401851310018108282082A41420220820442428428504800006FE306304846210241000020012004811002002012220A12442141001800003A04418180048420012304A1100100002008121004000000A042100400C0DEE307008110010000004002804134121800281021022200002004001100402299
+:808C80000100418021180200004008220000100110044800000000886F4C0E89048D21284C424454820018001A85C648849414140012C0A4889884188542420400815239828242440400001C8184C448CC48091400008849C8948CC112854282082001808282424404008C3C9D1002808342440400401402483E4245C81814140000808C81
+:808D0000082B11243400002181812859C3544400222019042B424884C41414210041808C8C814142028004858208283844250420F2459E60841400200100000000212001002800229044001001488004001400C0181830811224100200004800001004004004004210122801219088C021A2000011304200400118001800001002400410E9
+:808D800004200200008400002118001200008002200100220000001302800481408808800400F0EDBB448D428354118111A4464281041508141682024C4106002022C221498404C4000060418F247518321848841AC1121289812B08141D821229820100004002114C16414C2102A0444281888005A42490488A823EE3106884207418012A
+:808E00001100A0111B2140E221E1238181311200A042255484260400281144800481428501151118818141014B114D122078120200822031284428460481001182224149F442488482000000828F690242C048194101008100441A9112122400802111220122224CD284025400284A0420D4113418194122C5114840A881821829024486F4
+:808E80004622811402224C120449024400411840C8428C14C818200400862251914AE414D48814781199192F117111F21292212D128A68281AA119272229F2242227424F4212D44402442AA2224F4492448F447444F8494885D1991451914AE414D48895881F98D819F1129117212D92212D128AE828A891122F22B112F2242227424F421F
+:808F000012D44402442AA2224F4492448F447444F8494885D1991441A8444AF4884889E889B888B19269212F2119B28A4C11A84413F4584889549B1F81F111112D13864222A18823A813126D122B232F22D26442440410A42622CF42B244F645448D4C8415494111A84413F448488BC8BD891F81F1111125434222A18823A89B1AF81612FD
+:808F80002B322F22D26442440410A42622CF42B244F645448D4C841559111481CA24F458488BC8AF88E88189D12241C2DD5200000000000000000000000000000000000000000000000000000000000000000000000000000000E03B01000000000000000000000000000000000000000000000000000000000000000000000000000000D1
+:8090000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000065
+:8090800000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000097
+:8091000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B83301000000000000000000000000000000000000000000000000000000000000000000000000000019
+:809180000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B010000000000000000000000000000000000000000000000000000000000000000000000000000B4
+:809200000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B13000000000000000000000000000000000000000000000000000000000000000000000000000063
+:809280000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE13000000000000000000000000000000000000000000000000000000000000000000000000000095
+:809300000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B833010000000000000000000000000000000000000000000000000000000000000000000000000017
+:80938000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000B2
+:80940000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B130000000000000000000000000000000000000000000000000000000000000000000000000061
+:80948000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE130000000000000000000000000000000000000000000000000000000000000000000000000093
+:80950000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000015
+:8095800000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B01000000000000000000000000000000000000000000000000000000000000000000000000B0
+:8096000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B130000000000000000000000000000000000000000000000000000000000000000000000005F
+:8096800000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000091
+:8097000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B83301000000000000000000000000000000000000000000000000000000000000000000000013
+:809780000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B010000000000000000000000000000000000000000000000000000000000000000000000AE
+:809800000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000005D
+:809880000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000008F
+:809900000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B833010000000000000000000000000000000000000000000000000000000000000000000011
+:80998000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000AC
+:809A0000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B13000000000000000000000000000000000000000000000000000000000000000000005B
+:809A8000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE13000000000000000000000000000000000000000000000000000000000000000000008D
+:809B0000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B833010000000000000000000000000000000000000000000000000000000000000000000F
+:809B800000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B01000000000000000000000000000000000000000000000000000000000000000000AA
+:809C000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000059
+:809C800000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE130000000000000000000000000000000000000000000000000000000000000000008B
+:809D000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000D
+:809D80000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B010000000000000000000000000000000000000000000000000000000000000000A8
+:809E00000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B13000000000000000000000000000000000000000000000000000000000000000057
+:809E80000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE13000000000000000000000000000000000000000000000000000000000000000089
+:809F00000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B83301000000000000000000000000000000000000000000000000000000000000000B
+:809F8000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000A6
+:80A00000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B130000000000000000000000000000000000000000000000000000000000000055
+:80A08000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000000000000000000000000BE130000000000000000000000000000000000000000000000000000000000000087
+:80A10000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B0100000000000000000000000000000000000000000000000000000000000000000000000000000000B8330100000000000000000000000000000000000000000000000000000000000009
+:80A1800000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B01000000000000000000000000000000000000000000000000000000000000A4
+:80A2000000000000000000000000B833A111222222000000A024280042008024044800000000000022002002002822802224240400000048482028080000A08800002222000000FFB805181A010000002AA26628280000004800A04400000000002A020000008002002A020000004AA444488A0C00000000888A082A02000000C056238768
+:80A28000822301000080A2226A8484A44400000000484200000000002A8282A22200000080842602000080A44442888A08000000008882282A02000000F0E352001A01280000A0226A04A04400000000A04400000000002A02A02200000000A022800400004A24048A0800000000A088A022000000007C31CAA0311228220000282A24A410
+:80A300004200420000420000000000008022820220020020028004484200004842A0848288000000008A28882282020000005FC50A2AA31228000000284880024800004A04004200000000002800800200A022004A248604000080048084A88800000082888800282A020000E092345B1A812181020000282248424A8404008024044842EE
+:80A3800000000000008022A2222800002822802202480000802404888800000080A8888882282800000080F26F33183AA111222800008022A64280A44400004A0480040000000000222880A22200002A02A0242084040000484242888A2808000080A8888A08282A22020000C047C30C321222000000A0442A24024200802404000000006B
+:80A400000000A022280022008022022004420000000042428282000080088282002222000080B2E78521210122000020024A8424240400A044004A040000000000A02228222200002A02A0220042000020042028080000008A2828082222000000E0F23BEA1AA3111A02220000A04220044A2404004842004200000000002820022A220226
+:80A48000002822802482044200002004A0888A080000008AA88882A0222A02000000BFE6053812280000002A8226A424800400A04400000000000000282222800200A022004880040000A04448808488080000208828088082020000E08232781A812181020000288024A4444800004842800400000000008022A222280000282280028039
+:80A500000400004800888800000080A888888228280000008052B2183A8121820200002A22A44280A44400004A0480040000000000222880A22200002A02A02420840400004A0442888A2808000080A8888880A222220000003C1E2121010000002880A44622000080240400420000000000282A0200008022020022000000480042422036
+:80A58000080000888282000022000080F224BDA0323A01000000222A0400420000800448000000000080020022000080024A2604000000424280280800000080A888802202000000EC322218181200000000484248420000800448000000000000282228220000800228000000000000888A2808000080882808282A22020000F059A31831
+:80A600001A822222020000226A02004248008004004200000000002200208202002800482A2424040000424A04828288000088802808202282020080025C3C8D2C01433224B0148282E2444214184832488112224811281CA4219C0484141442100219E1924112D4244152244100284C62242842890283344121912904829412821441215D
+:80A68000432181188249E222840181266122101C046044C0143FA9CE244E242D482146188541062B214E641AD69454544815519827241B42AD4CD098942416F71812112F22A112631286612490126A321A6E241D2960864D24141425A48243B42CF9444587285D189428421D492D48C84CFA49181B84EF11591A9E2215E648949241F09126
+:80A70000881EE24C721A267346384443860226A6A21AB244F42815124305604491221824001283445281C018422B421128933411384418212243542400503862C4421502428100271224496884104485142A166224008A22114504652138848E143011805486261244881208902288414D182F590E402806204124F212240041814D4180CE
+:80A780001202A5044C06834412F1211120428221B41141A21128401851444414C02400883661882334180042849C48741831C8273112182684042182844A08841C0423240420C2144822DC313B1014020028B0240441225304811484800440487111180821160200002002495224220028410090448304104108004813048948789201007F
+:80A8000020818882A312122602444122002880F4FE5A242E22442844100480841608200414148014084002000000242840C212412002280048684422810011145011890C000082C0121002D02221184204442240044420042EB8F30B0000000000000000000000000000000000000000000000000044000000000000000000000000000071
+:80A88000E06F01A4288911018185024116E42268441800811CA44110C24C488C84C44124004840084414100484205428244245C4248A820185440123018C84488808B012C41821342A22040088A05240321848122C04482CCA43C358944444218562111481212E44403118C4161221810284121147311962418933414782618087945211E2
+:80A900002CC4234D182684C11C42469819482528F4815A4354412C8228A214C2B0123441CD12C6011C8242B848488118849C4C422D4188284004898238281E8848CF1A415144A18F32410A171181814D242849F841184C911825081CA14284294195585D41184E28154328026812245651344601837124282175488274186464884D13629D
+:80A980001695282D81905248868858128978122138121F2441C8834A92811004CB84B0410C2A119A441A02422A7588C2B63317084400841042A241101204408121040042248912248544542442304800C0264100850483541240286688430441A01200425842452804282608262804A04880C422120000812318086AF8C3DBA011141880FA
+:80AA0000114122024821502226011002004800A0442840448102438284C24844C08440C24112100218000011504400002012010014002EA41C4404410040C248888508C46C328423829212256824001092129189210100124522514A274128874148126413110841498164445118142E18818C4181011F82914C4CC25C264138218012012E
+:80AA80002CC4244849129844C1405918254104141222484658488346741502212448C228CBF82428141602211200214800122302208101212B61A0412041618110C43440044A039D34901890118041A42458C541C8218002111004428448451441013400806318424844104842028D8848608847B293872341321842149022901235381884
+:80AB0000241001242504851404C4206464220015044E244215044284308C10E214C129A141A02100400144466242C02480420884150815041912846244C48162441D14C04221814890744C021061124009003113422204231484049152144C04002342741202811245021148C1843223128C024054218C443C411321C414143041E0426476
+:80AB8000A184840023240188484810C128212149C21410EA860200AC3F17C01883C42400440000128942840410E19108444C421102861482410114242001112E482128344200C42018C2128024086018814C6128201984088D5140080088844184D0120200108412F8978780122252880028244C04462884082012042288230460118260F2
+:80AC000014424122488024A22264484118423904144220362430424508504410140880A1140048C11091142442428004114800402488358226E4216286400984282417441C84A42441214C1244A1211A642428536421824446522525C1281443041B61282E49246783245C91432A04D154A8242C643530884951414E84844D282C51288353
+:80AC8000684118211D4884811CC844182CC4488C5228410089A4428C4294A484EF7881088541140814414082825188290800482048641841001522824404184002004D248B44C048214141488014726C2D41040000411A1C84018304424442100246210861482470140200001532B128002400100221284800240014250800262204004203
+:80AD000090246041004141846144102242B18102114618014784009024C144101408818921142804830100484212481200848094844F1F4DE224240115114418420217814A110111180021188A0411242E431002804D38844888418681A228818230885744237848084A03CB24803148144118488411808112041084D4149444400814C40C
+:80AD8000420020440483C132D32308200225088400C420020042004004261434444381021088020042872100464C14042220A45200420062009028004024041141214502841D14901400260800118048F12C18004008902100C86024C08420C22400601440410128911A0292821D22428200260400140046854101141048724106C044140C
+:80AE0000001901185089C02410A14111812121111686512613452214027E3FF32242024502800220122248042C224294220044004AC1114042051883C5441812122823210112211420E54102284A2A16441C84022842406812812094142021841204100441004862008441AF67060081544400004C020000002400444440028400221744CB
+:80AE800000141006228244102C16164888040000008C040042004260821E4180048444004142420012814488AC37FF29841101A415384A1D48212B144018C3121186C12198811421208928522114289828861281280C40B14642528200C22908008001004C011440240111221215282402004008400800114200288FF40588501210A84178
+:80AF0000002002225400C06580044411000000800422200411812014081C43044285080090244024422822424845544811481841442585420420044C04001034414C3A7F824811842824442CA2424052211D2228116840081440521254437828F411A8A012602200801ED41488EC1188C281446022C591341440014829548140015C344101
+:80AF8000128331114A288401151249C814241901108C9211642092941877D3A0D41215782C4ADC217248081C9122CB1211448219024D42A6021421413E231AF422288501628E218F912138444CC9768E14D41846D64551481952611CF9261C95F8481813A444152C1476429424488539284157858B121CA15285C948C56142157958C81474
+:80B0000045D23401111E4847424B41195482248CB4D1E2EB38A366622824244554A387242D6A23B242FF48422F84DA16C2342B221E214B261185228814D4277844855C411A43A42A4B6C4FCCB625A24119E848C42CBEA846B2C80817A8111F13E692AC565D112226953844D3B12232214D244B42421C1211D119D1CC95554E41415E56152C
+:80B08000D46452858D2945827141A4414123A551144A54441449F4D6532426621485531199012219942264142D21255113218219321789654445932151C67715F63328BD2180A1282CA4818A24C42315D2E5BAA461A445BA84A4C66FE80449A7428F92A42842D0481434118C91244F54D488846141C9469811C3E24482A45419344516D865
+:80B100004814E4C4143C4A903242A9C294C9D9443D64221800000080018B848009988009D8C098001241210014184818C012412C01184100181001190111800118800118400126010026011220011601121002210080F244D7181E421CF1112551181AD2B8D619F241813F1CF131977BA89E322F21B993EA59FB95717B959AE865F9171BC5
+:80B180009FF1B8AC7DB29412D761ED211B828E899F98F8AD157F467994F585444F14FBB41BAF31F8E1345A7884DB3BFA83713B251F82B414F32954CDB45F487514D4A4D172D147A2324F83E18493655F54F1142DDF1333318F51F154684F167221B641E1D1F6252117C38F21F1121627141E188F81B348A1412D38B3E7E4F22E588B1D9E90
+:80B20000C153B13297421F11F12929B5FA1F1F2F82F461453F32D631F6DBB157557F12F1A3833F3ADE11F1357DEEC63FB8A8586F79F11F1DFFC8F885874F7AFABCBC4FE1D111A928AF2CFFC8E45F71F484845F5CE844F4B7B6D7981F1EFE2666CFC8D8FFF2A3C33F34D488F458582E484FC7F4B4C44F46F61454E761FFF3F234345FD1B1E8
+:80B280005C74787168F85D1DCFC3A333CF49FD1C548FC6FF21616F24A415DFF7F73569CD18AF61F116421285F82A7665F654168FA3F74246CFC2F2D8D84F4DFD22C2382F23F5121897819382F1142AAF3294292CFDD23CCF77B347A28386B243C325DF517EE59253CE462F61F882123A79B4D4E6F3BD1EE7131BA3AEE93F9AFDB1D11BDED5
+:80B300009E811F4CFCE4951F3BF3338B1FCEFDF485DFB8F88FE18E713B25BF92B519F2214D5F81FA91591361C48F71F22F355F437221AC252E5156C1391F53F33531DF5FF154695F17F62D217F16C1795F93F2241CCD16A5F753454F84D4E8F52A162B554FA57778F848662F86B5D8F3B47F43B672F752529F91D1BA52B3BFF1F12A687F34
+:80B38000B4F422222F25F7FEF4FFFFFC27312F31F1A3A31F1BFA65355F57F78A835AFC43123F38B833F3B1F55F39F93ABDEFE3F3A1218AF8F9E3CF49FBF3E1DAF9D1D16F2DFF97B7BFB9F9FBF3EF2DFF919DBFFAF8E1E13F3DF73B7B9F97F72169DFD4F5A9D19F16A611ED1A7FF2F22525CF13F36C781F86F2511117149F13F33D3C9FD3B1
+:80B40000FF1D5D9FDEF6656D5F76F64515BF56F62D61C781CD1C7D535F54F45C5C8FC4D744E445F57A79EFA4B464F64C5C4F4BFB944C4821842100848094822E412918C4824712888008884002114C22840228A02842826048841041440110A2428284A042608200302420120818104834484481444244834404000040088488411A3D2346
+:80B480008A2211485128214228200127880080128442221424382442181284003014A0418822205348121184A041811E4542148344012514C12141A04285C441001F410244221148114881704102874440044A018024F23641144F2331484F2331494D129B242CF149242CF1496496F24924929F4432929D242B491D242F89C4242F9D44D3
+:80B50000F4924926F4924943F212494F42F842494B929CF4249246F9249646F1249283F4249693D424B949C2929F44C6129F4466289F4426F9492523D949B292D441F292484CF2D249442F99A4222F9934242F91B424DA92B424E994F4249246F9249217144F2239484F2239486D928B242D928F44D222F148648E9B93DF41F112484CF3B9
+:80B5800016694CD242F421142F9134252F81A4962D254B928CB424CD494FA229F424D383B82435C94D128B2CF048A4988B348AE42422D848B2A234481CD441CA481F44CA684CFA124D2AE88834642FD1B26478823964945F22CD484FA269944F3219F824D293F4249293E422F949A42E928F44E13AD469E22A54492B4A9D242F18D441F278
+:80B6000082484CF282684E262FC954683B69C5B212B664F8AE6D000000100400000000100811000000822001210000000022000000000042100800000020182801210000000000490110C1A8F3818212944A202404E044032A682215C42C20412482212A01282448524A4249048122C44681E482044411942004B04A41A4242A1401430149
+:80B680004088C4444818108812014442225816042624042C2408101884B884F4EB89809842264404A42448004502808102454204452401614A584400412A240262424004284146921400482634582E2846641110A8221CC484688284442004434568C62291841B2C488954884628029012144826E88414D1A831882821412E424143944A91
+:80B7000021C074448221116E18701844D4412261421244482338C4181E241D28216084004846946849624215140C482252AB522E444A314142B01C1631858B6842490448E088051E2844146036388D44849028E0221412144128D4189C843ED7808264428100800440A2225044204202102409212604A044803424A022461814010042297F
+:80B78000110148100C8D2460922082040084444A0190241C8452884146282824E184342442008A0160C6C048AC3DF828320080140118008200220042412810828882814208101804A0842628A441182341028100281002104C48022C84420843022619288202111481144220048110282124288604CDFD841270280480012A88034C82D3C9
+:80B8000082712422A11222225022499318484C64421243E4247244042260821240E88214C1449410D1980184412A02834213042326028A3252811904244A8422840260828C84014A024A04811B61881D8844AD64130A22002094110022C0A428282C81228204218002682A15644420122802288398282043810114144081422882922885AF
+:80B880005481209222004A12141101622828140013C2488004844028012A8C08C1BE718CA2118426040028188A014022B11C02A021902464A41A21084922112834464504802401428F84241132468181818341042100645022424A0283B81212C8284608290442142608C0481820242224945811481332C82D81538502688C61818C140A42
+:80B900004418100118C301204401228905204404384185228412040018418D22421082020028001A04008E41000084A3860C188110022781884A816284A982021628140880F464624C0141212241290200602242004A8202611C0200221688BA180287114C1202492482044A142222B21484D8884404214888813243943448111B42601216
+:80B9800010941220081A8446A2624820D4240420B422816844483842C05DD347080042808101814904002041042152001400C0421126020081221110084810889212481858895112AC081E28200120C482128844183200800120021002818440028180F2E9AA28412C824138548F84122211A4214D412120011E2470448222212225424844
+:80BA0000E421062C828244E442B428C241C048237124B2484148E28A62414A81C1482E8281837214A821B0418E04344CC1882D58611A22819448281AE4A28422F8446280169812814A14121888C69A71891124440825C41400844200901C281002421048218194289029455148000020040046C444859442102224113192C0248C61810015
+:80BA80002A2408202204002800124212D0824442089608486A01149F9C89022002420000501883020000007021A411008448818082041189648240A81110084904C14822902811180082A02221A68891222908C1880081281148508224840000481048C8BCE32A0480044384128402284824000049942442002A042A04000040028091283B
+:80BB00001001544001262118052182223D48397181088189E12214111889869348130410088912C821142924140848001AA4424F398A840120112411042001182A9218004304424C4128A124202404002304842A14088093484008C10081821887182008818B918542122162243C051008C28470446221000000244A422201C81D5CE30E0A
+:80BB8000480000C044800429016022282612440224426442242846A224181242842714800421008400480000218111482223021481C0811008212C52121C68114041B11814228562214A21022082082F658D880242408484020083C428121800224681A3441E244608404408000081004008002881114180021C022002420010022110A2A5
+:80BC00002428C0180080011964210000210000BC379200000018120000103222291184421212548222299822293222004122002481160A1724442800814648480818268821E18241881188412292284140218401002A9428120021122800482904F065A4004400002024140447248C1104472400442440121404002A240100211800210060
+:80BC80001100100118A3881101135A1124B8112A5888A0841004002048328850921484422508153A412508848C35B480024244584C2282A2424A12183812D02402282822482C6281274482A3242204522242222D282C041820124864C2488C0420011A12A2614828281220040081811200009011114200284A0184904214888FD70B800269
+:80BD00002082314448440041100442128564244902002200822001212242008014223424108402428110C841200483011501488302407281022351813D41897169024A01424820221406488234F38F2408424584A42249A22228221B5416C2181A91124941B466D644E613B122B24893844AA2462222A044C02119E2A2B4482562811364AE
+:80BD8000424044614484837C281418F92811AE223127882283D82268A24672C8F86222A48B442227842914187825C158409B481C14A24248131691528562148CD41E87862212A444481A2181A4444E4883D28AE2A1912628244D24426116A2144F61F34C42214652866AA446186B216AD48A52822E1285429822932554C140D88824A486BB
+:80BE0000818F29F32181818CF22121621B22C09A26F2A82222AC85D2B891296E41821499C4E33F32F1214A2CD711341223E481416284212C0415E898385FA0142A860147414AE447044D1448CD242D2843D222D264E226A2241127264F64F24C4A242E642F22D88872420A202214F84248230487812971123248D56C82978649F42121840B
+:80BE80001123E1A8A1211F15A1918F15F191121E328F83D311B128F4114385F8818545C4221E823417998AD18834188FA6B111D5811172687852E28441F2426846C2688AAD2C5F1401100444200140044421440018004100180000400200422800205181441110011182112B18228A21E22821E22821A21870888162184434001008812B03
+:80BF000021112311088112811008815088C3B644A44647424F44F444844B255AA4554E442E4447C44F26E463D3E2D16251624F4254444F42D262F67676E596146F2CEE24F4464C2F24F412226F64A4544AE48452222D228B442542F842435F54545515A8629D4515F1A1484F5A52F41F1B78A179B253332F3B7CA3235BAA2FB9F8CA899F64
+:80BF80009CDE9BF2CCCCE5E714B4435C13BF98F889899D48BF38DF93D299741159BBA5F24A1284B55A3A8544F8C8888798FFF28CB64464444F42F6644449B434A4744F45A4244F44D4ECF6423E2F23F11E762F27F2243ECF45F44445CF24F246753FE7E364F45AC62BEAEEA6EFAAF662422F6F7446B212C2619F369243AFA67552522A8DE0
+:80C00000423F51746518D81D7269F94D488BA41F44FA2D84FF98F9B1819F31FB43833FBBFBCB811BB11DAAAFA8FB9B698F84F448699FD4FCCD8BAB481F26F6B3C286DB9B7889F94BCBBFBD53B9BF35D1BB54AB2D52A3F3484EE7B42724C3D488BCC8ECD83AFD4A726424D24482E44524A5556A36245F96F6634D21E5EA63E541F1143C4FF6
+:80C08000447646F744644F46F64C6C4B556F2CFC4262CDAC2F24A4764F4444028B24AF24F42A228B15AF21F11A1A3F25F444254554C81F96E294A4222EC89B22BF887933FA21893F33F781831FB3F121812F33F18ABAAFA3F268688F84B689FA4D4DAF24FC6B4A3B563F14F4898B9F98F849499FB9FF49299F95F459413FB4D4A2D422771B
+:80C100005A72427E42A84489E48484F448A8282E2449E6463464CAA7756E745AE646E214F22D7BFFA5F3322EAF627372F22476CF43E6A6F623366F11F7727E8B568F65BEE2ECECF6AE4A2BE46E444B5429C2699F96F64968AFA67552D22AF1185BAFD1545C5598688F52F448699F86F2C8218732AFB1FBBB219F397333F133F1B73B3F2B49
+:80C18000F3122AAFB3BBB8FCC8499F86FEE94CCFE4F4CE432F26FE61C2C6D992F8894B9FB4FDFB7A9FB2F55B181F94F44342AF24F5521A2FA4F44742AD4446C8484E489BB4232804424142000028810012800229024448124820022E4800A0422022444802420020048304000011210010020021001002000046422904460242602440023C
+:80C20000F0AB79A02240240C481222A04220121208003042228426C4422280020020048140A8110083145488800426884188B1218201181382A1228904AD4826448852226094C041288374121228914100120048008E8ED3DC41F312484CF316494CF112492AF1124943F212494B922D494F22C9494F2249F9249246F1249287444F22396B
+:80C28000594D929B242CF949242CF14924A6F24924929F4472B2D149B2B2D441F2B2488D346F9944F49249222F9934642F99B424F892494B929E69CF22F992294F22E91DF224928B2D4F2239D94FA2B9D9F22492BF45C2129F4462A89F447AB4F84934278B9D362F1BD461F3B2484CF392484CF19248222F89B624F112684B925F32427183
+:80C30000343648472393E623B149F214129F44E221D15DA219D74423F86D24DA912D8B4C99F2935819E29844E4996C422F9134A496F934A49C9496844BB215D9246B144BA287844F2139612E9293D424F969242C7949C492D7461E929FC6D4227969D42AFD29241DD82E242F91CD24AF91ED42D2B221EA9C3434AF11F4A6B4AD499A5B88BB
+:80C380006BAB17946F217A48B8147968F83692CF84D224F8682C1E1287C69E32B30D82002800000000004840081400000088004002008400481004000000008004000000008008000000000000000014F08D9D4422200312806442A04A302928824428412843A46C41440020A1428004001A8291280040C8112800242041A814A0122244D8
+:80C400008033481222890448114A0413A434902883A128811A0424528022A114288C6146F31E28088504818724A02448222164218C01184140048489712C2231285283820242222400901810198414081A34888B488C15125882882B291324078E281639428421841648D8821888C8114DC2944F2108A42280448184885438F0C922842A00
+:80C480008881921C448189064922E8A61291842D58D08441C4442A8434257014188688E184072E42A0243012268842089C02452405E0A58869841A54881E4A2A68A16E45143AB21868831D4A488582945818C662288186B811B6869819630A29823342461421A44C843B228D4D834C04280060242086044082023024008604818428188B02
+:80C500002122000000200112008114830200814824002898802444A82100104118C849423260814088C14800002A0118A014FEB8C02442410084121306C3020041000020128842022460241082220481C0480025D2110481A026128982688280228812028822810090190000001A32411220C14888004890681284CC354B490422442112B9
+:80C5800020A14218874422212C121824A112482C61454722876415343880022042082C0285018C43098448146014497858311142A88584082A49C44829028E588E1828412E4228134668848C129888C944098260846088308889041F930C4243524480011422CCA24128D04252824400224A13C22421275221106222008C06840095884237
+:80C600001251811190214A54418AB211329142A62828882201A62842286818899144281C440889E1121468811C118814088110C818E2D08833AD44422240028C218506C10000808101B04C01CC048C03421022023022004289414882C448001A12984840084302262218C44824209518226022800242812286C84400888842804C084608D5
+:80C68000AF3806122984A48200C914C84281A4000080014A4204008440041226344812412800004122002200812A4404009044201108804A2828282221B2482611082014AC442042880400C091D2418C33128C82442401430242000090122126818402420020A514242442483140C4118082022482002A24088AA2849088886012001BC10B
+:80C700008905282C3848588602292816821884048229428444882184048EA82480024482290222208141A44216482832244C0118001C18382222000000482002235588000081872584840018282012042A082022813141000080050000488100240049C4C46306B01262844124832116D4820516C2244840D84221A114281E2420C48923A8
+:80C78000222224C422C41014A32449022CD1844208218881588726834A684A88182E884CC84428288219C1181A084E1289028E228CA4818B422B149044414282230446C848238114046FCF076F21934880042890288004811884A022244C820400008144128084B14204001412420080124408004220042881811608C828422A7288014AA6
+:80C800000480220420C848800481414141004AC44BD31E84B414048321820444100E44800200000020042818830481161812082C044002C028B0180481800A608181892204224A822149C8B1460848A08440A468001142A220140C224A8A84F88D37244C121848042183124802446041A14B21A0415084F014284008121608228100890491
+:80C880008901200687822C8452448021082B4424004012C84882248420140884408241088849058C01464808224508001E5A53243212B0480183011812183212200183C124282CA24126884434142112AC0448C04A122A84021829222284042022021881B2838402008C2382118822022220826A838A220226C88526042001484E24524912
+:80C900002428F22AC684422800224268482A04E44A422204400400284820C24800E02124826422002052880022704404C02882844244504417118D4450448A0400814824248848884288238488084830228058812D1825D4A231DC400884608510086332248100400824218180D44812128834128100228481830421008420140A608828B6
+:80C980001A021232892208208D2825018881A0C11C1888C814894894A826A438D80000CA811914DC1F0F4584A1148452248341844462242016942280C41400182041420248243200901210C242B042314183019048814882812830888002868804811128422E11402801212820A24490288442228A422842089EC5E221180000421280417B
+:80CA000088522828288002200400814800291108124240C2484281004008488004422400242004248141902A00251898422A440844840000220040042C84F418BA28C890424C24082820B224047602830112800212CF84014A3212812180820228A043842C3141842220C128218C041842123A02002A8282010000421008008924196C4405
+:80CA80009322080048004488C03BB34E08448042E262210400608568438124412A64121A028CC244128018829518462201368201200468614422204148423258801459C1811489018004801892182117212638110024622C21880264901816C44AFFA343F864E84E444AA1814AE5818684A2144F44E444E6A3B42624051A924428221AB29F
+:80CB000028C34483725E92322F25C4522784222B511AB76247D2AAC41325486882425228F0144883A43C8B123A64263668828C015F82E248398816BC18C8482D581B2487128FA1C4C2822E888D58EAB88DB224381859B4188F264188B222F858963E142F45F8A64AA347E8E9D1287148E8C1D18AA65187834F417262F21822CC044F8282A4
+:80CB80007228082E4229D58814F848688F42B12A2224D4887128E886D488845688A04184422B6427225601CF2486B22C0483A8CC87242F2BC14812452A32631E286AB298A4451982A2224062AB2CE28CA8B147C84B628B484F16BAA4A6882C4B18A248482A0A2D84AB158FEFC726258413E4C40425322A72443E22CD1A29F3581A6D346B2F
+:80CC0000112A61634469E5423154124E548C71189218219022261868A1AF86A6132B255A924A83F428588552A8AB4483A21287811EA283D48887B29C4231AD4A54842B45C72A188B218B8487884E4860948D3A2B4419E281C146879843F48238624E884E484843C25C8CF4CCC8818FE433B800008001004004002100000040240200002293
+:80CC800018402202106812810028811008811A522812C582522428452A413211A411A41184118419411851823022182302611082018941F49828C42E1A6D4AEF8425E525B14AF6683887472AA1416AE187B73CF31C1CEFC3B11CA3432D366FC7F15C145FC5751CF414566F257112D22AF54A48A724A582A2632F267552E2A1613533D12206
+:80CD0000F222519B1146D62AA2428384B598E3ABFE728A8D28AD8667E96D877F58F643A66F6AF44E923F59F447233FB3FAAAABAF9AFA211337A12DA2AE691F46F9852D4F76FBB623BF2278C3FA2C98AD88ADCEE7C84DC82F88F22AE8C76EE5D4C4D58E3DABAB22A761AFE4B458A7516FE163868FC3A3132F23F134168F41F3581A8F83F180
+:80CD80005C7CC7C18F837742F2357FCFC1F53475CFC1F114346B761E128FACFD4A58AD92AD22AFA6B278F2782A2F25F33A32AF25F513532B44AD621F91A751AD4E87A24E4446E88DED8FF9EA42AFABF1381A2FAE4EF8A5CD57323F3EFCC8884F58F9515325F2E9A89F8EFA69E12FA5D5B3F9C1C9BF1AF2BCA5FF4BF6BDB48F5EF6CBC2AF89
+:80CE0000CEF6C8EA8FABFBCEAEE5F6CC868FA6F6FAEE4F49FD1454C5F818E9D022F4744ACFC7F57C188F21F14672AF87E747F134544B755E146E788FA3F51A3ECB351AF338424E767F83E745F334787E244F63B114F11248AFADF55848AF21966A2F84F458688FA6F31A62AFA5F15A133FA5F44A21BB568F87F14842CD222B428784588BD7
+:80CE8000B1BEAAAFABF9BA2A8BA4AF8FF228859F3A92E53B4E8F8CE1F9B445F672688F82FA896B3F8E65A52F11FEE1E83F5EFFFCE88F4FFBFDA99FAEBEC1F8A2F8872E8CFCA84AADC8CF2CE282FB388665F444544F8439B42B64AF45F75A38CFC5F51818AFE3F54248CF87F574746F67F7761ECF61F3383AAD1AEFE3A7334FC7F36666EF62
+:80CF000057F37848DFC3B138F11C34EFE7F75A52AFA4DDAA71CAF24A2A8FA6B278B37AF71A3AAFA3F35A5A1F35F56A6ABD691E581AF5484AAFA6F46C688784DED8BEA8AFACF8B2B2AF87F5B4FE65FEE5A13F46E43AF8FEBEDF4CBD5AF571732FA6F6E8A9AF26F65959AFACF4E8E88F3EF6BDAC8B6FCF5BFFEE47FBCE4F2AF2D8F82BFBAF35
+:80CF8000AC7C48F8C8CC2B22EFAFFC94DC4B5D4B157B7A84294218C24812842022E182142202260822242220B2482162246024304830482842904823811482148224C1482148802481140200000042208412084220C424424C82C4240048800448C04880C44543634C618981841182818681961421CB14800118800449311822448C011868
+:80D0000021902880B3220484892112088901422842844AC8288B161A1488224281B4188218888182048C3448869228AA84E1882464884286880342008AB2487182CC914FC946F1361283F4241293D424B149E221F149242CF1492486F24D24929F4432929D242B491D242F89C4242F99C4242F99B424F292494B222F91B424DA92B424C99E
+:80D08000494F234BF926B246F924B287844F2239494D929F84C2929FC6E221F1692C8E129FC4E229F1692C2F29D14DF292525F42F2925A4F42F29ADB47422FB925F29A4B4B22AF91B424D89AB424D998F4349285F926B287146F233B496F2339486F21B948D222F9482C2F21F168249E59F3DC61F33248446F91C6242FD1E442F112492215
+:80D100002FD1A4822D4D4B929CF424D2DCE4A269D54F327848F5249297442E9297442E929F44EA22F94914AE129764829F44235B692B4B8D242F9B54492B694CF2924D87422F19B62CF11269CB822F19B42CF99269CB422FD9F624182FDDF22411AF55D284F8DA2445B1DAC2992F45EA92E844E1B8F1482696FB483496C936BE498F64E30F
+:80D180009AD468D384D668EBC1F428869E48CD122986F9F122000020021200000000421008110000008200000000000000410000000042000000000000002100100800000000C0596329941281240026180212447018048C4208006E1862008884A02100848002002880925142A016005668868AB448A243800212221822A08182B8806415
+:80D200004444441248A024A842122C020032B068C848F0469CB0284804801108442692284E38206624400246220260284222A042214E480042382848AD18842509211002AB221429C8282B8112E088888184088B88101808201228328862822A04811241C04880248124011B81DC38A54824456822701408302425A8428CC128F048228185
+:80D28000A148333278488823A42881824AA14181218002288D421224267131022460E2F01942A22E82C24A21BC283818B08132988200828A222824C5846B24884A028C829144122662829054A0148E4884885FDC41A81200008C42021844E0422421040000280000A02221608420840340285288A044802681028C84F14828122200580030
+:80D300002884309820211238248118004A840A0020042812281842AC3D6C38160800008001802204004112584240044448000000200222801448081A04848034490000280049B4188238882A210800002848288C044508304848004A081820D2CC0849C214845885C218C285A824AD12424A8321C214008288C58C024B87A0223022508265
+:80D38000222A810420C128002084942846E88822C8AC84A6EC88B8242118240A8C94244885084A412C422846B824912848812AB14886018883058301CA9858AC39614C8262412045220912268A818486024141200410B44493842A8402101208A024200184840020A42489289A41CC189884268418A48242367844880A89888411084608B0
+:80D400004E28228B2489942C84481628E488048E182011A8437EAD181881508800878430482C84820112208189815C4C890200801202A02218002082220481425608813048812A2258888A22014400868832580028412062428C0100582022041248808C081C335200800240344228200482488C450242225890484A0182828001260213D9
+:80D48000020080013842203C4A200100C0448112884846080081834898184A838222622600124220D8820248881C0220F45E24002A16241304434284024120222184032081280110820C121223188241828221D2880487822A01280085A84468824B84424A032A8411818128858384A2488412444A01AD64818744C041482012840246145B
+:80D5000011C8E29244480018424008422800808242028800180080820242462801441200200484812420042281288100002840080000215082800C8820042022041A0815188122F8148944284C021243014821413024800136622248188252928B15240062002183A6111722412A21028B45228961842CA244A148122AB6887424285C84E4
+:80D580001A01CA24021A09C088288D1A40CA442A29E44424A244124681422A9454A8288744908858A304484200482284226842A0824881E082012200800488A012A0480000181008811281C0843048844200002826488831488442B0188204488B242220922886181804484A086048440028428F790D124112421222A0412004000020C4F3
+:80D600001880524400004888880084233818988820A11286688820AC62828482522884408888082220028B220080082AA22112812281623289C548400800D018322F00228420C11400006A819412984B428829014210828181A1480010020028221A8404484848224618280122891102002B21008918C21800A084890280344A1881588479
+:80D680000000410026288DF8B4AAA02152284448288082114484C12442800442008288008A022004A0280080420884A08480088446688220420224422E3284AE12224682049E4841C88004248EA8218825A8C420829C841243E4410868C8E38D02208102800420066218224822282820048004C08280838204282C84240120C2220022242B
+:80D7000000184968844B1A263CA4480010C888608428008911288C8144022002A02148802404B06B82880112480010A44412481288800A814A022664422A84842204202124840842222A082880084A0888008024A241892128211108422820A111492401802102188418228C840D8901604889099DA4D32624944C480018222A21A21222E5
+:80D78000224212008488000028800680012C12280800284E188318480952488828A28D120048004820024048248C18A8128800304862002243820236880441F0F43628800281006A0400000010061210028001004200204808481008002008828548021384820221002221846A042A4808A04184002A8882082008000000E0BB3DC6482246
+:80D800000046240512408401C084802802482820062004C042682268222A24042280240426840200400882188301208584046A2804120083A624C0486A81A412004230144A028004184F8E0F809418200241200146041A02A2428283229141008022012328F2121210220498508A3E18212002650448200443248562842A548C1001804196
+:80D880001864828242121221000021421024A2184314C44448CC34D4328A84724888A411202632141242282F480A2AA8244A01482841124AA1432880A28680E28EC2182A842A9838428C2208867298F482288F84B422A2C262232A1C08C6B448E18422648487818B438E8C8608A2A86A84BD2AA2D485A8F489A69481CA74888C6A84428A26
+:80D90000E414A523DF8E024E342E48C152484A63435A25B644A615581E741AA28225C8324283858AB424882122612C4E5242288886688848781A36988CF33AC85E4A833C21AA648EC286C818956485566A43AFAB6E215E82836228282C2C6A818C36141E488384B82881B518B82A6386A99388282A93444AA51552169C1882DEAE33AB340E
+:80D980004AA1531AF24414284812186A81F224742A84A4994D24AA8CA2A32E224F4434224248CA226624882CF642326A44A26E29A2488F2162874888F0CCC862224218C6A834AFC9A225362CC32C3AA24326E28B966A2AE484B274B114E68424F1684889A1268E42833342B246A2624E4849B114614883E248E444728474C8D81A04104668
+:80DA00008808124812444084419492908290122221100218000028A028812C029E22841E22848642682822864268282628483C82263C82B08201A308A388120A8110881A2811C822812881288904811291102851DC535F266D326F64A6554F442105441E444F45D444564416F444466F6A58662F28E824F6B28A27246F665264242A22A1F5
+:80DA80002225A2664E426AA64C89F6CAE22D622F283C1287A15E222728C25D432E222F25D18854AA2F2AFC91D9EFEBF9688A6F6AF8969E6F28C9862FAEF9A2C22F3E7868FA8A8A8AAAED2E388F81B148F888C88F8CFA18488F28F89292AF2CBA92FD98BA8F88F888E88F89FC88888F99FDA8A88F88FC88888F81F44CADAFFEC1366F62F100
+:80DB000042766F847578F454144B252AF554644F46F544342E444F45F544546F6C7352F4A4288B462F3739A326D445344629A61768EE422922F742422AE4ACB6E82CEC22F432BA2E18A3F26242AF2ED4DABC8FF282D267A9AF88BCC8EABCF34B3CCF83F48AB22F8FF1183483F3C6F33B49281F84D6AABA8AF8B884BAFFF8188F81F458282D
+:80DB80008D68ADF88F8893FA9ED88F2BEF8DBACAFEC8888F4AFCA85C8F45F9CCA88BCACF8C9458CFC4FA9C12D3AB664AF74C685E784F45E141A4777AA7414F41957447423AF546544F6A5F448E8823E63F297464742614A2665AD72258222AE724E426A66E68CA8EB6B2EE21F438482F83E28CF68A42975C2B6ADAF58A4A8F8CBC28F25120
+:80DC000079AFA1F59E5C8F23ED83F324382F4FE736B9283468AF88DCA8F422322FABFB6CBC8F85F5481885E824F218288BBE9ED88B332F89FD583ACEA88D689EE8CFC8F891DC8F96E68CFCCC8CDE888F81FE79554CA7577E7C8B578F41B594B154E242A5654F46B764E746B654F774564F4C7BB2B6A6FEA8621AFFB3622F56E666766482B8
+:80DC8000A6533E622F26B442A2662B462BC2CEE88F8EFEC8222F26ADBF2F86F178428F27BCCAF84889DF2CE26C7FF2F888484EAA2FB8BFDBF778E6CF87F2B29EEF49E3219E743FABFCA2296EC28F8EF64A622F27FEFA7CCF8BF558488F84B268EE8AFDE87A8BF38FADF33AF28F8FB37A6E8E8BD6DE5CCBD54F8CF778C4C6BC4CE184FBB906
+:80DD00009BB32F243248200480828122842284022880820400488004002220024842224222422004008304A0214200280048280048C0481248A04280042AA4142200001820044282424F510A001220011262186280A291800848A045224243820120C24280048482A012A0188D48884210282826C848C0281884001A2142886284002E24FC
+:80DD80001A01811008878432841A81848244041842200449E6F134351D242F81D448F21649442F91A4162F91B424F112494B822F91B424F992494F227982F9249227154F22B9CAF22492B3DD24B9D9C2929F44C2129F44622A9F442AFB49A4278B9D362B4B9DB62F8BD468F392498D962F99F428822F99F62C822F99F62C922F98F62C92DF
+:80DE00002FD8F42C922FD8F22492275D4F2239DA4FA239DB4FA2B949C29A9F44E2A2F14924A6FA49A496F849B4278B9D262F8BD461F2B2484E342F8944F492482AF192484B122F81B624F9B5B8146F42F148482F6231214722DB644F21F169241E129F44E228F149248AF949245AF849248BD995F481C81F42E299CD241ED92227B84B2ACA
+:80DE80002F9DB434F212496BBA1CB4A452984BAB46B9946B844B9317964B1BCF84B684F1612C9AF8694D1AF8282C1E82D7C42F25F86D24AF21DD4DF213DA1D24ADD34CF21AC3F018414B2AAF19B434F21A416B1AAD494F2B53986F287348F1A6228B444F2B3128472AC3F49412874696F268249E5EE30B820000440000000048004001007F
+:80DF0000000000400200000000C0240000000048004001000080080024000000800140044001EF3105112528028082A522A022000022288242800E41D222008088084888008A0242880024A046D08824A888101808124242209468121008818185048840A84248408201200180028DF59243628D484A9144184840B441694883F448A468BE
+:80DF800044C144201184810448A0421242424812228002002200892842628220C14428428A82810238811842E084022A24210283B644211602982883243288828138CAA2438581FA8C384CC2D82D28384C041AA472414997214318B8CC2234248D8843641416842A34444262A84A810524CA81022888284828A8406C282CB24442883858F3
+:80E00000422A9448A28C81C411624848890587826818188648AC46A8272480A8452E482CC2288844182AA66884118F9239A611208404002022084822004422008001980000A048004282000000002230480086840881122200811820220440982800430190280000926081001828885F324528022C81040020B121948200428002459442AF
+:80E080004142418144200228200A00820000400212428826887828AC18800110840146880280912400008F8484314812800822000028B024C23EF313829128428728A0414AA3241881222B218829020012A021898B262882942200418B1696482A048B4AD081048C84C168819618A82451128C62C181A078488B2420C248278ECC84528450
+:80E100008449C6C81AB284C124A88119A4241842274889A181E0144828F11A652489012E422481184AA2244A2211022BC2100210D44684C6249A2402481002288A648224890888423048842021C3188A42E842D8810887834181284B41582284E0A4628445A4234588C4488E481ACD689884144AA2240020214161C218AC3E2E224028810A
+:80E180000C8021113148A81220022820011881848849222202284183A18180048C02112044C2488C048688C42849011818800C8142282688880484C024205248492102202881C4868488802C8272690B844512A4424092140000482024820188100842A0988826A8421289028A0120820800AA849434004A02849A08202432288A24F21C7E
+:80E200004840080086283158220081886E1126240630A4484C084C8824C1ADC30E242228446043622822A283A28288400842A024181818008249C1128612C4420082C02881804208304882818904A024890482402106830430A88C084CC188701882318810042168281624180448A018BD2C002084118804004200281280020041285084D0
+:80E2800040A441000000481842008120818802448084011004280000608244A042228084024D441028040080015800414E9C430F214A024C052E42622880922848382281224282490448498128A1121A44328A414A2801425826184888688148A2662838248C242488448C82AA284246384881004B82223A944C838834388443C4281B52C2
+:80E30000422468444C818C8811B444A1147F830244816184001A01202688A2884200124028A211228420D8449248002200200A8200481024810481988112220081281843828452885088108802004B818964483024800818004A24088E454387C5181212480040088800220020862884080042C2B04802818C3848802229820888841A0862
+:80E380008928022880A94900281A04800884203488282E148AA2848838412A0422820018004C0840F428E440426644218904E181281AF148284002128125644816080041472410088400211810A844004A0110982CA01400124E2220284102804202482068830000890418C0184991844088B141028418428E85837E140800002041144890
+:80E4000004448941042008800188800E00008100488021241208224280240A2E1828A012188128128C21442829021842004C02A08480811108836841830889211208CF5B4741446286463422A12442704428242525044122489044452865218321212321014A81011002181848002820048304421058824123012B4818290421B0120423AE
+:80E480002168831849D82401651244024D1270620286022724289C3F852062812302842124848901008182800212008184818210682800822128844388028C844408162882028180278204481842816082812246048100A01400204805124400004CC84438579D60A61324028B12480080011008004800160858881880A442844A8494A2CA
+:80E500008041A8844A0428982608008021588820212804848242002608200488244A9A5249088088283124B02408880082CC3F59411840044642E8441282028C0228204282134408401454280000AC01000000000040048420048A1448028C88418202422140342248444D8800444A892144648C006081005042BFD34B880889C48628003D
+:80E580009042800448182002202C24618442C6A8224E284A022304424A22250443098492806284802833280000A083284216086222424181432102446A98528800822021061A01C084122C1B0A28418128C04483820440E481C814C048888C015C7128041002841A18A818C012892828F31824241881A02918162404421E4422403C188976
+:80E6000084E884124821054800A08441492143220244442C04241684226268488220F9B5278CF42C8A274387C1CF641CB42894288489A2842887868F282226992820A44C8C48E84428E42C6884878446F84848428D988D888B9C4A42BC48A81148388B888C92382E2C222E18842A34781E328B85821AA5D24AE485B458A223224229984436
+:80E680008F4D2392A42AFA1424C84F4B014AC97C42F044244328A18A2124AE842CC34ED3A251B285A21481AD422CB44842822331481287C512412CA8919AF1144C5A0156788CE425A8227E28248612A81429A2228B149AA9441885A84C8CA1918D188C084AAE9681AE48CE248D28C5A2822B328B8380F448488F8482325426D4A8A43C41E4
+:80E700004E88DE2847238AE5490886A4898E1A1A741E2489A318411E448AF22ED64415F14C724F2612925AA464AF25D4C4D588345C433154124D2826A2E24F4254841E24C97418F81442AF81B23824A9E1328D5242CA051E128B6649B3A6A43C46E8812188A4444AA6A48F4191385826E828A5118532188E8289D1225D282CCB6846E284B5
+:80E78000C1421E2470842E36D44AF486661674167192FC1614A638124E482B1187886F8CE8847492F4943E630F1800002002430243024722124502200900008222000088002382190480088901812881284128C522488242224902A44002450A228826883924982984D18284D88284518688258858C2D082F2A9454C7224DD4D94444FE422
+:80E80000FC4C5E2F8156A8AF62B626E784F244584F47FFFC242DB667E8EF4228D8447184D4C4722CD44CE541B514A5296A65818D88878889E185FA68988F29F1328C2B122B525AE181B918F1181428424B64989E3CC78D8B254781EFA4D8EAF11EBA23D92272A27A1ABA137442DAA2764A92521E522F417464F4844CCD4CCDE44D9665F670
+:80E8800046C22FFCDCC1F946246FA2754AC88925D1A2FC4E484E1A2DA23D5173FB3565EFC5F57E646F44F64E4CCFC5B168722AF644244FC5E746E646F4D4F44F24F7F2E2A7A2CF8AEE42DDD5FD5C4CCFD3F31C1C4F45F14CCC8BF51AED85F36838AFACF84A4A9AF93878AFA8A9338EF21E621AA5449AAA11C7C18B348FC486A6FD4F49AC03
+:80E90000622E146E56EFE9FD18188F8BE922F933B387848F17F2686A2D228D2842CF85FD725A4F4487FAAA6ACFC9FB1464DAF544842F2DF99FC18F6DF4E86AAFA1F34A42DF6DD5A8F8CA4EAF24BC5CA48AAD6A283E219F63F67E44EFE6F4445A4FA5E4A4D22AF462544F86F5587C5E948FABF464BA878D8F62B88AFA2414574CCF81F23879
+:80E980005CCF41F514D44BD59E38BE781E688B858F8CB442E989BF78AF198F83F946B46B1A1AB158BD78F99818CB2183B448C2D88F8DF3984CCF85F6781E8F8EF94A1CCBB18F29A932378A8F81F2384A85F8226887464D5E6F8DB114F674A44FC8D64EF43CA44F47FD44C44F21EC59F85B844FE1B6FCE122B45AFD449A8BC14EC6AF44E4CE
+:80EA0000CCFB3CA133F83161EFE5F75E6E6FE4F44EC4AFE5752A922E4FC4E487A5464B754BDD2F46F5BAF8C7C26FAEEA4BF95CD58FC5F47978CFC5F554144F45ED25BF38F758388F86F68ACA8FA4A4DD8F87A79F2F27F7D4D64F67A6558F81F5D8D81AF1181C8B32CF82A6228F8FAFBB4FC7F638186BD6CFE9791AE28BB9E2EB33FB4A5A7C
+:80EA80009F83716AE824F64A6A46F45E5E6E5C6E648AFAE86E4FCDEB4DAA192F68FD96945FFDA8592F4BFB5E5E4E5CDE442F19F9CE4ACEC84BD5EFFBF947378428104218C24821261882048C84410800201434484181800124304810A821811289248104200180042A2421028400180020044220C424424400421624644160480048120004
+:80EB00001984083C35EAA0414664888004001A1688828122024128984418524123C4988B2418282024094842A20089211828018C1688B448088B1248981222C2002A018428108801806A884C02889A048A8481440498822031246F5D45F1341293F4341293F414129B242CF149241E92DF446228DF44E229F14D242729DD242BD91D242F43
+:80EB800089CC242F994CF492C92AF2924943F212494B822D494B929CF4A4B2946F2269146F2B3B484F2A7949F884929F84E229F9492C8E129F46E228F8692C9E829F467292F229242F29FD21242FA9CC242FB94DF49ADB2AF2924B4B22AF91B424DA92F4A4B48D494F2B4BF9B6B246F9369287846F6A7948F896928F84F282928FC6F292B4
+:80EC0000128FC6F2821E6386F112494CF316694CD3D2E442D192A4122FD924F2824D2AF1924D2AFD824D4F82619D4F3278C8D124B9C9D224B1C9E222F949842CF949348E129F646A239F4428DB69BA34D461F9B2484CF812698DA42D458F42F99241C9F812614AF8826D8B922F5886F5826D4F82F9D2214D11AF1CB22431D345B8D3F2240B
+:80EC8000883B842E989D14AE521F647AA4FA4994B29DB6BAD468E113D468BA14D628EB49F46882688D921AF66C829FA80A880020024112000000200481121145020000000021000000000041000000004200100100000000100200000000110010C154638322011602A42001238108001220028A8202800180A214840011A042004008812B
+:80ED00004882E084282494A248480090140020C858200289254444482401402484420452180000122AF86E25E0241808811800290842C0828008816024848800822A08800282852862128418A05428204C28A1222100808A82211228022289A12200890118844282103428122E14001E2460482089241911C15393AD242309360223016CE9
+:80ED80002148820882A01C8481481B828100882882821283811818C1224284126085228BC248C981D22806488E22488A065A42383C9021819AE282058412C25256884824C12A18281A848231247A18949480414121F232B90081100881001842002100280021228220012022240228812811800400800888480000200200000000228C01DF
+:80EE00001014480400450444002001884218E0D832CB280040040018202228368222126048A02820082126024084040080AA480085A248814800008722008200418A028014080000000044402402001220810100226F6904832422440281402834A8214A0122200A00816A8284880890221084044826A424E81A8606896C8150884EE284A3
+:80EE8000188CA5482E482A0112141AA8448B82228E481E448D48222C52484483143C4C80288224011A04008E2278001ED4E32B228204418400169888800C22A09200808A8628C4828200304420044AA2482AA4246082C28B414220E4220C2E1848484E28800192488448818CD44824022C12241418440449084800001818222820F293BBE8
+:80EF00008C0400240080042E2280E3240822C084008128002C02103224000028498821E8260489088181815028188B28A018404421A26820AA1840280481109C44818082820118200588244812184C373721304228290420240480022860218800002438802808184614C4824004848688042843247424E884038B41A28096488A442882B8
+:80EF800082B12404888B144C0288447820EC84211CA82848202184060088C288F0DFB320024321020080221402202C02890480C8240080A842A0812014822402668202812313481482210642420052808448080084103488A08146040041000020024C01874180C45283040084844218221008800600213022188081289118400280022286
+:80F00000240010018400000084408808220020280C0012904800000020A128800882828A0200228FD50500C048A01468C06800A046A280084E22002812B216A8212C044C68446282482120823421004246B228B418E18604624E284A88891228A2841628248464C122430183A48220044698842A011888488888982668498828DC18C422AC
+:80F08000E06441484244044240820220321224402881584200880000002843028CD4280881278185048002128908C04800C028E0488228480810182484C4841E48880048A8200400004A084671E349280420040042002A8C08828A082442882880C8428002881A8803200848488270C8088612E448840480880112004888221280081800B3
+:80F100008100821200820000328A081004C0D72305800424414604481240820400880000200488004842208C02288244830C828112201128044840C81881C0A81883048C0A84844A084A0942400849111404411004120000DF1B0A10082148108414020088000021214A0830420000002890220020024200828004802821080088002AA1F8
+:80F180008818008504C4883084184A088200410020014488121F283EBA242C04006024162482440220042424001022042800882818422004489042004280644121222012020048220020020040880818818C18341481960880228802601100F03CC860844880442202004820242804200840220C0080020048800C1082088A08000000003C
+:80F200001289240100200180011244008041688400000080014004C0E3734F08808282041812222002A082880048C60280422204880000821004004302A828268214A28200232884882C824408A20048204438488C0820A8848901889024828200A01844D0C90724241022020000882142008044020021684004202424141204C0884008CB
+:80F2800024492174C8022250A484419644084128430C00C7881084044146080000002244002001004C3F1F2182000000268202280000001002009042882200200222A0844008462844921200C2008322880292809428161848084141490110C488C058008832004100806918F01EF10042214A280669941290620021004210489841000035
+:80F30000008E246041B08224222406214224222A0843441284082400E08404811011041840882488B41C01650445841848044C042E21144192908445343F2CB4C244D2220427462924A1634AB2229442CE82822288884A4492428848C2284200584842CAA846A04640EA888CE288246845B6A2442A2404CE883A18382484803CC4838299A2
+:80F3800088C32841F4488446FC4854828A8851C48AA18885A8882A82C2E48A98811A4114641882FD2FD08848A244882384D442C4422721122A3CA2484AA8882D8200888EC2004A04A8282AA242824B24424BA842488E22CAC448834C3A84236D282301C6642A25A8118B5C9286A4848C23664389889148448741464CF48848844F84C18838
+:80F4000018CF4461418604414948941412198979145441CC3884A3442A2422840429052242224888005022237448C2622429F222428E4244E044082A81B282A2244CB28234C48186B46A2834A22F8445F44E22A2807186AA1881818BB24A82E881A42B8C82D88831188458D084DC84F184885AB44C58C88A014331244901288081C89488B0
+:80F480003FFC0D0010022130121002888018C48240028800400280020082003082200882209948100881001800002218008001422044040012604880028220412801D0943B82865282482E42502625F252162F22026AD2225C22424F42526627284E422F24C442AFACF442422F24B4620245044F460465A4284F62A2AA4F4292C287848D27
+:80F50000C8CFC2D222D84CD484FC2868A5FA662C8F82FA8C8C2B88EFCBBBC8FC2CBC85F8BCB42AFC84A48F88F8AC948F8AFA8C8C8F8454CC85FC581C85FCCC88CF48B888E881E188FC8884C143B814014F4474842451888FC8E848F88484547F9A4872427A4AB24232624463E42475463242467242F2C28229EC447EE4F6868AAB442F3475
+:80F58000B44BF48288BD422D622B622A644443E8423434646BA42E246BAEEE244F22C88A85F888ECC726AFEEB846B95C6B262F64F26E888FC8F88C929EBEEF83FDC8ACCF8FF888BCCBEB8EA5DF8CFA88BC5F89F2A88CCF88F4581CC7414B5C47414F45ECE8D886E989B99AF9C8188F4968484CE143A2424F4ED844D184D188B99CE84118E6
+:80F60000748433A987248F84046850622D422F21F522422A24F6628229AC842A5E222FA8A8442541F2CA8A426AF2626225D244084F46855464EAFA24648AFA24242DC285F8C8C8CFC2F2CAEAC5E4C4AD722724EF66E286FE8484AF89F9BEBC8F8CFD2CFC844FCBABEA4F5CFA98984F42F3A8A8CFC8F8585845FC4C8CCFC5F1481CCFCCF811
+:80F680008C869AF9DC98DE988AF8848447484F4353444F4C76846441189AE849F8848445F43C3D2CDC82B448A4446AC44263E464B142F772622F26F622222F2EA8CC4A2AAEC88B482FA4B443F4C28BAF2CF442622B6627262594242E644362444BE4AE264BAEAE244F26F8C2CAABCCCEECCFA6F8CA8E6DD2AFADFBE8422FE4B266FEE88440
+:80F700004FA8F998BECF8BFDD8ACCB8B8F48BBBCEECAFEE5A88F5AB334FAA88CCF88F4581CCF41F4445C4FC1F44CCC4FC8B88EF998DE8BDD8F8CF9988CC7484D144F43F224C44F4C981449E141A98947414D845FC837E54260242004004A0142200420080082488004480080042A042A240483048B8440022420A428205928828182004889
+:80F7800040884208004508848884904488000000000086049FD94E08001002A0248042028220082904210010220200228008808408304888481820280420089220992880228862896088A04141484C084C48A811848810044B8290148009009C34291D242F81C4242F9144F61249222F91B424F112494B922F98B424E998F4249227984F9F
+:80F80000227942F1249283FC24929B2C4D929B2C2E929F44E222F14924A6F249A4929F443A929D246B4B1DA42F89C4A42F99D448F892498B962F99B42CF11249CB862D694B921E494F2249F9249256F124928B254F223D594D929B252CF949242CF549244F28F449249AF4492423D949B396D441FBB2484CF292484CF992482AF992484B82
+:80F88000122F81B424F9FF87144F2231484B12939616DB26419F4422F149249E829F44A2819F44F25282DF46F218429D243BC91D248F916C422F99EC42E299E44AF292494F41FA12492F48C949AE1694AEB446F1843683F484169F86F4A492DD484B899F86E221F14D6C86F26D449A316D2B1DDB26AB59D13F88F125242F9C55442F99310F
+:80F90000242F9C31A4279D4F43F852492B922F94F42482944F636114BEA283F434928372B4F24C289E824E241E128B249E67D30482000044000000004840081400000010080000000000000000000028008440010000200100240000000000004021F4AB788824422C04000048210048000020222408000080080042000029024008808264
+:80F98000048281000080820480010040040096080012004901000041D0B1298E22088200200420282408820000000010420880020000480080040000A100220020010000800481000000820040041001001114414B35A08223841E42040048218220A844828440014A080090828118602A000000808202C400282C146888004800121C1214
+:80FA00002804184880081840826188002001902440044004118C32B5000000800400480000002200000000000042004810024800000000220000000000008140040020080041204101001410F436B7000000100200000000000081000000004302000000304100002004810000000000000000810000000000100800C02F5301844002486D
+:80FA80002001A400220028001220080000008800000022000000848008800280821804000000228002200100000000008800F0638D004002002901A40020022800008C08000000801204000022004200108804842002282018040000800200800100000000100800C0EB23068400200400000000002001000000008800000000100100005B
+:80FB00008200000000000000008042080000000000008200B07204840048002840031008002810040081400800000000000000000021008120018100800500420020022800480000000000006C3F1E840084212400000000400100000040040000280048904314484248108284240841800200002002001008004024010000440082000072
+:80FB8000F0DC6C000000000000881022220100002800000000904A000000001C08002200000000120000000000400800490400000000C0BE334108004200002410880828190141004088028504000022844248D012440180048683848408812001810018A03400420020026042830110040000880000F0A7F60081105822002210014002F5
+:80FC00008002000000000000000000800442000021221004220000000000840000008004480041000000C095530F000000000081004008000000001100000000000000000000000000000000000000000000000000001200BFDF0600000000000020080000000000000000000000000000000000000000000000000000000000000000C003
+:80FC800059530D00000000000000000000000000000000000000000000000000000000000000000000008004000000F081C700000000000000000000000000000000000000000000000000000000000000000000000020040000001C38C7000000000000200800000000000000000000000000000000000000000000000000000000000028
+:80FD00000000007FDB090000000000000080020010088008000000000000000000810000000000000000000081000000000000004035C2000000000010080000000000840000003081004002000010020000000000004008400400008820010000000084009F56040000000000000000000000000000000000000000000000000000000072
+:80FD8000000000000000000000000000B833010010080000000000000000000000000000000000000000000000000000000000000000002008000000BFC30400000000000000000000000000000000000000000000000000000000000000000000000000000000B83301000000000000000000000000000000000000000000000000000065
+:80FE00000000000000000000000000000000BE1300000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300008400000000008002008400848800000011000000000024840000000000004008400400008820010000000000D0B30400000000001008000000000000000000820010022C
+:80FE800000000000000000000000000000100800000020080010081C362300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B01000000000000000022000000308100000013080021000000218100000081000000810041001008822001002008120081C05C634402405848184002B0
+:80FF00008D2840044885082840044800C08180D1884402C0814418400280480440428802448004842840044840088844800484804884012400884418404288028FFD0C00000000000000000000000000100100000000000000000000000000000000000000000000000020011C3C31440000000000000080020000001C080000C0810040AD
+:80FF8000024002002484000000840084004008400440440888841800008880014008F0C6BD00000000000000000000000000000000000000000000000000000000000000000000000000000000803B1300000000000000000000000000000000000000000000000000000000000000000000000000000000E03B012001210010240121206B
+:020000040002F8
+:800000000241200400100442000020211402004112000082410000221004420022100442002008200400100410020041002D17930B00000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000010010000000000000000000000000000000000000000000000EF
+:8000800000000012C0D7630F00000000000000000000000000000000000000000000000000000000000000000000000000000000BE1300000000000000000000000010010000000000000000000000000000000000000000000000000000006C31350000000000000000000000000000000000000000000000000000000000000000000031
+:38010000000000000018001BD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:00000001FF
diff --git a/kernel/xpp/firmwares/PIC_TYPE_1.hex b/kernel/xpp/firmwares/PIC_TYPE_1.hex
new file mode 100644
index 0000000..c5ca503
--- /dev/null
+++ b/kernel/xpp/firmwares/PIC_TYPE_1.hex
@@ -0,0 +1,467 @@
+#
+# $Id: PIC_TYPE_1.hex 7107 2009-05-18 12:35:20Z dima $
+#
+:03000000A1EA4A28
+:03000100C41C41DB
+:030002000390392F
+:0300030067967984
+:03000400A03A031C
+:03000500C40C40E8
+:030006000390392B
+:030007007797796F
+:03000800A07A07D4
+:030009008008006C
+:03000A002072075A
+:03000B0064364315
+:03000C00A11A1125
+:03000D003213218A
+:03000E002C82C879
+:03000F00D00D0011
+:03001000A0BA0B88
+:03001100CFECFE33
+:0300120016116163
+:03001300C01C010D
+:030014006046043F
+:03001500121121A4
+:030016002072074E
+:0300170064364309
+:03001800A1DA1D4D
+:030019003613613A
+:03001A002C82C86D
+:03001B00D00D0005
+:03001C00A17A17AF
+:03001D0080080058
+:03001E00C0710BA3
+:03001F0016603830
+:03002000743C0627
+:03002100A26D804D
+:03002200C01024E7
+:030023001CCC00F2
+:03002400E03022A7
+:0300250002C20113
+:03002600C03030B7
+:0300270018C901F4
+:030028006432043B
+:03002900A4C03040
+:03002A0020C901E9
+:03002B007432022A
+:03002C00AFA03052
+:03002D0020990116
+:03002E00021C8031
+:03002F00C40FFFFC
+:03003000D8016490
+:03003100024C106E
+:03003200C00FFFFD
+:0300330002215057
+:03003400201D0884
+:030035000306B906
+:03003600901D100A
+:0300370020402244
+:03003800030201BF
+:03003900901030F4
+:03003A0020290179
+:03003B00030204B9
+:03003C00901030F1
+:03003D00C11901E5
+:03003E00190202A2
+:03003F00643030FA
+:03004000A45901BF
+:03004100C22800D2
+:030042001902148C
+:03004300743E7098
+:03004400A483088A
+:03004500209308FD
+:030046001253084A
+:03004700A4B30857
+:03004800209027DE
+:03004900FFF800BD
+:03004A00165C0041
+:03004B00AFA0392A
+:03004C00209038C9
+:03004D00145C0739
+:03004E00643D40CE
+:03004F00A8C03412
+:03005000209C08E9
+:0300510002103862
+:03005200C40219CC
+:03005300D80E07BD
+:0300540002402047
+:03005500C0036085
+:0300560002236022
+:0300570020136013
+:030058000303603F
+:03005900901C10E8
+:03005A002040380B
+:03005B0003021984
+:03005C00901E07EC
+:03005D002021203F
+:03005E00030C1080
+:03005F009011807D
+:03006000C11E704E
+:0300610019074339
+:03006200643A6D90
+:03006300A68C0266
+:03006400C2218036
+:03006500190E036E
+:03006600743643AA
+:03006700A8CA70B4
+:03006800209C03D6
+:0300690002118001
+:03006A00C44E037E
+:03006B00D8064371
+:03006C00024A70D5
+:03006D00C00C01C3
+:03006E0002203835
+:03006F00201A6FE5
+:03007000030C1866
+:03007100901038B4
+:0300720020421910
+:03007300030E0F6A
+:0300740090103DAC
+:03007500202C003C
+:030076000300384C
+:03007700901C02D8
+:03007800210180E3
+:03007900E03E0363
+:03007A0074374395
+:03007B00C04A80F8
+:03007C00190C3F1D
+:03007D007480315B
+:03007E00A8CC16F5
+:03007F00C04A84F0
+:03008000FFFCFF83
+:0300810015003136
+:03008200643C18C3
+:03008300A87A84D4
+:0300840020903C8D
+:0300850013EE0F68
+:03008600A8A09D92
+:03008700209703BC
+:03008800FFFA8EEE
+:0300890017EC0F62
+:03008A0021EFFF64
+:03008B0003515CC2
+:03008C00C1411D52
+:03008D00D80A8FFF
+:03008E0002421C0F
+:03008F00C000307E
+:03009000022E0F2E
+:0300910020103C00
+:03009200030C025A
+:0300930090103991
+:03009400204C00FD
+:030095000300392C
+:03009600901C803B
+:0300970020202402
+:03009800030C084E
+:03009900901104BF
+:03009A0021003909
+:03009B00E01C0066
+:03009C00027039B6
+:03009D00C18C0013
+:03009E00D8002661
+:03009F00024025F7
+:0300A000C0003E5F
+:0300A10002202B0F
+:0300A200201C031C
+:0300A30003002C2B
+:0300A400901C00AD
+:0300A500204208EE
+:0300A60003003024
+:0300A700901901AC
+:0300A800202C8089
+:0300A90003020847
+:0300AA0090103083
+:0300AB0021090127
+:0300AC0003BC4052
+:0300AD00C1403916
+:0300AE000246D92E
+:0300AF00C01AB3C1
+:0300B0000226F92C
+:0300B100201BB65B
+:0300B200030AAE90
+:0300B3009019425F
+:0300B400204C02DB
+:0300B500030180C4
+:0300B600901E0396
+:0300B7002077436C
+:0300B800030AD464
+:0300B900901C0692
+:0300BA0021A195EC
+:0300BB00141743D4
+:0300BC00707AD483
+:0300BD00AC07D3BA
+:0300BE00181AD439
+:0300BF00AC3C0650
+:0300C00069B1879C
+:0300C100AFA743A3
+:0300C200F00AC57C
+:0300C300228C0389
+:0300C400643AD2C9
+:0300C500AFAC07D6
+:0300C6001BA187F4
+:0300C700C107432B
+:0300C800FFFACB71
+:0300C90017BC0160
+:0300CA0021AAD296
+:0300CB00141C03FF
+:0300CC0064318715
+:0300CD00AD074339
+:0300CE00C10AD193
+:0300CF0013BC005F
+:0300D000C50AD28C
+:0300D10003920790
+:0300D200799027FB
+:0300D300AD2AE172
+:0300D40020BC0647
+:0300D500D00195C2
+:0300D6000386435B
+:0300D700219AE18A
+:0300D800E07C01C8
+:0300D9003481C7A8
+:0300DA0034809CD3
+:0300DB0034870364
+:0300DC00348AE182
+:0300DD00030CFF12
+:0300DE002060227D
+:0300DF0034802743
+:0300E000348B4915
+:0300E100348C005C
+:0300E2003486F36E
+:0300E300D05CFFEF
+:0300E400031021E5
+:0300E500C00C014B
+:0300E600032024D0
+:0300E70003390AD0
+:0300E800C706B395
+:0300E900039B7006
+:0300EA00C50C0141
+:0300EB0003902F50
+:0300EC00C18215B9
+:0300ED000306D334
+:0300EE00C00D80C2
+:0300EF00031024D7
+:0300F00021B21723
+:0300F100032022C7
+:0300F200C00C0639
+:0300F30003319541
+:0300F400C70743F8
+:0300F500039B3832
+:0300F600C506D369
+:0300F700039B3830
+:0300F800C40CE055
+:0300F90003915719
+:0300FA00369643F4
+:0300FB00C01B38EF
+:0300FC001E6C0077
+:0300FD0021C7B761
+:0300FE00086C0586
+:0300FF007437D77C
+:03010000A1EC105F
+:030101000267F79B
+:03010200C02C020C
+:03010300FFF027E3
+:0301040016BC1016
+:03010500C02D0208
+:0301060023EFFFE5
+:030107007431420E
+:0301080012B69795
+:0301090020BD0214
+:03010A0003863732
+:03010B00C44D10D0
+:03010C000390223B
+:03010D00C40C809F
+:03010E0003912436
+:03010F00C00C021F
+:0301100002318039
+:03011100AACE0370
+:03011200B12743CF
+:03011300000B26B8
+:03011400000C05D7
+:030115000001479F
+:030116000006439D
+:03011700000B26B4
+:03011800000C01D7
+:0301190000018161
+:03011A0000074398
+:03011B00000B1FB7
+:03011C00000C10C4
+:03011D00000021BE
+:03011E00000B26AD
+:03011F00000C10C1
+:030120000001815A
+:0301210000074391
+:03012200000B26A9
+:03012300000C20AD
+:03012400000021B7
+:03012500000B26A6
+:03012600000201D3
+:03012700000030A5
+:03012800000901CA
+:03012900000204CD
+:03012A00000030A2
+:03012B00000901C7
+:03012C00000202CC
+:03012D000000309F
+:03012E00000901C4
+:03012F00000C8041
+:03013000000FFFBE
+:0301310000016466
+:03013200000207C1
+:0301330000016266
+:03013400000FFFBA
+:0301350000015076
+:03013600000D08B1
+:03013700000122A2
+:03013800000201C1
+:0301390000003093
+:03013A00000901B8
+:03013B00000204BB
+:03013C0000003090
+:03013D00000901B5
+:03013E00000202BA
+:03013F000000308D
+:03014000000901B2
+:03014100000C00AF
+:0301420000002F8B
+:030143000007D3DF
+:03014400000B6B42
+:03014500000210A5
+:0301460000002294
+:0301470000020EA5
+:030148000000278D
+:03014900000C5057
+:03014A0000003979
+:03014B0000079911
+:03014C00000B4B5A
+:03014D000002129B
+:03014E000000307E
+:03014F0000021497
+:030150000000317B
+:0301510000021396
+:030152000006B3F1
+:03015300000D108C
+:0301540000003276
+:03015500000C009B
+:0301560000003373
+:03015700000C7029
+:030158000000396B
+:03015900000C5047
+:03015A0000003969
+:03015B000002158A
+:03015C0000003070
+:03015D0000021687
+:03015E000000316D
+:03015F0000020299
+:030160000000326A
+:03016100000C008F
+:030162000006B3E1
+:0301630000020790
+:0301640000003365
+:03016500000C701B
+:030166000000395D
+:03016700000C5039
+:030168000000395B
+:03016900000C4047
+:03016A0000003959
+:03016B00000C0085
+:03016C0000003957
+:03016D00000C0083
+:03016E00000C0082
+:03016F00000AACD7
+:03017000000C027E
+:0301710000002F5C
+:03017200000C0A74
+:0301730000002A5F
+:03017400000C007C
+:0301750000002463
+:030176000007D3AC
+:03017700000B93E7
+:0301780000020181
+:0301790000003053
+:03017A0000090178
+:03017B000002156A
+:03017C0000003050
+:03017D0000090175
+:03017E0000021666
+:03017F000000304D
+:0301800000090172
+:03018100000C1F50
+:03018200000D80ED
+:0301830000002257
+:0301840000020175
+:0301850000003047
+:030186000009016C
+:0301870000020271
+:0301880000003044
+:0301890000090169
+:03018A000002046C
+:03018B0000003041
+:03018C0000090166
+:03018D000002EA83
+:03018E0000071057
+:03018F00000B91D1
+:03019000000B84DD
+:030191000007D391
+:03019200000BB1AE
+:03019300000C1D40
+:030194000006D38F
+:03019500000D80DA
+:0301960000002244
+:0301970000020162
+:0301980000003034
+:0301990000090159
+:03019A000002025E
+:03019B0000003031
+:03019C0000090156
+:03019D0000021845
+:03019E000000302E
+:03019F0000090153
+:0301A0000002104A
+:0301A10000002E2D
+:0301A200000C1C32
+:0301A3000006D380
+:0301A400000D80CB
+:0301A50000002235
+:0301A60000020153
+:0301A70000003025
+:0301A8000009014A
+:0301A9000002024F
+:0301AA0000003022
+:0301AB0000090147
+:0301AC0000021737
+:0301AD000000301F
+:0301AE0000090144
+:0301AF000007D373
+:0301B000000B78C9
+:0301B100000C003F
+:0301B20000002F1B
+:0301B3000007D36F
+:0301B400000B6BD2
+:0301B500000B49F3
+:0301B600000C0733
+:0301B70000002F16
+:0301B800000C0434
+:0301B90000002122
+:0301BA00000C0036
+:0301BB0000091E1A
+:0301BC00000C1024
+:0301BD000000211E
+:0301BE00000C082A
+:0301BF0000091E16
+:0301C000000C40F0
+:0301C1000000211A
+:0301C200000C101E
+:0301C30000091E12
+:0301C400000C002C
+:0301C50000002611
+:0301C600000C0129
+:0301C7000000290C
+:0301C800000C0028
+:0301C90000002F04
+:0301CA00000C2006
+:0301CB000000230E
+:0301CC00000A0026
+:0301CD00000AAC79
+:0301CE00000BCE55
+:00000001FF
diff --git a/kernel/xpp/firmwares/PIC_TYPE_2.hex b/kernel/xpp/firmwares/PIC_TYPE_2.hex
new file mode 100644
index 0000000..c37fd5b
--- /dev/null
+++ b/kernel/xpp/firmwares/PIC_TYPE_2.hex
@@ -0,0 +1,339 @@
+#
+# $Id: PIC_TYPE_2.hex 7107 2009-05-18 12:35:20Z dima $
+#
+:03000000A57A4896
+:03000100C41C41DB
+:030002000390392F
+:0300030067967984
+:03000400A03A031C
+:03000500C40C40E8
+:030006000390392B
+:030007007797796F
+:03000800A07A07D4
+:030009008008006C
+:03000A0002A02A27
+:03000B00C04C04E2
+:03000C000240248B
+:03000D00C00C0024
+:03000E0002502578
+:03000F0036536500
+:0300100020A20A21
+:03001100E01E01ED
+:0300120012512563
+:0300130032A32AEB
+:030014002E42E495
+:03001500A0FA0F3F
+:030016008008005F
+:0300170020D21DD7
+:0300180062410B37
+:0300190020E038AC
+:03001A00025C2065
+:03001B0020AD40D5
+:03001C0064312527
+:03001D00A23C20E2
+:03001E0032502439
+:03001F00325C0050
+:030020002C80220F
+:03002100D0020505
+:03002200A1C0304A
+:0300230020590160
+:03002400E03204C3
+:0300250002103096
+:03002600CFC9013E
+:030027001652026C
+:0300280064403001
+:03002900A3290107
+:03002A00704C40D7
+:03002B00A41FFF10
+:03002C00C011659B
+:03002D001E1C0294
+:03002E00C03FFFD1
+:03002F0016115057
+:030030002016B9DE
+:03003100125D025B
+:0300320020A022E9
+:03003300643C0228
+:03003400A3AD0178
+:03003500365162DF
+:030036003652053A
+:030037002C8030EA
+:03003800D00901EB
+:03003900A33204EB
+:03003A0020503023
+:03003B0072490106
+:03003C00A3E2023A
+:03003D00A40030EC
+:03003E0002D901E3
+:03003F00A4180002
+:0300400002E214C5
+:03004100800E70BE
+:030042000223088E
+:030043002063082F
+:030044006433081A
+:03004500A4A30869
+:0300460032203F26
+:030047002C880002
+:03004800D00C00D9
+:03004900A4403997
+:03004A00CFE038CC
+:03004B00162C0769
+:03004C00C01D4094
+:03004D00604034DC
+:03004E00122C0869
+:03004F00206038F6
+:03005000643219FE
+:03005100A56E0792
+:0300520036202035
+:030053002C83609B
+:03005400D0036076
+:03005500A50360A0
+:03005600800360C4
+:03005700C07C105A
+:03005800166038F7
+:03005900743219E5
+:03005A00A5FE07F9
+:03005B00C01120B1
+:03005C001CCC2099
+:03005D00E07180CF
+:03005E0002CE705F
+:03005F00206743D4
+:0300600090AA6BF8
+:03006100205C021E
+:03006200D2018048
+:03006300D40E03B5
+:0300640003D6437D
+:03006500C1CA6E9F
+:03006600022C0366
+:03006700C0018055
+:03006800024E0342
+:0300690021D6435A
+:03006A00030A6E18
+:03006B00901C01E5
+:03006C0020203819
+:03006D00030A6D16
+:03006E00901C18CB
+:03006F00204038F6
+:030070000302196F
+:03007100901E0FCF
+:0300720021002248
+:03007300024C003C
+:03007400C0303861
+:030075000842003E
+:03007600603E03E6
+:03007700A7AF022E
+:030078002097438B
+:03007900A7CA7E95
+:03007A00C00C00B7
+:03007B00A7C031EA
+:03007C00187C12DB
+:03007D00149A8250
+:03007E00643C00DF
+:03007F00AAB031F3
+:030080001A7C18CF
+:03008100C50A822B
+:0300820003903BAD
+:03008300799E0F54
+:03008400A830821F
+:0300850020B7039E
+:03008600D00A8C11
+:03008700038C0FD8
+:03008800219FFFB6
+:03008900E0715BC8
+:03008A00348102BC
+:03008B00348A8D27
+:03008C0034821BA0
+:03008D003480308C
+:03008E00030E0F4F
+:03008F0020603BB3
+:03009000348C02AB
+:030091003480397F
+:03009200348C00AB
+:030093003480397D
+:03009400D05C80BD
+:03009500031D0840
+:03009600C000396E
+:03009700032C0037
+:03009800033039F9
+:03009900C70C4051
+:03009A0003903997
+:03009B00C507D9BD
+:03009C00039A9B29
+:03009D00C1CC00D3
+:03009E0003002636
+:03009F00C0002777
+:0300A00003102B1F
+:0300A100204020DC
+:0300A200032C0329
+:0300A300C0002C6E
+:0300A400033C20FA
+:0300A500C70D8004
+:0300A6000390259F
+:0300A700C50C2065
+:0300A8000390249E
+:0300A900C40C0084
+:0300AA000390229E
+:0300AB0020C2056B
+:0300AC007430307D
+:0300AD00B1790125
+:0300AE00C0020489
+:0300AF00024030DC
+:0300B000C0590133
+:0300B10002220226
+:0300B200205030AB
+:0300B300D209016E
+:0300B400D40C4029
+:0300B50003D0393C
+:0300B60021D6D977
+:0300B700030ABB7E
+:0300B8009016F9A6
+:0300B900202B38C1
+:0300BA00030AB680
+:0300BB0090194059
+:0300BC00204C20B5
+:0300BD00030195A7
+:0300BE0090164356
+:0300BF00C01ACA9A
+:0300C000150C011B
+:0300C1000241DF1A
+:0300C20021A09BDF
+:0300C3009427037C
+:0300C400202ACA25
+:0300C50003A7D3BB
+:0300C600206B3379
+:0300C700743CFF87
+:0300C800AD502216
+:0300C900C9FB155B
+:0300CA0016B21F4C
+:0300CB00C0090A5F
+:0300CC006B0C209A
+:0300CD00D2012538
+:0300CE006D06D3E9
+:0300CF00D40AD57B
+:0300D00012BC203F
+:0300D100C80095CF
+:0300D2001AB64318
+:0300D30020BADD73
+:0300D400038ADAC2
+:0300D500206C405C
+:0300D60002A1255F
+:0300D700C04C001A
+:0300D80008602499
+:0300D900703B0574
+:0300DA00ADE2177D
+:0300DB00C000243E
+:0300DC00024B05CF
+:0300DD00AE2C4006
+:0300DE00C0410519
+:0300DF000AA03D37
+:0300E000C02C0031
+:0300E100024024B6
+:0300E20091721DFB
+:0300E300C010301A
+:0300E40003E9012C
+:0300E50020621581
+:0300E60064303053
+:0300E700AEB901AE
+:0300E80037E204F8
+:0300E9002C803038
+:0300EA00AE8901DB
+:0300EB00C602103A
+:0300EC00150024D8
+:0300ED007437F76E
+:0300EE00AFFAF670
+:0300EF0021EC02FF
+:0300F0001AFFFFF5
+:0300F10014F164A3
+:0300F200743C0259
+:0300F300B1715791
+:0300F400C04124E4
+:0300F500124B02A9
+:0300F6009177D728
+:0300F700C00B0239
+:0300F800024C01B6
+:0300F900200FFFD6
+:0300FA00942164EA
+:0300FB00202C01B5
+:0300FC00020157A7
+:0300FD0003512488
+:0300FE00B17B02D1
+:0300FF00CFF21726
+:0301000019E024DF
+:0301010016FB02E8
+:03010200C03C02FC
+:03010300081D01D3
+:03010400743164EF
+:03010500B0EC80DB
+:03010600C016F32D
+:030107000241258D
+:03010800200205CD
+:030109009420300F
+:03010A00202901A8
+:03010B00020215D8
+:03010C000350306D
+:03010D00B17901C4
+:03010E00C0020428
+:03010F0018103095
+:030110006439014E
+:030111006B07D3A6
+:03011200B14B33BB
+:03011300B17210B6
+:03011400C01022F6
+:03011500124C5039
+:03011600917039AC
+:030117003697997F
+:03011800C01B17F2
+:030119001E621251
+:03011A0021B030E1
+:03011B0008621463
+:03011C007430310B
+:03011D00A57213B5
+:03011E000260324A
+:03011F00C02C00F1
+:03012000FFF033BA
+:0301210016BC7099
+:03012200C02039C1
+:0301230023AC50BA
+:03012400743039FB
+:0301250012B215FE
+:0301260020B030D6
+:03012700038C0046
+:03012800C440319F
+:030129000392023C
+:03012A00C40032DC
+:03012B00039C0032
+:03012C00C00033DD
+:03012D00023C7021
+:03012E00AB4039AA
+:03012F00B2FC50CF
+:0301300000003993
+:03013100000C407F
+:0301320000003991
+:03013300000C00BD
+:030134000000398F
+:03013500000C00BB
+:03013600000C00BA
+:03013700000AB407
+:03013800000C04B4
+:030139000000259E
+:03013A00000C00B6
+:03013B0000003D84
+:03013C00000917A0
+:03013D00000C02B1
+:03013E0000002599
+:03013F00000C08A9
+:0301400000003D7F
+:030141000009179B
+:03014200000C06A8
+:0301430000002594
+:03014400000C109C
+:0301450000003D7A
+:0301460000091796
+:03014700000C00A9
+:030148000000268E
+:03014900000C01A6
+:03014A0000002989
+:03014B00000C2085
+:03014C000000238D
+:03014D00000A00A5
+:03014E00000B4E55
+:00000001FF
diff --git a/kernel/xpp/firmwares/PIC_TYPE_3.hex b/kernel/xpp/firmwares/PIC_TYPE_3.hex
new file mode 100644
index 0000000..a71cb55
--- /dev/null
+++ b/kernel/xpp/firmwares/PIC_TYPE_3.hex
@@ -0,0 +1,374 @@
+#
+# $Id: PIC_TYPE_3.hex 7107 2009-05-18 12:35:20Z dima $
+#
+:03000000A0AC00B1
+:03000100C41039EF
+:0300020003903830
+:03000300679C08EF
+:03000400A03038F1
+:03000500C4021919
+:03000600039E074F
+:03000700779020CF
+:03000800A0736082
+:0300090080036011
+:03000A00C0F360E0
+:03000B000343604C
+:03000C00C08C1095
+:03000D0003803835
+:03000E0021921923
+:03000F00E07E0789
+:03001000020120CA
+:03001100360C307A
+:0300120036018034
+:03001300360E7036
+:030014003606436A
+:03001500C10A1904
+:03001600038C0157
+:03001700219038FD
+:03001800E07A1873
+:03001900120C20A6
+:03001A00C30023FD
+:03001B00180A0AB6
+:03001C00E70C41AD
+:03001D0074303903
+:03001E00A20679BE
+:03001F00A23A1EE4
+:03002000C01C40C1
+:0300210003803920
+:03002200A2277999
+:03002300C18A226D
+:030024000388004E
+:03002500219C40DB
+:03002600E0F039CE
+:0300270002BC0018
+:03002800C0003ADB
+:030029000386F952
+:03002A00C00A7E8B
+:03002B0002C7D930
+:03002C0002EA27BE
+:03002D00C4020901
+:03002E0060C02C83
+:03002F00D01C40A2
+:030030000276D481
+:03003100C16D019D
+:0300320020802704
+:03003300030C00BB
+:030034002076D45F
+:03003500031D01A7
+:03003600901029FE
+:03003700C006F40C
+:03003800D80A9B48
+:03003900029C1610
+:03003A00C00208F9
+:03003B00208030F2
+:03003C00030207B5
+:03003D00209031DF
+:03003E0003191C87
+:03003F0090121408
+:03004000C63F10A8
+:03004100090308A8
+:030042007433080C
+:03004300A4C3084B
+:03004400C04308AE
+:030045001EEE03A9
+:03004600C01208DD
+:030047001EC030A8
+:03004800C02209CA
+:0300490008C031BB
+:03004A0074391CEA
+:03004B00A2D21529
+:03004C0020E03081
+:03004D0008B207EF
+:03004E00703031DE
+:03004F00A5291CC4
+:0300500020B209D2
+:0300510002E6D3F1
+:03005200C08D80DE
+:0300530008E02A98
+:0300540060321700
+:03005500A5903043
+:03005600C0220ABB
+:03005700D40031A1
+:03005800A6A91C3A
+:03005900C017D3FA
+:03005A0003BA796D
+:03005B00C04C5046
+:03005C0008E03980
+:03005D0070379960
+:03005E00A66A5D32
+:03005F0020E2128A
+:03006000348030B9
+:03006100348214D2
+:03006200348031B6
+:03006300348213D1
+:0300640011B032A6
+:03006500A6AC0046
+:03006600C0403364
+:0300670002EC7038
+:0300680021B0398B
+:03006900D40C5064
+:03006A0003B039A7
+:03006B00C00215BB
+:03006C0002C0309F
+:03006D0002A216D6
+:03006E00C400319A
+:03006F000272100A
+:03007000C000329B
+:03007100029C00EE
+:03007200C0103388
+:0300730022CC702C
+:03007400743039AC
+:03007500A7AC50E5
+:03007600C0F0399E
+:0300770002BC4088
+:03007800C4C039C8
+:03007900A8BC0020
+:03007A0008C03982
+:03007B007436D9FF
+:03007C00A81A7B44
+:03007D00C07A2521
+:03007E0002B21AB1
+:03007F00C4AE709C
+:03008000A8B743DB
+:0300810020CA8A08
+:0300820002BC803D
+:03008300C02D0F7E
+:030084000AB0348B
+:0300850032BC0486
+:030086007030389F
+:03008700A8AC140E
+:03008800C802C8E3
+:03008900129A8840
+:03008A00C48C40E3
+:03008B00208027AB
+:03008C00030C0161
+:03008D002076DA00
+:03008E0003112734
+:03008F00901C00C2
+:0300900020B02974
+:03009100030C015C
+:030092002096DADB
+:030093000311292D
+:03009400901209BE
+:03009500210D80BA
+:0300960034802C87
+:03009700348C00A6
+:03009800348D0F95
+:030099003480347C
+:03009A0002BAACFB
+:03009B00C80C0787
+:03009C0014B15448
+:03009D007E964309
+:03009E00AA1AA0FB
+:03009F0032AAA8DA
+:0300A00012AC009F
+:0300A100C0177411
+:0300A2001ECC80F1
+:0300A300C12D0864
+:0300A40008C03958
+:0300A500743C00A8
+:0300A600A6E03998
+:0300A70020AA2567
+:0300A80002B20998
+:0300A90032B02C46
+:0300AA00C5521428
+:0300AB0016A03A62
+:0300AC0016B21A6F
+:0300AD0034AE303E
+:0300AE0010BF1070
+:0300AF0003130830
+:0300B00021BD046B
+:0300B1000306EC57
+:0300B200C02D015D
+:0300B30003902F88
+:0300B400C00C0F6E
+:0300B500039208AB
+:0300B600C0003057
+:0300B7000232070B
+:0300B800A2503122
+:0300B90020591CAF
+:0300BA0008420FEA
+:0300BB00E3F20865
+:0300BC0002D0303F
+:0300BD0020120905
+:0300BE000A003104
+:0300BF00C0191C49
+:0300C00022020910
+:0300C100743D800B
+:0300C2001ED02A23
+:0300C300C05C001E
+:0300C40002B02B5C
+:0300C50020DC1C20
+:0300C60008B20875
+:0300C70060303076
+:0300C800ACA207E0
+:0300C900ACF03167
+:0300CA00C0591CFE
+:0300CB0002DC0054
+:0300CC00C0020867
+:0300CD0002B0304E
+:0300CE00AD420A36
+:0300CF00220031DB
+:0300D00064391C74
+:0300D100B4221046
+:0300D200C016282D
+:0300D30002BAC5A9
+:0300D40021A60B57
+:0300D500E70B6DC9
+:0300D600D8020944
+:0300D70003AD80F6
+:0300D80020D02A0B
+:0300D90013AC0C59
+:0300DA00C0020859
+:0300DB0002603090
+:0300DC0020D20728
+:0300DD006430315B
+:0300DE00B0591CFA
+:0300DF00C01C0042
+:0300E0000AD20839
+:0300E1001E60306E
+:0300E200C8020A47
+:0300E30020803149
+:0300E40003091CF1
+:0300E50020721076
+:0300E600031020E4
+:0300E700901C0D5D
+:0300E800C002084B
+:0300E90020803044
+:0300EA0003020707
+:0300EB0020C03101
+:0300EC0003191CD9
+:0300ED00901C0064
+:0300EE002C620879
+:0300EF00AF3030FF
+:0300F00021020AE0
+:0300F10003B03128
+:0300F200B0491CF6
+:0300F3002C82104C
+:0300F400AF8021B9
+:0300F500210C04D7
+:0300F60003C2083A
+:0300F700B04030E6
+:0300F8002C820750
+:0300F900AFD03154
+:0300FA0021091CBD
+:0300FB0003DC0023
+:0300FC00B0420807
+:0300FD002C803024
+:0300FE00B0220A23
+:0300FF00210031AC
+:0301000003E91CF4
+:03010100B04210F9
+:03010200210024B5
+:0301030003FC06F4
+:03010400ADC20881
+:0301050070B030A7
+:03010600B24207FB
+:03010700C0E03124
+:0301080020891C2F
+:03010900030C00E4
+:03010A0020720858
+:03010B00031030AE
+:03010C0090120A44
+:03010D00C01031EE
+:03010E0020891C29
+:03010F00030210D8
+:0301100020902517
+:03011100031C14B8
+:0301120090120840
+:03011300C0803079
+:0301140013A2072C
+:03011500C1C03135
+:0301160020891C21
+:03011700030C00D6
+:030118002072084A
+:03011900031030A0
+:03011A0090120A36
+:03011B00C00031F0
+:03011C0020891C1B
+:03011D00030210CA
+:03011E0020A026F8
+:03011F00031C209E
+:0301200090102319
+:030121002106ECC8
+:03012200628AB935
+:03012300B15C00CC
+:03012400C50023F0
+:03012500039C0731
+:0301260079902BA2
+:03012700B26201C0
+:03012800C0008094
+:03012900030E07BB
+:03012A0021A08B86
+:03012B0003164375
+:03012C0021BA25D0
+:03012D00032C3F61
+:03012E00C0002BE3
+:03012F0003320692
+:03013000C700AB5A
+:0301310003921422
+:03013200C50E07F0
+:0301330003902D09
+:0301340021C0AB3C
+:03013500030603BB
+:0301360021DA25A6
+:03013700031C00A6
+:0301380021E0269D
+:0301390003220D91
+:03013A0021F64368
+:03013B00033B5C27
+:03013C00C70C01EC
+:03013D000390AD7F
+:03013E00C501E612
+:03013F00039C809E
+:03014000C40208EE
+:03014100039030F8
+:03014200C70207EA
+:0301430017A031D1
+:03014400C1091CD2
+:030145001FA2C630
+:0301460031AB4991
+:03014700308213F0
+:03014800308B56A3
+:030149003082C839
+:03014A0018EB4D62
+:03014B0064321506
+:03014C00B50B569A
+:03014D00C002C825
+:03014E00023B5120
+:03014F00A2921663
+:03015000C00B568B
+:0301510003A2C83E
+:03015200C44B5546
+:03015300039217FD
+:03015400C40B5683
+:03015500039218FA
+:03015600C00208DC
+:0301570002303043
+:03015800A2520CA4
+:0301590000003172
+:03015A0000091C7D
+:03015B00000B395D
+:03015C0000077425
+:03015D00000B6D27
+:03015E00000C0E84
+:03015F0000020893
+:030160000000306C
+:0301610000020792
+:0301620000003169
+:0301630000091C74
+:03016400000C018B
+:030165000002088D
+:0301660000003066
+:030167000002098A
+:0301680000003163
+:0301690000091C6E
+:03016A00000C0185
+:03016B0000002B66
+:03016C00000AC5C1
+:03016D00000C0083
+:03016E0000003955
+:03016F000006D9AE
+:03017000000B6F12
+:03017100000A255C
+:00000001FF
diff --git a/kernel/xpp/firmwares/PIC_TYPE_4.hex b/kernel/xpp/firmwares/PIC_TYPE_4.hex
new file mode 100644
index 0000000..6419870
--- /dev/null
+++ b/kernel/xpp/firmwares/PIC_TYPE_4.hex
@@ -0,0 +1,316 @@
+#
+# $Id: PIC_TYPE_4.hex 7107 2009-05-18 12:35:20Z dima $
+#
+:03000000A0AA0AA9
+:03000100C41C41DB
+:030002000390392F
+:0300030067967984
+:03000400A03A031C
+:03000500C40C40E8
+:030006000390392B
+:030007007797796F
+:03000800A07A07D4
+:030009008008006C
+:03000A00000C00E7
+:03000B00000039B9
+:03000C00000038B9
+:03000D00000CFFE5
+:03000E000002C825
+:03000F00000A0ED6
+:03001000000C00E1
+:03001100000038B4
+:03001200000C17C8
+:03001300000034B6
+:0300140000002BBE
+:03001500000C08D4
+:03001600000038AF
+:03001700000219CB
+:03001800000E07D0
+:03001900000020C4
+:03001A0000036080
+:03001B000003607F
+:03001C000003607E
+:03001D000003607D
+:03001E00000C10C3
+:03001F00000038A6
+:03002000000219C2
+:03002100000E07C7
+:03002200000120BA
+:03002300000C408E
+:0300240000018058
+:03002500000E705A
+:030026000007438D
+:03002700000A29A3
+:03002800000A2C9F
+:03002900000C01C7
+:03002A000000389B
+:03002B00000A2B9D
+:03002C00000C18AD
+:03002D0000003898
+:03002E00000219B4
+:03002F00000E0FB1
+:0300300000002E9F
+:03003100000C00C0
+:0300320000003893
+:03003300000C00BE
+:03003400000024A5
+:0300350000002D9B
+:0300360000002C9B
+:03003700000C902A
+:030038000000299C
+:03003900000C00B8
+:03003A00000021A2
+:03003B00000C8234
+:03003C000000229F
+:03003D00000201BD
+:03003E000000328D
+:03003F00000202BA
+:030040000000318C
+:03004100000209B1
+:030042000000308B
+:03004300000901B0
+:03004400000C832A
+:0300450000002296
+:03004600000201B4
+:0300470000003284
+:03004800000202B1
+:0300490000003183
+:03004A00000209A8
+:03004B0000003082
+:03004C00000901A7
+:03004D00000C04A0
+:03004E0000008E21
+:03004F00000703A4
+:03005000000A544F
+:0300510000020E9C
+:0300520000002F7C
+:03005300000A564A
+:03005400000C0499
+:0300550000002F79
+:0300560000036F35
+:0300570000036F34
+:0300580000036F33
+:0300590000036F32
+:03005A00000C0196
+:03005B0000012F72
+:03005C0000020F90
+:03005D0000003070
+:03005E00000C0093
+:03005F000000316D
+:03006000000C028F
+:0300610000003963
+:03006200000C008F
+:0300630000003961
+:03006400000C404D
+:030065000000395F
+:030066000007D9B7
+:03006700000AB6D6
+:03006800000C0089
+:030069000007D3BA
+:03006A00000A6C1D
+:03006B00000D8005
+:03006C0000002170
+:03006D000002147A
+:03006E00000E3051
+:03006F0000030883
+:0300700000030882
+:0300710000030881
+:0300720000030880
+:0300730000012168
+:0300740000020186
+:0300750000003256
+:0300760000021570
+:0300770000003155
+:030078000002176C
+:0300790000003054
+:03007A0000090179
+:03007B00000C2155
+:03007C00000195EB
+:03007D0000074336
+:03007E00000A91E4
+:03007F000006D3A5
+:03008000000A91E2
+:03008100000C016F
+:0300820000002A51
+:0300830000020177
+:03008400000E0368
+:030085000006432F
+:03008600000A8BE2
+:0300870000036A09
+:030088000002C8AB
+:03008900000D0067
+:03008A00000A85E4
+:03008B00000CFF67
+:03008C0000018AE6
+:03008D0000014C23
+:03008E000006D792
+:03008F0000010A63
+:0300900000002C41
+:030091000007D392
+:03009200000AB1B0
+:03009300000C500E
+:0300940000003930
+:03009500000799C8
+:03009600000A95C8
+:0300970000021252
+:0300980000003035
+:030099000002144E
+:03009A0000003132
+:03009B000002134D
+:03009C000000322F
+:03009D00000C0054
+:03009E000000332C
+:03009F00000C70E2
+:0300A00000003924
+:0300A100000C5000
+:0300A20000003922
+:0300A30000021543
+:0300A40000003029
+:0300A50000021640
+:0300A60000003126
+:0300A70000021044
+:0300A80000003223
+:0300A900000C0048
+:0300AA0000003320
+:0300AB00000C70D6
+:0300AC0000003918
+:0300AD00000C50F4
+:0300AE0000003916
+:0300AF00000C4002
+:0300B00000003914
+:0300B100000C0040
+:0300B20000003912
+:0300B300000C003E
+:0300B400000C003D
+:0300B500000A64DA
+:0300B60000036DD7
+:0300B70000020440
+:0300B800000E0334
+:0300B900000743FA
+:0300BA00000ABD7C
+:0300BB00000C0135
+:0300BC0000002D14
+:0300BD00000C0034
+:0300BE0000002916
+:0300BF0000020438
+:0300C000000D80B0
+:0300C1000000211B
+:0300C200000C62CD
+:0300C30000002218
+:0300C40000020136
+:0300C50000003206
+:0300C60000020233
+:0300C70000003105
+:0300C8000002092A
+:0300C90000003004
+:0300CA0000090129
+:0300CB0000020C24
+:0300CC0000014DE3
+:0300CD00000643E7
+:0300CE00000AD154
+:0300CF000002101C
+:0300D000000AD251
+:0300D100000C0020
+:0300D20000002506
+:0300D30000020424
+:0300D400000D809C
+:0300D50000002107
+:0300D600000C63B8
+:0300D70000002204
+:0300D80000020122
+:0300D900000032F2
+:0300DA000002021F
+:0300DB00000031F1
+:0300DC0000020916
+:0300DD00000030F0
+:0300DE0000090115
+:0300DF0000020C10
+:0300E00000014DCF
+:0300E100000643D3
+:0300E200000AE52C
+:0300E30000021008
+:0300E400000AE629
+:0300E500000C000C
+:0300E600000026F1
+:0300E700000C000A
+:0300E800000027EE
+:0300E900000C0107
+:0300EA00000145CD
+:0300EB00000643C9
+:0300EC00000B1AEC
+:0300ED00000C7094
+:0300EE000001C747
+:0300EF00000022EC
+:0300F0000002010A
+:0300F100000032DA
+:0300F20000020207
+:0300F300000031D9
+:0300F400000209FE
+:0300F500000030D8
+:0300F600000901FD
+:0300F700000C50AA
+:0300F800000039CC
+:0300F90000079964
+:0300FA00000AF900
+:0300FB00000C00F6
+:0300FC00000030D1
+:0300FD00000204FA
+:0300FE00000348B4
+:0300FF00000348B3
+:03010000000348B1
+:03010100000348B0
+:03010200000D05E8
+:03010300000031C8
+:03010400000C00EC
+:03010500000032C5
+:03010600000C00EA
+:03010700000033C2
+:03010800000C7078
+:03010900000039BA
+:03010A00000C5096
+:03010B00000039B8
+:03010C00000202EC
+:03010D00000030BF
+:03010E00000C00E2
+:03010F00000031BC
+:03011000000210DA
+:03011100000032B9
+:03011200000C00DE
+:03011300000033B6
+:03011400000C706C
+:03011500000039AE
+:03011600000C508A
+:03011700000039AC
+:03011800000C4098
+:03011900000039AA
+:03011A00000325BA
+:03011B00000C01D4
+:03011C000001E7F8
+:03011D00000C08CB
+:03011E0000008757
+:03011F0000074393
+:03012000000B23AE
+:03012100000206D3
+:03012200000025B5
+:03012300000C10BD
+:0301240000008751
+:030125000007438D
+:03012600000AE9E3
+:03012700000C01C8
+:030128000001C40F
+:03012900000E03C2
+:03012A00000024AE
+:03012B00000208C7
+:03012C0000074386
+:03012D00000B368E
+:03012E0000020BC1
+:03012F00000D8040
+:0301300000003498
+:03013100000C3A85
+:030132000002C800
+:03013300000B328C
+:0301340000020BBB
+:0301350000003493
+:03013600000A6458
+:03013700000B3783
+:00000001FF
diff --git a/kernel/xpp/firmwares/USB_FW.hex b/kernel/xpp/firmwares/USB_FW.hex
index 0d33657..37d2b0f 100644
--- a/kernel/xpp/firmwares/USB_FW.hex
+++ b/kernel/xpp/firmwares/USB_FW.hex
@@ -1,265 +1,523 @@
#
-# $Id: USB_FW.hex 6885 2009-03-16 11:52:52Z dima $
+# $Id: USB_FW.hex 7071 2009-05-12 12:33:48Z dima $
#
-:03004300020E00AA
-:03005300020E009A
-:100E0000020D2800020D8500020D6F00020D40004A
-:080E1000020BC000020B83007D
-:100700001201000200000040E4E451110000010267
-:1007100003010A0600020000004001000902370040
-:10072000020100C0000904000002FFFFFF040705EA
-:10073000020200020007058602000200090401000F
-:1007400002FFFFFF050705040200020007058802FB
-:10075000000200001201000200000040E4E4511118
-:100760000000010203010A0600020000004001002F
-:1007700009023700020100C0320904000002FFFF35
-:10078000FF04070502024000000705860240000042
-:100790000904010002FFFFFF0507050402400000F5
-:1007A000070588024000000604001600140012002D
-:1007B0000A00120004030904160358006F007200B7
-:1007C00063006F006D0020004C00540044001403CF
-:1007D00041007300740072006900620061006E00E5
-:1007E0006B001203490053004E0075006D0062005B
-:1007F000650072000A0346005000470041001203E2
-:100800004D006E0067002000500072006F00630012
-:020810000000E6
-:020E24000000CC
-:100CF0004110010041101400411000004210020098
-:010D000000F2
-:100CD000E490E670F075B5E653B5EE43B28053B2DA
-:100CE000FCC2B3C2B5C2B67F32FE120D9BD2B62291
-:100D5800538EF75389FB5389F74389015389FDE47F
-:070D6800F58AF58CD2A922E7
-:100A9E0078187C107D017BFF7A0E79247E007F0210
-:100AAE0012059890E678E0541824F0601E24087021
-:100ABE003AE4901018F07C107D187B017F50120ADA
-:100ACE00387C107D047B107F50801D901018741F91
-:100ADE00F0A374EFF07C107D187B027F51120A3860
-:0B0AEE007C107D047B107F5112060974
-:010AF90022DA
-:100C25007F03120C7DEF2402FFE43EFEE4FD740C0D
-:100C35002DF582E43410F583E0FC8F828E8375F008
-:0B0C450002ED1205FDECF00DBD08E310
-:010C50002281
-:100B4000901001EFF0E50B240AFDE4350AFC90104B
-:100B500007E02FFBA3E0FF0DED8C8370010C14F573
-:100B600082EBF08D828C83EFF0EFFFAD03ED901000
-:100B700002CFF0A3EFF0D207120BF690E680E0541C
-:020B8000F7F08C
-:010B82002250
-:1009410090E600E054E74410F090E60174C0F090A6
-:10095100E6107420F000000090E611F00000009015
-:10096100E6047480F0000000740FF0000000E4F071
-:1009710000000090E6187410F0000000E490E61901
-:10098100F000000090E61A7408F0000000E490E620
-:100991001BF000000090E6497482F0000000F000B6
-:1009A100000090E6247402F0000000E490E625F0D7
-:1009B10000000090E6957480F0000000F000000057
-:0409C10043AF01221D
-:100D9B007C007D181205EBEF1FAC0670011E4C702A
-:020DAB00F6222E
-:0A06AE008E198F1A8B1B8A1C891D00
-:1006B800E4F51EF51FC3E51F951AE51E951950337D
-:1006C800AB1BAA1CA91D851F82851E831205BEFFB0
-:1006D800E4FEC2B2EF1392B7EFC313FFD2B20EBE5D
-:1006E80008F0C2B220B002C322051FE51F70C6057C
-:0406F8001E80C2D3CB
-:0106FC0022DB
-:100D100090E60174C0F0C2B67F327E00120D9BD205
-:080D2000B67F327E00020D9B3C
-:10081200901014E0FF901000F0901002E0FCA3E0B2
-:1008220054F064607003EC641160030208B3300694
-:1008320022EFB51902D322208104E5196008208035
-:1008420007E519B40102C322E4F510901014E5196A
-:10085200F0803B30810C208009E4F510901014F0F8
-:10086200802C30800D20810AE4F51090101404F0E1
-:10087200801CE510B40117200014E4F51090101448
-:10088200E060047F0080027F01901014EFF090106E
-:1008920014E0FF901000E06F600FA3E0D3940040DB
-:1008A20008120D107F01120B40901014E024FF92E9
-:0308B200B5D32299
-:10007000E4901018F0F517F518C205E5AA5484604D
-:100080000302029F90F400E024FE70030201452465
-:10009000FA700302016924F8700302019624F070DB
-:1000A0000302019A24F070030201A924F0700302F4
-:1000B00001B424C8700302025D2477600302027257
-:1000C00075170075180490FC007401F090F401E0BD
-:1000D00090FC01F090F402E090FC02F090F401E05A
-:1000E000700AA3E0700630B003120D1020B0033088
-:1000F000B44A90E694E0FE90E695E07C002400FF90
-:10010000EC3ECF24FCCF34FFFE7B017AF47904125D
-:1001100006AE501F90FC0330B4137408F07FE87EE5
-:1001200003120D9B90E6017403F002027E7404F04A
-:1001300002027E90FC037402F002027E90FC0374C3
-:1001400001F002027E75170075180490FC0074021D
-:10015000F0E4A3F0A3F030B407A37410F002027E21
-:1001600090FC037420F002027E7517007518119040
-:10017000FC007408F0E4FF74042FF582E43410F5F9
-:1001800083E0FE74012FF582E434FCF583EEF00F7A
-:10019000BF10E402027E7F028014D206E4F5191239
-:1001A0000812120D10E4FF8005120D107F01120BD2
-:1001B0004002027E75170075180490F400E090FC70
-:1001C00000F090F401E090FC01F0E4A3F0A3F090C3
-:1001D000F401E014B40A00400302027E9001EA75C3
-:1001E000F003A4C58325F0C5837302020802021040
-:1001F00002027E02021802022002027E020226028F
-:10020000024502027E02024B90F402E0F5108047A4
-:1002100090FC02E510F08066D200A200E433803743
-:10022000A200E4338031E4F510D20690F402E0F548
-:10023000191208125007E4F517F518804190FC02D6
-:1002400074FFF08039901014E0800CA280E4332514
-:10025000E0FFA281E4334F90FC02F08021E4F51727
-:10026000F51890FC007478F0E4A3F0A3F00000000F
-:10027000800C75170075180190FC0074AAF0E51841
-:1002800045176012E51790E69CF0000000E5189015
-:0F029000E69DF000000090E6957480F0000000FD
-:01029F00223C
-:0206FD00D32206
-:080DF70090E6BAE0F522D322D8
-:100DAD0090E740E522F0E490E68AF090E68B04F0BF
-:020DBD00D3223F
-:080E180090E6BAE0F521D322B7
-:100DBF0090E740E521F0E490E68AF090E68B04F0AE
-:020DCF00D3222D
-:100CA80090E6B9E0242F600D04701990E604E0FF87
-:100CB800430780800890E604E0FF53077F000000A8
-:070CC800EFF08002D322C30C
-:010CCF002202
-:100D2800C0E0C083C082D2025391EF90E65D7401A7
-:080D3800F0D082D083D0E0323C
-:100D6F00C0E0C083C0825391EF90E65D7404F0D071
-:060D7F0082D083D0E032B7
-:100D8500C0E0C083C0825391EF90E65D7402F0D05D
-:060D950082D083D0E032A1
-:100BC000C0E0C083C08285110C85120D850D828521
-:100BD0000C83A37402F085080E85090F850F8285AA
-:100BE0000E83A37407F05391EF90E65D7410F0D07C
-:060BF00082D083D0E03248
-:100D4000C0E0C083C082D2045391EF90E65D740886
-:080D5000F0D082D083D0E03224
-:100B8300C0E0C083C08290E680E030E72085080C97
-:100B930085090D850D82850C83A37402F085110EE2
-:100BA30085120F850F82850E83A37407F05391EF8F
-:0D0BB30090E65D7420F0D082D083D0E03257
-:0A0DED0000010202030304040505DF
-:0E0D0100011000C10042101500004110170043
-:1009C500C204C201D203C202120CD0120D58120980
-:1009D50041120A9E750A07750B00751307751412E7
-:1009E50075080775091C75110775127085110E8537
-:1009F500120F7515077516B4D2E843D82090E6682E
-:100A0500E04409F090E65CE0443DF0120C257F01DE
-:100A1500120B40D2AF538EF8C204C2AF120070D28F
-:100A2500AF3002051202A0C2023004EEC204120C5D
-:030A35005180E706
-:0B0DE20090E50DE030E402C322D322B4
-:1002A00090E6B9E070030203651470030203DA24D8
-:1002B000FE700302045524FB700302035F147003F5
-:1002C00002035914700302034D14700302035324F4
-:1002D0000560030204B41206FD40030204C090E668
-:1002E000BBE024FE602714603E24FD6011146027EB
-:1002F00024067056E50A90E6B3F0E50B8042120D35
-:10030000E25044E51390E6B3F0E5148033E50C9039
-:10031000E6B3F0E50D802985110E85120FE50E90EC
-:10032000E6B3F0E50F801990E6BAE0FF120C7DAA63
-:1003300006A9077B01EA494B600DEE90E6B3F0EFAA
-:1003400090E6B4F00204C00204AF0204AF120DBF85
-:100350000204C0120E180204C0120DF70204C012EB
-:100360000DAD0204C090E6B8E0247F60151460195A
-:1003700024027063A201E43325E0FFA203E4334FBB
-:100380008041E490E740F0803F90E6BCE0547EFF7F
-:100390007E00E0D394807C0040047D0180027D00DB
-:1003A000EC4EFEED4F24EDF582740D3EF583E493A3
-:1003B000FF3395E0FEEF24A1FFEE34E68F82F58354
-:1003C000E0540190E740F0E4A3F090E68AF090E674
-:1003D0008B7402F00204C00204AF90E6B8E024FE81
-:1003E0006016240260030204C090E6BAE0B401057E
-:1003F000C2010204C00204AF90E6BAE0705590E674
-:10040000BCE0547EFF7E00E0D394807C0040047DFD
-:100410000180027D00EC4EFEED4F24EDF582740D5F
-:100420003EF583E493FF3395E0FEEF24A1FFEE3425
-:10043000E68F82F583E054FEF090E6BCE054801332
-:100440001313541FFFE0540F2F90E683F0E0442075
-:10045000F0806D805A90E6B8E024FE6019240270A6
-:100460004E90E6BAE0B40104D201805490E6BAE0BE
-:100470006402604C803990E6BCE0547EFF7E00E070
-:10048000D394807C0040047D0180027D00EC4EFE10
-:10049000ED4F24EDF582740D3EF583E493FF339523
-:1004A000E0FEEF24A1FFEE34E68F82F583800D900D
-:1004B000E6A08008120CA8500790E6A0E04401F0E6
-:0704C00090E6A0E04480F08B
-:0104C7002212
-:03003300020E209A
-:040E200053D8EF3282
-:100C510090E682E030E004E020E60B90E682E030AE
-:100C6100E119E030E71590E680E04401F07F147E61
-:0C0C710000120AFA90E680E054FEF02227
-:100BF60030070990E680E0440AF0800790E680E03E
-:100C06004408F07FDC7E05120AFA90E65D74FFF078
-:0F0C160090E65FF05391EF90E680E054F7F02204
-:060609008C178D18AE07EE
-:10060F00EB70037F012290E678E020E6F990E67820
-:10061F007480F0EE25E0440190E679F090E678E002
-:10062F0030E0F990E678E020E26BE030E167BB0163
-:10063F000790E678E04420F090E679E0F5191BEB9F
-:10064F00603090E678E030E0F990E678E020E2451F
-:10065F00BB010790E678E04420F090E679E0FF05D3
-:10066F0018E518AC177002051714F5828C83EFF09C
-:10067F0080CC90E678E030E0F990E678E020E21563
-:10068F0090E678E04440F090E679E085188285178F
-:0E069F0083F07F012290E678E04440F07F0077
-:0106AD00222A
-:100A380090E678E020E6F990E6787480F0EF25E01B
-:100A480090E679F090E678E030E0F990E678E020FA
-:100A5800E23AE030E136EBD3940040260DEDAE04E7
-:100A680070010C14F5828E83E090E679F01B90E615
-:100A780078E030E0F990E678E020E210E020E1D676
-:100A8800800A90E678E04440F07F012290E678E022
-:050A98004440F07F0066
-:010A9D002236
-:020C7D00A907C5
-:100C7F00AE15AF168F828E83A3E064037017AD019C
-:100C8F0019ED7001228F828E83E07C002FFDEC3EE8
-:080C9F00FEAF0580DFE4FEFF5B
-:010CA700222A
-:100AFA008E1A8F1B90E600E054187012E51B240131
-:100B0A00FFE4351AC313F51AEF13F51B801590E6A7
-:100B1A0000E05418FFBF100BE51B25E0F51BE51A92
-:100B2A0033F51AE51B151BAE1A7002151A4E60052D
-:060B3A00120DD180EE2235
-:100DD1007400F58690FDA57C05A3E582458370F935
-:010DE10022EF
-:030000000208B53E
-:0C08B500787FE4F6D8FD7581220208FC73
-:1004C800E709F608DFFA8046E709F208DFFA803E16
-:1004D80088828C83E709F0A3DFFA8032E309F60803
-:1004E800DFFA8078E309F208DFFA807088828C836B
-:1004F800E309F0A3DFFA806489828A83E0A3F6081F
-:10050800DFFA805889828A83E0A3F208DFFA804CF8
-:1005180080D280FA80C680D4806980F280338010CF
-:1005280080A680EA809A80A880DA80E280CA803338
-:1005380089828A83ECFAE493A3C8C582C8CCC583B0
-:10054800CCF0A3C8C582C8CCC583CCDFE9DEE78080
-:100558000D89828A83E493A3F608DFF9ECFAA9F0FF
-:10056800EDFB2289828A83ECFAE0A3C8C582C8CC55
-:10057800C583CCF0A3C8C582C8CCC583CCDFEADE6E
-:10058800E880DB89828A83E493A3F208DFF980CCD0
-:1005980088F0EF60010E4E60C388F0ED2402B404C9
-:1005A8000050B9F582EB2402B4040050AF23234570
-:0605B80082239005187378
-:1005BE00BB010CE58229F582E5833AF583E02250F2
-:1005CE0006E92582F8E622BBFE06E92582F8E2223C
-:0D05DE00E58229F582E5833AF583E4932256
-:1005EB00EF8DF0A4A8F0CF8CF0A428CE8DF0A42E24
-:0205FB00FE22DE
-:0C05FD00A42582F582E5F03583F5832209
-:1008C1000209C5E493A3F8E493A34003F68001F27F
-:1008D10008DFF48029E493A3F85407240CC8C33338
-:1008E100C4540F4420C8834004F456800146F6DF07
-:1008F100E4800B0102040810204080900CF0E47E9B
-:10090100019360BCA3FF543F30E509541FFEE493FB
-:10091100A360010ECF54C025E060A840B8E493A3C2
-:10092100FAE493A3F8E493A3C8C582C8CAC583CAED
-:10093100F0A3C8C582C8CAC583CADFE9DEE780BEA5
-:010D0F0000E3
+:03004300021B009D
+:03005300021B008D
+:101B0000021B1800021B7500021B5F00021B300045
+:081B1000021925000218AE00C5
+:100C00001201000200000040AAAAAAAAAAAA010290
+:100C100003010A060002000000400100090237003B
+:100C2000020100C0000904000002FFFFFF040705E5
+:100C3000020200020007058602000200090401000A
+:100C400002FFFFFF050705040200020007058802F6
+:100C5000000200001201000200000040E4E4511113
+:100C60000000010203010A0600020000004001002A
+:100C700009023700020100C0320904000002FFFF30
+:100C8000FF0407050202400000070586024000003D
+:100C90000904010002FFFFFF0507050402400000F0
+:100CA0000705880240000006040016001400120028
+:100CB0000A00260004030904160358006F0072009E
+:100CC00063006F006D0020004C00540044001403CA
+:100CD00041007300740072006900620061006E00E0
+:100CE0006B001203530065007200690061006C0024
+:100CF0004E006F000A0346005000470041002603E3
+:100D00004D0061006E00610067006D0065006E00BF
+:100D10007400500072006F00630065007300730080
+:060D20006F0072000000EC
+:1010800041E0300041E09C0042E097000041E03147
+:0F10900000021BE06B0218E05F43E099000000D4
+:101A45008B4E8A4F8950E5531553AE52700215528D
+:101A55004E6014AB4E0550E550AA4F7002054F1469
+:081A6500F9ED12063C80DF22BE
+:1018EB008B4E8A4F8950E5551555AE5470021554E1
+:1018FB004E6026AB510553E553AA527002055214A4
+:10190B00F91205F6FFAB4E0550E550AA4F700205D4
+:0A191B004F14F9EF12063C80CD22B4
+:10000E00E490E670F075B5E653B5EE43B28053B2A8
+:10001E00F4C2B3C2B5C2B67F32FE121AE9D2B6220C
+:101B4800538EF75389FB5389F74389015389FDE481
+:071B5800F58AF58CD2A922E9
+:101566008C428D43AA06A9077551018A5289537583
+:10157600540075551C7B017AE079321218EB90E025
+:101586004AE0FCA3E0FDA3E0FEA3E064D1FFEE6425
+:101596008DFEED644CFDEC6449FC90E04A120718A0
+:1015A6007EE07F327D1C7C00120B4C7EE07F327B1E
+:1015B6001C7A00AD43AC42120FCE7D1C7C00AF43BB
+:1015C600AE42120F077D1C7C00AF43AE4202195B90
+:08174E008E428F438C448D454F
+:10175600C208121ACABF5004D208803BE4F546F507
+:1017660047E5452547F582E5443546F583E0FFE53F
+:10177600432547F582E5423546F583E0B5070E0574
+:1017860047E547700205466410454670D4E5476450
+:091796001045467002D208A208B9
+:01179F002227
+:10137D00121ACA8F3FE4F543F544AD44AC43AF3F79
+:10138D001211D1744F2544F582E434E0F583E54024
+:10139D00F00544E54470020543C39410E5436480B1
+:1013AD00948040D67540FF75411D754219754300F7
+:1013BD00754410C3E544942CE54364809480502D0E
+:1013CD00E53FB45108AD42AC41FF1211D1744F2528
+:1013DD0044F582E434E0F583E540F00544E54470DE
+:0D13ED000205430542E54270CA054180C675
+:0113FA0022D0
+:0A163C008E428F438B448A45894695
+:101646007E00E5432DF54BEE3542F54A121ACA8F58
+:1016560047E5476451600BC3E5439410E5429400A7
+:101666005035854248854349C3E549954BE548953C
+:101676004A5024AB44AA45A946AD49AC48AF4712E7
+:1016860013FB0549E5497002054874012546F546F0
+:07169600E43545F54580D164
+:01169D00222A
+:061477008B3F8A40894111
+:10147D00D2077551017552E075534F75540075556E
+:10148D00107B017AE0797B1218EBE5412410F9E429
+:10149D003540853F51F552895375540075551C7B68
+:1014AD00017AE0798B1218EB7EE07F7B7CE07D1476
+:1014BD001215667EE07F14E541241CF9E43540FCED
+:1014CD00AD0112174E5016AB3FE5412410F9E4352E
+:1014DD0040FA7D1C7F197E1D12163C8002C207A2A8
+:0114ED0007F7
+:0114EE0022DB
+:100E38007F03121A1AEF2402FFE43EA907753F0147
+:100E4800F540894190E050E0FFE50C2408F582E484
+:100E5800350BF583EFF090E051E0FFE50C2409F540
+:100E680082E4350BF583EFF090E052E0FFE50C24C7
+:100E78000AF582E4350BF583EFF090E053E0FFE5E7
+:100E88000C240BF582E4350BF583EFF090E054E089
+:100E9800FFE50C240CF582E4350BF583EFF090E0C8
+:100EA80055E0FFE50C240DF582E4350BF583EFF0F2
+:100EB8007F087E00E4FDEDC394085028744F2FF599
+:100EC80082E434E0F583E0FCAB3FAA40A94175F029
+:100ED80002EDA4F58285F083EC12064E0D0FBF00DB
+:100EE800010E80D2E5192404F582E43518F583E073
+:0E0EF80030E0047F0180027F0090E030EFF0D8
+:010F060022C8
+:1017A000AE0790E052E02EFFE50C240AF582E43506
+:1017B0000BF583EFF0E50C240BF582E4350BF58394
+:1017C000E0FEE50C240AF582E4350BF583E0FDED3F
+:1017D000FF90E097EEF0A3EFF0D20712199190E698
+:0517E00080E054F7F069
+:0117E50022E1
+:1012F90090E600E054E74410F090E60174C0F090E5
+:10130900E6107420F000000090E611F00000009053
+:10131900E6047480F0000000740FF0000000E4F0AF
+:1013290000000090E6187410F0000000E490E6193F
+:10133900F000000090E61A7408F0000000E490E65E
+:101349001BF000000090E6497482F0000000F000F4
+:10135900000090E6247402F0000000E490E625F015
+:1013690000000090E6957480F0000000F000000095
+:0413790043AF01225B
+:061AE300D2877F0A7E009D
+:101AE9007C007D18120670EF1FAC0670011E4C7049
+:021AF900F622D3
+:0A16F7008E3F8F408B418A428943E9
+:10170100E4F544F545C3E5459540E544953F503B37
+:10171100AB41AA42A94385458285448312060FFF46
+:10172100E4FBFAC2B2EF1392B7EFC313FFD2B20BCD
+:10173100BB00010AEB64084A70E9C2B220B002C3DF
+:0C174100220545E54570BE054480BAD382
+:01174D002279
+:101A9500E4F51190E60174C0F0C2B67F967E00129F
+:0B1AA5001AE9D2B67F327E00021AE977
+:101B8B00D2B1121AE3C2B1121AE5C2877F0A7E00E4
+:031B9B00021AE942
+:02186E00AB07C6
+:10187000E4F9FAEBC413131354011392B17F027EFF
+:1018800000121AE9D2877F057E00121AE9E925E0E5
+:10189000FFA283E4334FF97F057E00121AE9EB259E
+:0D18A000E0FBC287121AE50ABA08C8AF01C2
+:0118AD002218
+:06182C008B538A5489551C
+:10183200C2AF121B8BE4F55AE55AC395595027AB38
+:1018420053AA54A955855A8275830012060FFF12B6
+:10185200186EAB56AA57A958855A82758300EF12A3
+:0B186200064E055A80D2120036D2AFAD
+:01186D002258
+:0B003600C2B1121AE5121AE3D2B12287
+:101AB000753F8F8F40755600755700755849755999
+:0A1AC000027B007A00793F02182C27
+:100A1300753F007540007541007543017544E075ED
+:100A230045007546017547E0754808E4FF7B017A88
+:100A3300E07900F552755308FD121A45AB43AA44F9
+:100A4300A945740112063CE4F54DE54DC454F0ABE1
+:100A530043AA44A94590000112064E854656854790
+:100A63005785485875590812182CAB46AA47A94808
+:100A730090000212060FFF530770EF24E060172463
+:100A8300F0601924F0601B2430702A753F0185182B
+:100A9300408519418028E5192401800AE5192402BB
+:100AA3008004E5192403FDE43518A905753F01F514
+:100AB3004089418009753F00754000754100E5405C
+:100AC3004541453F6028AB3FAA40A9411205F6FEC8
+:100AD300547FFDD3940740047C088002AC058C420C
+:100AE300EE5480FEC3ED95424E12063C800BEF7030
+:100AF300047E0180027E008E427449254DF8A64291
+:100B0300054DE54DC394045003020A4DAB43AA447B
+:100B1300A945748812063CAB43E5452401F9E43545
+:100B230044FA755100755200755349755400755553
+:100B3300041218EB8546568547578548587559085A
+:090B4300AB43AA44A94502182C99
+:10169E008F3F90E097E0FEA3E054F064607003EE9D
+:1016AE00641160037F012290E030E070037F0F220F
+:1016BE00E53F7003308108E53FB401062080037FCB
+:1016CE00102290E09CE0B53F037F0122E4F511D299
+:1016DE0007121991AF3F90E09CEFF024FF92B59066
+:0916EE00E680E054F7F07F0022D1
+:101ACA0090E678E0541824F06008240870087F50E3
+:081ADA0080067F518002E4FF49
+:011AE20022E1
+:0611D1007B007A0079406A
+:0C11D7008F458C468D478B488A49894A19
+:1011E300E4F54BF54C754D03FDF54EF54FE5452400
+:1011F300AF600D047012754B00754C017D018008C2
+:10120300754B00754C02E4FDE5456059E54C454BD3
+:101213006053E54690E099F0E547A3F0C2AF7499B7
+:101223002DF582E434E0AD82FCAB4CAF451215D60C
+:10123300754E008F4FD2AF7F0A7E001217E6E54F3F
+:10124300454E6014C2AF7CE07D4E7B01AF45121169
+:101253002C754E008F4FD2AF90E04EE0AB48AA49B9
+:09126300A94A12063CAE4EAF4F41
+:01126C00225F
+:0C13FB008F4C8C4D8D4E8B4F8A508951C9
+:10140700E4F552F553755403FDF555F556E54C24AF
+:10141700AF600D0470127552007553027D0180088C
+:10142700755200755303E4FDE54C603FE5534552A3
+:101437006039E54D90E099F0E54EA3F0AB4FAA5027
+:10144700A9511205F690E09BF0C2AF74992DF58271
+:10145700E434E0AD82FCAB53AF4C1215D6755500A2
+:0F1467008F56D2AF7F0A7E001217E6AE55AF56F2
+:011476002253
+:10005600E4F531F532F535F53AF53BF53CF53DE598
+:10006600AA548460030204FF90E694E0FE90E695AD
+:10007600E0FBEEF53AEBF53BC39405E53A94004018
+:100086000790F404E0FD80027DFFED12072400CE08
+:100096000102180502420702A10903090B011C0E01
+:1000A60000E40F018A1101AF1304712503333103F4
+:1000B600853203983403E63503FD36041A370316F2
+:1000C600450328470000047F75310075320790FC10
+:1000D600047481F0A37413F0E4A3F00204A27F0F6A
+:1000E600121AB075310075320690FC047480F0E483
+:1000F600A3F0753505F511FE74002535F9EE34F4D7
+:10010600FA7B01121477400690FC05740EF0121368
+:100116007D7F8F0202127F0E121AB0753100753282
+:1001260005121ACA8F3D90FC04748EF0121ACA8FFB
+:100136003DE53D64516019E53D645060137531003D
+:1001460075320690FC047480F0A3740BF00204A2CE
+:1001560012137D74002532F974FC3531FA7B01C027
+:10016600038B517552E075534F75540075552CD05D
+:10017600031218EB742C2532F532E43531F5317F54
+:100186008E02021275310075320790FC047491F0EC
+:1001960090E678E090FC05F030B4047F0180027FA1
+:1001A6000090FC06EFF00204A27F13121AB075311C
+:1001B6000075321D90FC047493F0121ACA8F3D75B7
+:1001C600381D753900753600753705D3E53994182D
+:1001D600E538941D5034E53DB4510E7B007A007924
+:1001E6003EAD39AC38FF1211D774002537F582744D
+:1001F600FC3536F583E53EF00539E53970020538FC
+:100206000537E53770C5053680C17F93121AB002EF
+:1002160004A275310075320690FC047480F0E4A3E4
+:10022600F090F405E090E031F0E014706530B00332
+:1002360002032D90FC057401F0020301753100756F
+:10024600320690FC047480F0E4A3F0753507AF35F0
+:10025600FEC3E53B9FF534E53A9EF53390E031E089
+:1002660014702F20B00330B42074002FF974F43EBC
+:10027600FA7B01AF34AE331216F75004E40203F6EC
+:1002860090FC05740CF00204A290FC057402F002C6
+:1002960004A290FC057403F00204A27531007532C5
+:1002A6000690FC047480F0E4A3F090E031E024FEB4
+:1002B600604904704030B43590E6017403F07F6401
+:1002C6007E00121AE912137D7EE07F4F7CE07D9D51
+:1002D6001215667EE07F9DAD1CAC1B12174E5005B5
+:1002E600120A13801690FC05740EF0800E90FC0521
+:1002F600740DF0800690FC057403F0E490E031F094
+:100306000204A2E4F531F5327F021217A00204A21C
+:1003160012137D120E38E4FF12169EE4FF1217A088
+:1003260080057F011217A0121A950204A2753100EA
+:1003360075320690FC047480F0E4A3F090F405E0B6
+:10034600F53CE4F511E53C64016004E53C7012906F
+:10035600E097E0FEA3E054F064607003EE64116081
+:1003660002807490E030E07002805A20B40990FC5C
+:1003760005740DF00204A2853C11C2010204A275A7
+:10038600310075320690FC0474B2F0A3E511F00258
+:1003960004A275310075320690FC047480F0E4A363
+:1003A600F090F405E0F53CE4F511C201AF3C1216FD
+:1003B6009EEF24F1600F1460152410701AE4F531D5
+:1003C600F5320204A290FC05740FF00204A290FC20
+:1003D600057410F00204A290FC057401F00204A258
+:1003E60075310075320690FC0474B5F090E09CE01F
+:1003F60090FC05F00204A275310075320690FC04EB
+:1004060074B6F0A280E43325E0FFA281E4334FA363
+:10041600F00204A2853A31853B3290FC0474B7F0B1
+:10042600753505C3E53B9535F534E53A9400F53366
+:1004360074002535F582E434F4F583E06488605C65
+:10044600AF357E0074002FF9EE34F4FA7B01C00359
+:10045600C00174002FF9EE34FC8B56F55789588588
+:100466003459D001D00312182C8031753100753201
+:100476000590FC0474A5F080237531007532069052
+:10048600FC047480F0C3E53B9405E53A94005006FD
+:10049600A37407F0800690FC057406F090F404E05F
+:1004A600B48004A3E0701290F404E06405600FE0E9
+:1004B6006407600AE064096005E490E031F0E53223
+:1004C6004531602CE532FD90FC00F0E531FFA3F0EC
+:1004D60090F402E090FC02F090F403E090FC03F04C
+:1004E60090E69CEFF000000090E69DEDF000000025
+:0904F60090E6957480F00000000E
+:0104FF0022DA
+:02004100D322C8
+:0800030090E6BAE0F51DD322DE
+:101B9E0090E740E51DF0E490E68AF090E68B04F0C5
+:021BAE00D32240
+:081BE20090E6BAE0F51AD322E7
+:101BB00090E740E51AF0E490E68AF090E68B04F0B6
+:021BC000D3222E
+:101A6D0090E6B9E0242F600D04701990E604E0FFB4
+:101A7D00430780800890E604E0FF53077F000000D5
+:071A8D00EFF08002D322C339
+:011A9400222F
+:101B1800C0E0C083C082D2025391EF90E65D7401A9
+:081B2800F0D082D083D0E0323E
+:101B5F00C0E0C083C0825391EF90E65D7404F0D073
+:061B6F0082D083D0E032B9
+:101B7500C0E0C083C0825391EF90E65D7402F0D05F
+:061B850082D083D0E032A3
+:10192500C0E0C083C08285120D85130E850E8285A9
+:101935000D83A37402F085090F850A108510828531
+:101945000F83A37407F05391EF90E65D7410F0D008
+:0619550082D083D0E032D5
+:101B3000C0E0C083C082D2045391EF90E65D740888
+:081B4000F0D082D083D0E03226
+:1018AE00C0E0C083C08290E680E030E72085090D5D
+:1018BE00850A0E850E82850D83A37402F085120FA4
+:1018CE00851310851082850F83A37407F05391EF53
+:0D18DE0090E65D7420F0D082D083D0E0321F
+:0F1BD300000102020303040405050300000000E3
+:08109F00011100C1010108006C
+:03000B00020D26BD
+:100D2600C0E0C0F0C083C082C0D075D000C000C093
+:0D0D360001C002C003C004C005C006C00714
+:100D430078227C007D007BFF7A1B79DD7E007F05A6
+:100D53001205D07F0590E09CE0F527C205E5086009
+:100D6300051508020E1D750805E5116401600330C1
+:100D7300012D7556007557007558228F597B007ADF
+:100D830000792212182CE5245401F528E524540295
+:100D9300700D7F011217A0121A95751100C201E59B
+:100DA3001164017029E528700E90E09CE060047FD7
+:100DB3000080157F018011A280308101B3500F3074
+:100DC30081047F0080027F018F27D205D201300585
+:100DD3004990E097E0FEA3E054F064607003EE6492
+:100DE30011703790E030E0603190E09CE06527605F
+:100DF30029E5277003308122E527B4010330801AE7
+:100E0300751100D207121991AF2790E09CEFF024DF
+:0A0E1300FF92B590E680E054F7F07E
+:100E1D00D007D006D005D004D003D002D001D00029
+:0B0E2D00D0D0D082D083D0F0D0E032D3
+:1014EF00C204C200D203C20212000E121B48121213
+:1014FF00F9C2B5750B0C750C0075140C75151275BA
+:10150F00090C750A1C75120C75137085120F851353
+:10151F001075160C7517B412137D120E38D2E843DE
+:10152F00D82090E668E04409F090E65CE0443DF096
+:10153F007F011217A0D2AFD28C538EF8C204C2AF64
+:10154F00120056D2AF3002051207EBC2023004EE82
+:07155F00C2041219EE80E73F
+:0B00460090E50DE030E402C322D3225D
+:1007EB0090E6B9E070030208B014700302092524E7
+:1007FB00FE70030209A024FB70030208AA14700305
+:10080B000208A414700302089814700302089E24B3
+:10081B000560030209FF1200414003020A0B90E638
+:10082B00BBE024FE602714603E24FD60111460279A
+:10083B0024067056E50B90E6B3F0E50C80421200EF
+:10084B00465044E51490E6B3F0E5158033E50D9082
+:10085B00E6B3F0E50E802985120F851310E50F9096
+:10086B00E6B3F0E510801990E6BAE0FF121A1AAA67
+:10087B0006A9077B01EA494B600DEE90E6B3F0EF5A
+:10088B0090E6B4F0020A0B0209FA0209FA121BB045
+:10089B00020A0B121BE2020A0B120003020A0B12D2
+:1008AB001B9E020A0B90E6B8E0247F6015146019BA
+:1008BB0024027063A200E43325E0FFA203E4334F6C
+:1008CB008041E490E740F0803F90E6BCE0547EFF2F
+:1008DB007E00E0D394807C0040047D0180027D008B
+:1008EB00EC4EFEED4F24D3F582741B3EF583E4935F
+:1008FB00FF3395E0FEEF24A1FFEE34E68F82F58304
+:10090B00E0540190E740F0E4A3F090E68AF090E623
+:10091B008B7402F0020A0B0209FA90E6B8E024FE8F
+:10092B00601624026003020A0B90E6BAE0B40105DC
+:10093B00C200020A0B0209FA90E6BAE0705590E683
+:10094B00BCE0547EFF7E00E0D394807C0040047DAD
+:10095B000180027D00EC4EFEED4F24D3F582741B1B
+:10096B003EF583E493FF3395E0FEEF24A1FFEE34D5
+:10097B00E68F82F583E054FEF090E6BCE0548013E2
+:10098B001313541FFFE0540F2F90E683F0E0442025
+:10099B00F0806D805A90E6B8E024FE601924027056
+:1009AB004E90E6BAE0B40104D200805490E6BAE06F
+:1009BB006402604C803990E6BCE0547EFF7E00E020
+:1009CB00D394807C0040047D0180027D00EC4EFEC0
+:1009DB00ED4F24D3F582741B3EF583E493FF3395DF
+:1009EB00E0FEEF24A1FFEE34E68F82F583800D90BD
+:1009FB00E6A08008121A6D500790E6A0E04401F0C3
+:070A0B0090E6A0E04480F03A
+:010A120022C1
+:0300330002002E9A
+:04002E0053D8EF3282
+:1010A7006080E0B9292E43C9A2D87C013D3654A1FE
+:1010B700ECF0061362A705F3C0C7738C98932BD97E
+:1010C700BC4C82CA1E9B573CFDD4E01667426F1882
+:1010D7008A17E512BE4EC4D6DA9EDE49A0FBF58E0E
+:1010E700BB2FEE7AA968799115B2073F94C2108990
+:1010F7000B225F21807F5D9A5A903227353ECCE7DD
+:10110700BFF79703FF1930B348A5B5D1D75E922A29
+:10111700AC56AAC64FB838D296A47DB676FC6BE219
+:041127009C7404F1BF
+:080B4C008C448D45AB07AA069D
+:100B5400E4F546F547C3E5479545E5446480F8E583
+:100B6400466480984003020BFBE54725E0FFE54619
+:100B740033FE74B92FF58274E03EF583E0FF7E0006
+:100B8400AC44AD451206828C488D49E54725E0FF0B
+:100B9400E54633FE74BA2FF58274E03EF583E0FF38
+:100BA4007E00AC44AD451206828C4A8D4BE5496506
+:100BB4004B7004E548654A6030EB2549F582EA3517
+:100BC40048F583E0F9EB254BF582EA354AF583E0F5
+:100BD400FFEB2549F582EA3548F583EFF0EB254B29
+:100BE400F582EA354AF583E9F00547E547600302F3
+:0B0BF4000B590546020B597E007F01E3
+:010BFF0022D3
+:0C0FCE008E448F458C468D478A488B4925
+:100FDA00E54545446006E54745467004E4FEFF22C0
+:100FEA00E4F54AF54BC3E54B9549E5486480F8E5D5
+:100FFA004A648098507BE4F54CF54DE547254BF55E
+:10100A0082E546354AF583E4F0C3E54D9549E5485E
+:10101A006480F8E54C6480985049E54D254B24B925
+:10102A00F582E434E0F583E0FFE545254DF582E5F8
+:10103A0044354CF583E0FEEF8EF0A4FFE547254BDF
+:10104A00F582E546354AF583E02FFFE547254BF55E
+:10105A0082E546354AF583EFF0054DE54D70AA0560
+:10106A004C80A6054BE54B6003020FEF054A020FC1
+:05107A00EF7E007F0184
+:01107F00224E
+:1019C0001205F6FF90000312060F12063C9000036A
+:1019D000EF12064E90000212060FFF900001120651
+:0E19E0000F90000212064E900001EF02064E1C
+:080F07008E448F458C468D4796
+:100F0F00E4F548F549E547AE467802CEA2E713CEA1
+:100F1F0013D8F8FFC3E5499FEE6480F8E548648075
+:100F2F00984003020FC9E549AE487802C333CE3368
+:100F3F00CED8F92545FFEE3544FAA9077B018B4A38
+:100F4F00F54B894C74BA2549F582E434E0F583E01A
+:100F5F00541FFFE48F50F54FF54EF54D1219C0ABEE
+:100F6F004AAA4BA94C1206DEC374209550F9F81209
+:100F7F0006CBC004C005C006C007A94C1206DEA9E7
+:100F8F0050A8011206B8D003D002D001D000EF4B09
+:100F9F00FFEE4AFEED49FDEC48FCAB4AAA4BA94CCB
+:100FAF001206FEAB4AAA4BA94C1219C00549E549D6
+:0E0FBF006003020F140548020F147E007F012C
+:010FCD002201
+:10195B00D3ED9410EC64809480402AED1D70011C33
+:10196B00142FF582EE3CF583E0FB547F24B9F5820E
+:10197B00E434E0F583E0F9540F2FF582E43EF58370
+:05198B00E06BF080CBD1
+:011990002234
+:1019EE0090E682E030E004E020E60B90E682E03004
+:1019FE00E119E030E71590E680E04401F07F147EB7
+:0C1A0E00001217E690E680E054FEF02283
+:1019910030070990E680E0440AF0800790E680E095
+:1019A1004408F07FDC7E051217E690E65D74FFF0D7
+:0F19B10090E65FF05391EF90E680E054F7F0225C
+:1017E6008E578F5890E600E054187012E558240181
+:1017F600FFE43557C313F557EF13F558801590E6F8
+:1018060000E05418FFBF100BE55825E0F558E557E2
+:1018160033F557E5581558AE57700215574E600503
+:06182600121BC280EE223D
+:06112C008C508D51AE074E
+:10113200EB70037F012290E678E020E6F990E678F2
+:101142007480F0EE25E0440190E679F090E678E0D4
+:1011520030E0F990E678E020E26BE030E167BB0135
+:101162000790E678E04420F090E679E0F5521BEB38
+:10117200603090E678E030E0F990E678E020E245F1
+:10118200BB010790E678E04420F090E679E0FF05A5
+:1011920051E551AC507002055014F5828C83EFF08A
+:1011A20080CC90E678E030E0F990E678E020E21535
+:1011B20090E678E04440F090E679E08551828550EF
+:0E11C20083F07F012290E678E04440F07F0049
+:0111D00022FC
+:1015D60090E678E020E6F990E6787480F0EF25E072
+:1015E60090E679F090E678E030E0F990E678E02051
+:1015F600E23AE030E136EBD3940040260DEDAE043E
+:1016060070010C14F5828E83E090E679F01B90E66B
+:1016160078E030E0F990E678E020E210E020E1D6CC
+:10162600800A90E678E04440F07F012290E678E078
+:051636004440F07F00BC
+:01163B00228C
+:021A1A00A9071A
+:101A1C00AE16AF178F828E83A3E064037017AD01EF
+:101A2C0019ED7001228F828E83E07C002FFDEC3E3D
+:081A3C00FEAF0580DFE4FEFFB0
+:011A4400227F
+:101BC2007400F58690FDA57C05A3E582458370F936
+:011BD20022F0
+:0300000002126D7C
+:0C126D00787FE4F6D8FD75815A0212B4B7
+:10050000E709F608DFFA8046E709F208DFFA803EDD
+:1005100088828C83E709F0A3DFFA8032E309F608CA
+:10052000DFFA8078E309F208DFFA807088828C8332
+:10053000E309F0A3DFFA806489828A83E0A3F608E6
+:10054000DFFA805889828A83E0A3F208DFFA804CC0
+:1005500080D280FA80C680D4806980F28033801097
+:1005600080A680EA809A80A880DA80E280CA803300
+:1005700089828A83ECFAE493A3C8C582C8CCC58378
+:10058000CCF0A3C8C582C8CCC583CCDFE9DEE78048
+:100590000D89828A83E493A3F608DFF9ECFAA9F0C7
+:1005A000EDFB2289828A83ECFAE0A3C8C582C8CC1D
+:1005B000C583CCF0A3C8C582C8CCC583CCDFEADE36
+:1005C000E880DB89828A83E493A3F208DFF980CC98
+:1005D00088F0EF60010E4E60C388F0ED2402B40491
+:1005E0000050B9F582EB2402B4040050AF23234538
+:0605F00082239005507308
+:1005F600BB010689828A83E0225002E722BBFE0203
+:09060600E32289828A83E4932235
+:10060F00BB010CE58229F582E5833AF583E02250A0
+:10061F0006E92582F8E622BBFE06E92582F8E222EA
+:0D062F00E58229F582E5833AF583E4932204
+:10063C00BB010689828A83F0225002F722BBFE019D
+:02064C00F32297
+:10064E00F8BB010DE58229F582E5833AF583E8F0E2
+:10065E00225006E92582C8F622BBFE05E92582C88E
+:02066E00F22276
+:10067000EF8DF0A4A8F0CF8CF0A428CE8DF0A42E9E
+:02068000FE2258
+:10068200C2D5EC30E709B2D5E4C39DFDE49CFCEE93
+:1006920030E715B2D5E4C39FFFE49EFE12074AC3BA
+:1006A200E49DFDE49CFC800312074A30D507C3E4B5
+:0606B2009FFFE49EFE2202
+:1006B800E8600FECC313FCED13FDEE13FEEF13FF20
+:0306C800D8F12244
+:1006CB00E8600FEFC333FFEE33FEED33FDEC33FC8D
+:0306DB00D8F12231
+:1006DE00BB010789828A830207AB5005E9F802073E
+:1006EE009FBBFE05E9F80207B789828A830207C31A
+:1006FE00BB010789828A830207185005E9F80207B1
+:0A070E00D3BBFE05E9F80207DF2265
+:0C071800ECF0A3EDF0A3EEF0A3EFF02254
+:10072400D083D082F8E4937012740193700DA3A364
+:1007340093F8740193F5828883E473740293686078
+:06074400EFA3A3A380DF78
+:101279000214EFE493A3F8E493A34003F68001F288
+:1012890008DFF48029E493A3F85407240CC8C33376
+:10129900C4540F4420C8834004F456800146F6DF45
+:1012A900E4800B0102040810204080901080E47E45
+:1012B900019360BCA3FF543F30E509541FFEE4933A
+:1012C900A360010ECF54C025E060A840B8E493A301
+:1012D900FAE493A3F8E493A3C8C582C8CAC583CA2C
+:1012E900F0A3C8C582C8CAC583CADFE9DEE780BEE4
+:01112B0000C3
+:10074A00BC000BBE0029EF8DF084FFADF022E4CC93
+:10075A00F875F008EF2FFFEE33FEEC33FCEE9DEC5C
+:10076A00984005FCEE9DFE0FD5F0E9E4CEFD22EDA2
+:10077A00F8F5F0EE8420D21CFEADF075F008EF2FEC
+:10078A00FFED33FD4007985006D5F0F222C398FDDD
+:05079A000FD5F0EA227A
+:0C079F00E6FC08E6FD08E6FE08E6FF2286
+:0C07AB00E0FCA3E0FDA3E0FEA3E0FF22C1
+:0C07B700E2FC08E2FD08E2FE08E2FF227E
+:1007C300E493FC740193FD740293FE740393FF227C
+:0C07D300ECF608EDF608EEF608EFF62252
+:0C07DF00ECF208EDF208EEF208EFF22256
:00000001FF
 \ No newline at end of file
diff --git a/kernel/xpp/init_card_1_30 b/kernel/xpp/init_card_1_30
index fafd2c1..6495f34 100755
--- a/kernel/xpp/init_card_1_30
+++ b/kernel/xpp/init_card_1_30
@@ -70,11 +70,11 @@ sub debug {
# Arrange for error logging
if (-t STDERR) {
$unit_id = 'Interactive';
- main::debug "Interactive startup";
+ debug "Interactive startup";
} else {
$unit_id = "$ENV{XBUS_NAME}/UNIT-$ENV{UNIT_NUMBER}";
open (STDERR, "| logger -t $program -p kern.info") || die;
- main::debug "Non Interactive startup";
+ debug "Non Interactive startup";
foreach my $k (qw(
XBUS_NAME
XBUS_NUMBER
@@ -148,28 +148,45 @@ sub read_reg($$$) {
write_to_slic_file(
sprintf("%s R%s %02X", $read_slic, $direct, $read_reg));
- main::mysleep(0.005);
- open(SLICS,$chipregs) or
- die("Failed reading from chipregs file $chipregs");
- #awk '/^SLIC_REPLY:/{print $5}' $SLICS | cut -dx -f2
- my @reply = ();
- while(<SLICS>){
- #if (/^ /) {
- # main::debug "answer line: $_";
- #}
- s/#.*//;
- next unless /\S/;
- if (/^ \d*\s+[RW][DI]\s+[[:xdigit:]]+\s+([[:xdigit:]]+)\s+([[:xdigit:]]*)/){
- @reply = (hex($1), hex($2));
- #main::debug "got [$reply]";
- last;
- } else {
- main::logit("Got from '$chipregs' a non-matching line '$_'");
+ my $retries = 10;
+ my @reply;
+ # If the command queue is long, we may need to wait...
+WAIT_RESULTS:
+ {
+ my @results;
+
+ # The time to sleep is a tradeoff:
+ # - Too long is a waste of time.
+ # - Too short will cause many retries, wastes time.
+ # So the current value (after trial and error) is...
+ main::mysleep(0.013);
+ open(SLICS,$chipregs) or
+ die("Failed reading from chipregs file $chipregs");
+ while(<SLICS>){
+ s/#.*//;
+ next unless /\S/;
+ @results = /^\s*(\d+)\s+[RW][DI]\s+([[:xdigit:]]+)\s+([[:xdigit:]]+)\s+([[:xdigit:]]*)/;
+ if(@results != 4) {
+ main::logit "Failed reading from '$chipregs' ($read_slic,$read_reg,$direct)";
+ die;
+ }
+ }
+ close(SLICS);
+ my $reg = hex($results[1]);
+ if($results[0] ne $read_slic || $reg ne $read_reg) {
+ # We read obsolete values, need to wait some more
+ if(--$retries) {
+ main::debug "$read_slic RD $read_reg -- retry ($results[0], $reg)";
+ redo WAIT_RESULTS;
+ } else {
+ main::logit "Failed: $read_slic RD $read_reg returned $results[0], $reg";
+ die;
+ }
}
+ # Good.
+ @reply = (hex($results[2]), hex($results[3]));
+
}
- close(SLICS);
- die("Failed reading from '$chipregs' ($read_slic,$read_reg,$direct)")
- unless @reply;
if ($direct eq 'S') {
return @reply;
} else {
@@ -230,8 +247,8 @@ sub init_indirect_registers() {
* WS 1E 12 00 00
* WS 1E 13 00 00
-* WS 1E 14 F0 7E
-* WS 1E 15 C0 01
+* WS 1E 14 FD 7E
+* WS 1E 15 77 01
* WS 1E 16 00 00
* WS 1E 17 00 20
@@ -246,23 +263,17 @@ sub init_indirect_registers() {
* WS 1E 1F 00 02
* WS 1E 20 C0 07
-* WS 1E 21 00 26
-* WS 1E 22 F4 0F
+* WS 1E 21 6F 37
+* WS 1E 22 80 1B
* WS 1E 23 00 80
-
-#* WS 1E 24 20 03
-#* WS 1E 25 8C 08
-#* WS 1E 26 00 01
-#* WS 1E 27 10 00
* WS 1E 24 00 08
* WS 1E 25 00 08
* WS 1E 26 00 08
* WS 1E 27 00 08
-* WS 1E 28 00 0C
-* WS 1E 29 00 0C
-* WS 1E 2B 00 01
+* WS 1E 28 00 00
+* WS 1E 2B 00 08 # LCRTL = 5.08 mA
* WS 1E 63 DA 00
* WS 1E 64 60 6B
@@ -277,7 +288,8 @@ sub init_indirect_registers() {
sub init_early_direct_regs() {
return write_to_slic_file("#
* WD 08 00 # Audio Path Loopback Control
-* WD 4A 34 # High Battery Voltage
+* WD 6C 01
+* WD 4A 3F # High Battery Voltage
* WD 4B 10 # Low Battery Voltage
* WD 40 00 # Line Feed Control
#")
@@ -310,35 +322,36 @@ my $ManualCalibrationSleepTime = 0.04; # 40ms
sub manual_calibrate_loop($$) {
my $write_reg = shift;
my $read_reg = shift;
-
- # counters to count down to (at most) 0
- my @slic_counters = ();
- for my $i (0 .. $#SlicNums) {
- $slic_counters[$i] = 0x1F;
- }
-
- # start calibration:
- my $calibration_in_progress = 1;
- write_reg('*', $write_reg, 'D', 0x1F);
- main::mysleep $ManualCalibrationSleepTime;
-
+ my @curr_slics = @SlicNums;
+
+ # initialize counters
+ my @slic_counters = map { 0x1F } @curr_slics;
+
# wait until all slics have finished calibration, or for timeout
- while ($calibration_in_progress) {
- $calibration_in_progress = 0; # until proven otherwise
+ while (@curr_slics) {
my $debug_calib_str = "ManualCalib:: ";
- for my $slic(@SlicNums) {
+ my @next_slics;
+
+ for my $slic (@curr_slics) {
+ write_reg($slic,$write_reg,'D',$slic_counters[$slic]);
+ }
+ main::mysleep $ManualCalibrationSleepTime;
+ for my $slic (@curr_slics) {
my $value = read_reg($slic, $read_reg, 'D');
- $debug_calib_str .= " [$slic_counters[$slic]:$value]";
- if ($value != 0 && $slic_counters[$slic] > 0) {
- $calibration_in_progress = 1;
+ $debug_calib_str .= sprintf " [%d:%d:%X]",
+ $slic, $slic_counters[$slic], $value;
+ next if $value == 0; # This one is calibrated.
+ if ($slic_counters[$slic] > 0) {
$slic_counters[$slic]--;
- write_reg($slic,$write_reg,'D',$slic_counters[$slic]);
+ push(@next_slics, $slic);
+ } else {
+ main::logit("ERROR: SLIC $slic reached 0 during manual calibration");
}
}
+ @curr_slics = @next_slics;
main::debug($debug_calib_str);
- # TODO: unnecessary sleep in the last round:
- main::mysleep $ManualCalibrationSleepTime;
}
+ main::debug("No more slics to calibrate");
}
sub manual_calibrate() {
@@ -352,47 +365,52 @@ sub auto_calibrate($$) {
#log_calib_params();
# start calibration:
- write_to_slic_file(
- sprintf
- "* WD 60 %02X\n".
- "* WD 61 %02X\n".
- "", $calib_96, $calib_97
-
- );
+ for my $slic(@SlicNums) {
+ write_to_slic_file(
+ sprintf
+ "$slic WD 61 %02X\n".
+ "$slic WD 60 %02X\n".
+ "", $calib_97, $calib_96
+
+ );
+ }
+
# wait until all slics have finished calibration, or for timeout
- my $sleep_cnt = 0;
# time periods in seconds:
- my $sleep_time = 0.1;
- my $timeout_time = 2;
- CALIB_LOOP: for my $slic (@SlicNums) {
- main::debug("checking slic $slic");
- while(1) {
- if ((read_reg($slic, 60, 'D')) == 0) {
- # move to next register
- main::debug("slic $slic calibrated");
- last;
- }
- if ( $sleep_cnt > $timeout_time/$sleep_time) {
- main::debug("Auto Calibration: Exiting on timeout: $timeout_time.");
- last CALIB_LOOP;
- }
- main::debug("auto_calibrate not done yet: slic #$slic");
- main::mysleep(0.1);
- $sleep_cnt++;
+ my $sleep_time = 0.001;
+ my $timeout_time = 0.600; # Maximum from the spec
+ my @curr_slics = @SlicNums;
+ my $sleep_cnt = 0;
+CALIB_LOOP:
+ while(1) {
+ main::mysleep($sleep_time);
+ my @next_slics;
+ for my $slic (@curr_slics) {
+ main::debug("checking slic $slic");
+ my $val = read_reg($slic, 96, 'D');
+ push(@next_slics, $slic) if $val != 0;
}
+ @curr_slics = @next_slics;
+ last unless @curr_slics;
+ if ($sleep_cnt * $sleep_time > $timeout_time) {
+ main::logit("Auto Calibration: Exiting on timeout: $timeout_time.");
+ last CALIB_LOOP;
+ }
+ main::debug("auto_calibrate not done yet($sleep_cnt): @curr_slics");
+ $sleep_cnt++;
}
#log_calib_params();
}
sub calibrate_slics() {
- main::logit "Calibrating '$0'";
- auto_calibrate(0x47, 0x1E);
+ main::debug "Calibrating '$0'";
+ auto_calibrate(0x40, 0x1E);
main::debug "after auto_calibrate";
manual_calibrate();
main::debug "after manul_calibrate";
auto_calibrate(0x40, 0x01);
main::debug "after auto_calibrate 2";
- main::logit "Continue '$0'";
+ main::debug "Continue '$0'";
}
sub read_defaults() {
@@ -403,11 +421,23 @@ sub read_defaults() {
}
}
+# Try to identify which slics are valid
+sub check_slics() {
+ my @slics;
+ foreach my $slic (0 .. 7) {
+ my $value = read_reg($slic, 0, 'D');
+ push(@slics, $slic) if $value != 0xFF;
+ }
+ main::logit "Found " . scalar(@slics) . " SLICS (@slics)";
+ return @slics;
+}
+
package main;
-main::logit "Starting '$0'";
+main::debug "Starting '$0'";
FXS::read_defaults;
+@SlicNums = FXS::check_slics;
main::debug "before init_indirect_registers";
FXS::init_indirect_registers();
main::debug "after init_indirect_registers";
@@ -431,15 +461,13 @@ while(<DATA>) {
}
close REG;
-main::logit "Ending '$0'";
+main::debug "Ending '$0'";
close STDERR;
exit 0;
# ----------------------------------==== 8-channel FXS unit initialization ===-----------------------------------------
__DATA__
-# Change SLICs states to "Open state"s (Off,all transfers tristated to avoid data collision), Voltage sense
-* WD 40 00
# Flush out energy accumulators
* WS 1E 58 00 00
@@ -450,8 +478,9 @@ __DATA__
* WS 1E 5D 00 00
* WS 1E 5E 00 00
* WS 1E 5F 00 00
+
* WS 1E 61 00 00
-* WS 1E 58 00 00
+
* WS 1E C1 00 00
* WS 1E C2 00 00
* WS 1E C3 00 00
@@ -471,31 +500,63 @@ __DATA__
* WS 1E D1 00 00
* WS 1E D2 00 00
* WS 1E D3 00 00
+
+# Clear and disable interrupts
+* WD 12 FF
+* WD 13 FF
+* WD 14 FF
+* WD 15 00
+* WD 16 00
+* WD 17 00
+## Mode(8-bit,u-Law,1 PCLK )
+* WD 01 08 # Disable PCM transfers
+
# Setting of SLICs offsets
# New card initialization
+
+* WD 03 00
+* WD 05 00
+
0 WD 02 00
0 WD 04 00
+0 WD 01 28 # Enable PCM transfers
1 WD 02 08
1 WD 04 08
+1 WD 01 28
2 WD 02 10
2 WD 04 10
+2 WD 01 28
3 WD 02 18
3 WD 04 18
+3 WD 01 28
4 WD 02 20
4 WD 04 20
+4 WD 01 28
5 WD 02 28
5 WD 04 28
+5 WD 01 28
6 WD 02 30
6 WD 04 30
+6 WD 01 28
7 WD 02 38
7 WD 04 38
-* WD 03 00
-* WD 05 00
+7 WD 01 28
# Audio path. (also initialize 0A and 0B here if necessary)
* WD 08 00
* WD 09 00
+* WD 0A 08
+* WD 0B 33
+
+#------ Metering tone
+* WD 2C 00 # Timer dL
+* WD 2D 03 # Timer dH
+* WS 1E 17 61 15 # Amplitue Ramp-up
+* WS 1E 18 61 15 # Max Amplitude
+* WS 1E 19 FB 30 # Frequency
+
+# Ring regs are set by driver
# Automatic/Manual Control: defaults but:
# Cancel AOPN - Power Alarm
@@ -514,39 +575,16 @@ __DATA__
# Loop Current Limit
* WD 47 00
-# Ring VBath:
-* WD 4A 3F
-
+# On-Hook Line Voltage (VOC)
+* WD 48 20
-* WD 6C 01
+# Common Mode Voltage (VCM)
+* WD 49 03
* WS 1E 23 00 80
* WS 1E 24 20 03
-* WS 1E 25 8C 08
-* WS 1E 26 00 01
+* WS 1E 25 8C 00
+* WS 1E 26 00 00
* WS 1E 27 10 00
-#------ Metering tone
-* WS 1E 17 61 15 # Amplitue Ramp-up
-* WS 1E 18 61 15 # Max Amplitude
-* WS 1E 19 FB 30 # Frequency
-* WD 2C 00 # Timer dL
-* WD 2D 03 # Timer dH
-
-# ------------------------------------- Initialization of direct registers --------------------------------------------
-
-# Mode(8-bit,u-Law,1 PCLK ) setting, Loopbacks and Interrupts clear
-
-* WD 01 29
-#* WD 0E 00
-
-#* WD 15 00
-#* WD 16 03
-
-# Clear pending interrupts
-* WD 12 FF
-* WD 13 FF
-* WD 14 FF
-
-#* WD 4A 34
-#* WD 4B 10
+* WD 0E 00
diff --git a/kernel/xpp/init_card_2_30 b/kernel/xpp/init_card_2_30
index 34f8a0b..efc19a9 100755
--- a/kernel/xpp/init_card_2_30
+++ b/kernel/xpp/init_card_2_30
@@ -69,11 +69,11 @@ sub debug {
# Arrange for error logging
if (-t STDERR || $opts{v}) {
$unit_id = 'Interactive';
- main::debug "Interactive startup";
+ debug "Interactive startup";
} else {
$unit_id = "$ENV{XBUS_NAME}/UNIT-$ENV{UNIT_NUMBER}";
open (STDERR, "| logger -t $program -p kern.info") || die;
- main::debug "Non Interactive startup";
+ debug "Non Interactive startup";
foreach my $k (qw(
XBUS_NAME
XBUS_NUMBER
@@ -365,7 +365,7 @@ if($opts{v}) {
exit 0;
}
-main::logit "Starting";
+main::debug "Starting";
FXO::read_defaults;
die "OPERMODE is undefined" unless $OPERMODE;
@@ -384,56 +384,51 @@ while(<DATA>) {
FXO::opermode_setup;
close REG;
-main::logit "Ending '$0'";
+main::debug "Ending '$0'";
close STDERR;
exit 0;
__DATA__
-* WD 21 28
+* WD 21 08 # Disable PCM transfers
* WD 18 99
* WD 06 00
# ----------- DAA PCM start offset ----------
+* WD 23 00
+* WD 25 00
+
0 WD 22 00
-0 WD 23 00
0 WD 24 00
-0 WD 25 00
+0 WD 21 28 # Enable PCM transfers, when offsets are set
1 WD 22 08
-1 WD 23 00
1 WD 24 08
-1 WD 25 00
+1 WD 21 28
2 WD 22 10
-2 WD 23 00
2 WD 24 10
-2 WD 25 00
+2 WD 21 28
3 WD 22 18
-3 WD 23 00
3 WD 24 18
-3 WD 25 00
+3 WD 21 28
4 WD 22 20
-4 WD 23 00
4 WD 24 20
-4 WD 25 00
+4 WD 21 28
5 WD 22 28
-5 WD 23 00
5 WD 24 28
-5 WD 25 00
+5 WD 21 28
6 WD 22 30
-6 WD 23 00
6 WD 24 30
-6 WD 25 00
+6 WD 21 28
7 WD 22 38
-7 WD 23 00
7 WD 24 38
-7 WD 25 00
+7 WD 21 28
# ----------- DAA ONHOOK --------------------
* WD 05 00
diff --git a/kernel/xpp/init_card_3_30 b/kernel/xpp/init_card_3_30
index 9e72089..7796b2e 100755
--- a/kernel/xpp/init_card_3_30
+++ b/kernel/xpp/init_card_3_30
@@ -67,18 +67,24 @@ my %opts;
getopts('o:', \%opts);
+my %settings;
+
sub logit {
print STDERR "$unit_id: @_\n";
}
+sub debug {
+ logit @_ if $settings{debug};
+}
+
# Arrange for error logging
if (-t STDERR) {
$unit_id = 'Interactive';
- logit "Interactive startup";
+ debug "Interactive startup";
} else {
$unit_id = "$ENV{XBUS_NAME}/UNIT-$ENV{UNIT_NUMBER}";
open (STDERR, "| logger -t $program -p kern.info") || die;
- logit "Non Interactive startup";
+ debug "Non Interactive startup";
foreach my $k (qw(
XBUS_NAME
XBUS_NUMBER
@@ -138,6 +144,14 @@ sub multibyte($) {
}
}
+sub read_defaults() {
+ if(XppConfig::read_config(\%settings)) {
+ main::logit "Defaults from $settings{xppconf}";
+ } else {
+ main::logit "No defaults file, use hard-coded defaults.";
+ }
+}
+
package BRI::Port;
sub new {
@@ -362,14 +376,16 @@ sub zthfc_startup {
package main;
-logit "Starting '$0'";
+debug "Starting '$0'";
+
+BRI::read_defaults;
#------------------------------------------- Instance detection
# zap_xhfc_su.c:895
sub init_xhfc($) {
my $portnum = shift;
- main::logit "init_xhfc($portnum)";
+ main::debug "init_xhfc($portnum)";
BRI::gen "#--------------------------- init_xhfc";
BRI::gen "$portnum WD 0D 00"; # r_FIFO_MD: 16 fifos,
# 64 bytes for TX and RX each (FIFO mode config)
@@ -452,7 +468,7 @@ sub main() {
main;
-logit "Ending '$0'";
+debug "Ending '$0'";
close REG;
close STDERR;
diff --git a/kernel/xpp/init_card_4_30 b/kernel/xpp/init_card_4_30
index 6d56398..ea04545 100755
--- a/kernel/xpp/init_card_4_30
+++ b/kernel/xpp/init_card_4_30
@@ -71,14 +71,18 @@ sub logit {
print STDERR "$unit_id: @_\n";
}
+sub debug {
+ logit @_ if $settings{debug};
+}
+
# Arrange for error logging
if (-t STDERR) {
$unit_id = 'Interactive';
- logit "Interactive startup";
+ debug "Interactive startup";
} else {
$unit_id = "$ENV{XBUS_NAME}/UNIT-$ENV{UNIT_NUMBER}";
open (STDERR, "| logger -t $program -p kern.info") || die;
- logit "Non Interactive startup";
+ debug "Non Interactive startup";
foreach my $k (qw(
XBUS_NAME
XBUS_NUMBER
@@ -226,7 +230,7 @@ sub write_pri_info {
print INFO "$pri_protocol\n" || die "Failed writing '$pri_protocol' to '$file': $!\n";
close INFO || die "Failed during close of '$file': $!\n";
} else {
- main::logit "$xpd_name: Skip setting pri protocol -- non given";
+ main::logit "$xpd_name: pri_protocol not given. Driver will use defaults.";
}
}
@@ -359,7 +363,7 @@ sub port_setup($) {
package main;
-logit "Starting '$0'";
+main::debug "Starting '$0'";
PRI::read_defaults;
@@ -367,11 +371,11 @@ sub main() {
my @ports;
my $subunit;
- logit "main(): Initializing chip ($ENV{UNIT_SUBUNITS} ports)";
+ main::debug "main(): Initializing chip ($ENV{UNIT_SUBUNITS} ports)";
PRI::init_quad;
# Must initialize all 4 ports, regardless how much there are
for($subunit = 0; $subunit < 4; $subunit++) {
- #logit "main(): Initializing subunit $subunit";
+ #main::debug "main(): Initializing subunit $subunit";
my $p = PRI::Port->new(
'PORT_NUM' => $subunit,
'EXIST' => ($subunit < $ENV{UNIT_SUBUNITS})
@@ -389,7 +393,7 @@ sub main() {
main;
-logit "Ending '$0'";
+main::debug "Ending '$0'";
close REG;
close STDERR;
diff --git a/kernel/xpp/utils/Makefile b/kernel/xpp/utils/Makefile
index b88bb75..a2c2e71 100644
--- a/kernel/xpp/utils/Makefile
+++ b/kernel/xpp/utils/Makefile
@@ -65,13 +65,20 @@ PERL_SCRIPTS = \
PERL_MANS = $(PERL_SCRIPTS:%=%.8)
-TARGETS = init_fxo_modes print_modes perlcheck
+ABHEXLOAD_OBJS = astribank_hexload.o hexfile.o pic_loader.o astribank_usb.o mpp_funcs.o debug.o
+ABTOOL_OBJS = astribank_tool.o astribank_usb.o mpp_funcs.o debug.o
+ABALLOW_OBJS = astribank_allow.o astribank_usb.o mpp_funcs.o debug.o
+
+TARGETS = init_fxo_modes print_modes .perlcheck
PROG_INSTALL = genzaptelconf
MAN_INSTALL = $(PROG_INSTALL:%=%.8)
ifeq (1,$(PBX_LIBUSB))
TARGETS += fpga_load \
+ astribank_tool \
+ astribank_hexload \
+ astribank_allow \
test_parse
-PROG_INSTALL += fpga_load
+PROG_INSTALL += fpga_load astribank_tool astribank_hexload
endif
ifneq (,$(PERLLIBDIR))
PROG_INSTALL += $(PERL_SCRIPTS)
@@ -111,6 +118,15 @@ endif
fpga_load: fpga_load.o hexfile.o
$(CC) -L. -o $@ $^ $(EXTRA_LIBS) -lusb
+astribank_hexload: $(ABHEXLOAD_OBJS)
+ $(CC) -L. -o $@ $(ABHEXLOAD_OBJS) $(EXTRA_LIBS) -lusb
+
+astribank_tool: $(ABTOOL_OBJS)
+ $(CC) -L. -o $@ $(ABTOOL_OBJS) $(EXTRA_LIBS) -lusb
+
+astribank_allow: $(ABALLOW_OBJS)
+ $(CC) -L. -o $@ $(ABALLOW_OBJS) $(EXTRA_LIBS) -lusb
+
fpga_load.o: CFLAGS+=-D_GNU_SOURCE # We use memrchr()
test_parse: test_parse.o hexfile.o
@@ -127,12 +143,12 @@ wctdm_fxomodes.h: $(WCTDM)
init_fxo_modes: print_modes
./$< >$@
-perlcheck: $(PERL_SCRIPTS)
+.perlcheck: $(PERL_SCRIPTS)
for i in $^; do perl -I./zconf -c $$i || exit 1; done
touch $@
clean:
- $(RM) .depend *.o $(TARGETS) wctdm_fxomodes.h
+ $(RM) .depend *.o $(TARGETS)
.PHONY: depend
depend: .depend
diff --git a/kernel/xpp/utils/astribank_allow.c b/kernel/xpp/utils/astribank_allow.c
new file mode 100644
index 0000000..ec60d4a
--- /dev/null
+++ b/kernel/xpp/utils/astribank_allow.c
@@ -0,0 +1,378 @@
+/*
+ * Written by Oron Peled <oron@actcom.co.il> and
+ * Alex Landau <alex.landau@xorcom.com>
+ * Copyright (C) 2008, 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <getopt.h>
+#include <time.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include "mpp.h"
+#include "mpp_funcs.h"
+#include "debug.h"
+
+static const char rcsid[] = "$Id$";
+
+#define DBG_MASK 0x80
+
+static char *progname;
+
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [options...] -D {/proc/bus/usb|/dev/bus/usb}/<bus>/<dev> options\n", progname);
+ fprintf(stderr, "\tOptions:\n");
+ fprintf(stderr, "\t\t[-v] # Increase verbosity\n");
+ fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n");
+ fprintf(stderr, "\t\t[-w] # Write capabilities to EEPROM, otherwise read capabilities\n");
+ fprintf(stderr, "\t\t[-f filename] # License filename (stdin/stdout if not specified)\n\n");
+ exit(1);
+}
+
+static int capabilities_burn(
+ struct astribank_device *astribank,
+ struct eeprom_table *eeprom_table,
+ struct capabilities *capabilities,
+ struct capkey *key)
+{
+ int ret;
+
+ INFO("Burning capabilities\n");
+ ret = mpp_caps_set(astribank, eeprom_table, capabilities, key);
+ if(ret < 0) {
+ ERR("Capabilities burning failed: %d\n", ret);
+ return ret;
+ }
+ INFO("Done\n");
+ return 0;
+}
+
+static int bin_to_file(void *buf, int len, FILE *f)
+{
+ static int bytes_on_line;
+ unsigned char *p = buf;
+ if (buf == NULL) {
+ if (bytes_on_line != 0) {
+ if (fprintf(f, "\n") != 1)
+ return -1;
+ bytes_on_line = 0;
+ }
+ return 0;
+ }
+ int i;
+ for (i = 0; i < len; i++) {
+ if (fprintf(f, "%02x", *p++) != 2)
+ return -1;
+ bytes_on_line++;
+ if (bytes_on_line >= 16) {
+ if (fprintf(f, "\n") != 1)
+ return -1;
+ bytes_on_line = 0;
+ }
+ }
+ return 0;
+}
+
+static int write_to_file(struct eeprom_table *eeprom_table, struct capabilities *caps, struct capkey *key, FILE *f)
+{
+ fprintf(f, "-----BEGIN XORCOM LICENSE BLOCK-----\n");
+ fprintf(f, "Version: 1.0\n");
+ fprintf(f, "Timestamp: %u\n", caps->timestamp);
+ fprintf(f, "Serial: %.*s\n", LABEL_SIZE, eeprom_table->label);
+ fprintf(f, "Capabilities.Port.FXS: %d\n", caps->ports_fxs);
+ fprintf(f, "Capabilities.Port.FXO: %d\n", caps->ports_fxo);
+ fprintf(f, "Capabilities.Port.BRI: %d\n", caps->ports_bri);
+ fprintf(f, "Capabilities.Port.PRI: %d\n", caps->ports_pri);
+ fprintf(f, "Capabilities.Twinstar: %d\n", CAP_EXTRA_TWINSTAR(caps));
+ fprintf(f, "Data:\n");
+ bin_to_file(eeprom_table, sizeof(*eeprom_table), f);
+ bin_to_file(caps, sizeof(*caps), f);
+ bin_to_file(key, sizeof(*key), f);
+ bin_to_file(NULL, 0, f);
+ fprintf(f, "-----END XORCOM LICENSE BLOCK-----\n");
+ return 0;
+}
+
+/*
+ * Removes whitespace on both sizes of the string.
+ * Returns a pointer to the first non-space char. The string
+ * is modified in place to trim trailing whitespace.
+ * If the whole string is whitespace, returns NULL.
+ */
+char *trim(char *s)
+{
+ int len = strlen(s);
+ while (len > 0 && isspace(s[len-1])) {
+ len--;
+ }
+ if (len == 0)
+ return NULL;
+ s[len] = '\0';
+ while (isspace(*s))
+ s++;
+ /* *s is not a space, since in this case we'd return NULL above */
+ return s;
+}
+
+int get_key_value(char *line, char **key, char **value)
+{
+ char *p = strchr(line, ':');
+ if (p == NULL)
+ return -1;
+ *p = '\0';
+ *key = trim(line);
+ *value = trim(p + 1);
+ return 0;
+}
+
+static int hex_digit_to_int(char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ else if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ else
+ return -1;
+}
+
+static int str_to_bin(char *line, void *buf, int maxlen)
+{
+ static int offset;
+ unsigned char *p = buf;
+ if (strlen(line) % 2 != 0)
+ return -1;
+ while (offset < maxlen && *line) {
+ uint8_t value;
+ char c = hex_digit_to_int(*line++);
+ if (c < 0 || *line == '\0')
+ return -1;
+ value = c << 4;
+ c = hex_digit_to_int(*line++);
+ if (c < 0)
+ return -1;
+ value |= c;
+ p[offset++] = value;
+ }
+ if (offset == maxlen && *line)
+ return -1;
+ return offset;
+}
+
+static int read_from_file(struct eeprom_table *eeprom_table, struct capabilities *caps, struct capkey *capkey, FILE *f)
+{
+ char buf[256];
+ char *line, *key, *value;
+ int state = 0;
+ int lineno = 0;
+ struct table {
+ struct eeprom_table eeprom_table;
+ struct capabilities capabilities;
+ struct capkey capkey;
+ } PACKED table;
+
+ memset(&table, 0, sizeof(struct table));
+ /*
+ * states:
+ * 0: start - before BEGIN_LICENSE_BLOCK line. on BEGIN_LICENSE_BLOCK line goto 1.
+ * 1: read Version, goto 2. if not version line then error.
+ * 2: after BEGIN line. split line into key:value. if line is Data:, goto 3.
+ * 3: read binary data. if line is END_LICENSE_BLOCK goto 4.
+ * 4: END_LICENSE_BLOCK - if not EOF - error. otherwise exit loop and success.
+ */
+ while (fgets(buf, 256, f) != NULL) {
+ lineno++;
+ int len = strlen(buf);
+ if (len > 0 && buf[len-1] != '\n') {
+ ERR("Line %d: Line too long\n", lineno);
+ return -1;
+ }
+ line = trim(buf);
+ if (line == NULL) {
+ ERR("Line %d: Empty line\n", lineno);
+ }
+ switch (state) {
+ case 0:
+ if (strcmp(line, "-----BEGIN XORCOM LICENSE BLOCK-----") == 0)
+ state = 1;
+ else {
+ ERR("Line %d: Invalid license begin block\n", lineno);
+ return -1;
+ }
+ break;
+ case 1:
+ if (get_key_value(line, &key, &value) < 0) {
+ ERR("Line %d: Can't parse line\n", lineno);
+ return -1;
+ }
+ if (strcmp(key, "Version") == 0) {
+ if (strcmp(value, "1.0") == 0) {
+ state = 2;
+ } else {
+ ERR("Line %d: Unknown license file version '%s', need version '1.0'\n", lineno, value);
+ return -1;
+ }
+ } else {
+ ERR("Line %d: No license file version\n", lineno);
+ return -1;
+ }
+ break;
+ case 2:
+ if (get_key_value(line, &key, &value) < 0) {
+ ERR("Line %d: Can't parse line\n", lineno);
+ return -1;
+ }
+ if (strcmp(key, "Data") == 0) {
+ state = 3;
+ break;
+ }
+ break;
+ case 3:
+ if (strcmp(line, "-----END XORCOM LICENSE BLOCK-----") == 0) {
+ state = 4;
+ break;
+ }
+ if (str_to_bin(line, &table, sizeof(table)) < 0) {
+ ERR("Line %d: Error in data block\n", lineno);
+ return -1;
+ }
+ break;
+ case 4:
+ ERR("Extra data after license end block\n");
+ return -1;
+ }
+ }
+ if (state != 4) {
+ ERR("Invalid license file\n");
+ return -1;
+ }
+ memcpy(eeprom_table, &table.eeprom_table, sizeof(*eeprom_table));
+ memcpy(caps, &table.capabilities, sizeof(*caps));
+ memcpy(capkey, &table.capkey, sizeof(*capkey));
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ char *devpath = NULL;
+ struct astribank_device *astribank;
+ struct eeprom_table eeprom_table;
+ struct capabilities caps;
+ struct capkey key;
+ const char options[] = "vd:D:wf:";
+ int do_write = 0;
+ FILE *file;
+ char *filename = NULL;
+ int ret;
+
+ progname = argv[0];
+ while (1) {
+ int c;
+
+ c = getopt (argc, argv, options);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'D':
+ devpath = optarg;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'd':
+ debug_mask = strtoul(optarg, NULL, 0);
+ break;
+ case 'w':
+ do_write = 1;
+ break;
+ case 'f':
+ filename = optarg;
+ break;
+ case 'h':
+ default:
+ ERR("Unknown option '%c'\n", c);
+ usage();
+ }
+ }
+ if(!devpath) {
+ ERR("Missing device path\n");
+ usage();
+ }
+ DBG("Startup %s\n", devpath);
+ if((astribank = mpp_init(devpath)) == NULL) {
+ ERR("Failed initializing MPP\n");
+ return 1;
+ }
+ if(astribank->eeprom_type != EEPROM_TYPE_LARGE) {
+ ERR("Cannot use this program with astribank EEPROM type %d (need %d)\n",
+ astribank->eeprom_type, EEPROM_TYPE_LARGE);
+ return 1;
+ }
+ ret = mpp_caps_get(astribank, &eeprom_table, &caps, &key);
+ if(ret < 0) {
+ ERR("Failed to get original capabilities: %d\n", ret);
+ return 1;
+ }
+ if (do_write) {
+ /* update capabilities based on input file */
+ file = stdin;
+ if (filename) {
+ file = fopen(filename, "r");
+ if (file == NULL) {
+ ERR("Can't open file '%s'\n", filename);
+ return 1;
+ }
+ }
+ ret = read_from_file(&eeprom_table, &caps, &key, file);
+ if (ret < 0) {
+ ERR("Failed to read capabilities from file: %d\n", ret);
+ return 1;
+ }
+ show_capabilities(&caps, stderr);
+ if (capabilities_burn(astribank, &eeprom_table, &caps, &key) < 0)
+ return 1;
+ if (file != stdin)
+ fclose(file);
+ } else {
+ /* print capabilities to stdout */
+ file = stdout;
+ if (filename) {
+ file = fopen(filename, "w");
+ if (file == NULL) {
+ ERR("Can't create file '%s'\n", filename);
+ return 1;
+ }
+ }
+ ret = write_to_file(&eeprom_table, &caps, &key, file);
+ if (ret < 0) {
+ ERR("Failed to write capabilities to file: %d\n", ret);
+ return 1;
+ }
+ if (file != stdout)
+ fclose(file);
+ }
+ mpp_exit(astribank);
+ return 0;
+}
diff --git a/kernel/xpp/utils/astribank_hexload.8 b/kernel/xpp/utils/astribank_hexload.8
new file mode 100644
index 0000000..4017f78
--- /dev/null
+++ b/kernel/xpp/utils/astribank_hexload.8
@@ -0,0 +1,66 @@
+.TH "ASTRIBANK_HEXLOAD" "8" "29 March 2009" "" ""
+
+.SH NAME
+astribank_tool \- Xorcom Astribank (xpp) firmware loader
+.SH SYNOPSIS
+.B astribank_tool -D \fIdevice-path\fR <\fB-F|-p\fR> [\fIoptions\fR] \fIhexfile\fR
+
+.B astribank_tool [-h]
+
+.SH DESCRIPTION
+.B astribank_hexload
+is a second-stage firmware loader for Xorcom Astribanks. Note that some
+older models use fpga_load(8) instead.
+
+It is used to load a file in the Intel HEX format into a Xorcom
+Astribank. It can be used to load either an FPGA firmware or a PIC
+firmware. It is normally run by the script xpp_fxloader.
+
+.SH OPTIONS
+.B -D
+.I device-path
+.RS
+Required. The device to read from/write to. On modern UDEV-based system
+this is usually /dev/bus/usb/\fIbus_num\fR/\fIdevice_num\fR,
+where \fIbus_num\fR and \fIdevice_num\fR are the first two numbers in the
+output of lsusb(8).
+On older systems that use usbfs, it is usually
+/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR.
+.RE
+
+.B -F
+.RS
+The firmware to load is a FPGA firmware.
+.RE
+
+.B -p
+.RS
+The firmware to load is a PIC firmware.
+.RE
+
+.B -v
+.RS
+Increase verbosity. May be used multiple times.
+.RE
+
+.B -d \fImask\fR
+.RS
+Set debug mask to \fImask\fR. Default is 0, 0xFF is "everything".
+.RE
+
+.B -h
+.RS
+Displays usage message.
+.RE
+
+.SH SEE ALSO
+fxload(8), lsusb(8), astribank_tool(8), fpga_load(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/kernel/xpp/utils/astribank_hexload.c b/kernel/xpp/utils/astribank_hexload.c
new file mode 100644
index 0000000..85cfd23
--- /dev/null
+++ b/kernel/xpp/utils/astribank_hexload.c
@@ -0,0 +1,201 @@
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2008, 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <arpa/inet.h>
+#include "debug.h"
+#include "hexfile.h"
+#include "mpp_funcs.h"
+#include "pic_loader.h"
+#include "astribank_usb.h"
+
+#define DBG_MASK 0x80
+#define MAX_HEX_LINES 10000
+
+static char *progname;
+
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [options...] -D {/proc/bus/usb|/dev/bus/usb}/<bus>/<dev> hexfile...\n", progname);
+ fprintf(stderr, "\tOptions: {-F|-p}\n");
+ fprintf(stderr, "\t\t[-F] # Load FPGA firmware\n");
+ fprintf(stderr, "\t\t[-p] # Load PIC firmware\n");
+ fprintf(stderr, "\t\t[-v] # Increase verbosity\n");
+ fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n");
+ exit(1);
+}
+
+int handle_hexline(struct astribank_device *astribank, struct hexline *hexline)
+{
+ uint16_t len;
+ uint16_t offset_dummy;
+ uint8_t *data;
+ int ret;
+
+ assert(hexline);
+ assert(astribank);
+ if(hexline->d.content.header.tt != TT_DATA) {
+ DBG("Non data record type = %d\n", hexline->d.content.header.tt);
+ return 0;
+ }
+ len = hexline->d.content.header.ll;
+ offset_dummy = hexline->d.content.header.offset;
+ data = hexline->d.content.tt_data.data;
+ if((ret = mpp_send_seg(astribank, data, offset_dummy, len)) < 0) {
+ ERR("Failed FPGA send line: %d\n", ret);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int load_fpga(struct astribank_device *astribank, const char *hexfile)
+{
+ struct hexdata *hexdata = NULL;
+ int finished = 0;
+ int ret;
+ int i;
+
+ if((hexdata = parse_hexfile(hexfile, MAX_HEX_LINES)) == NULL) {
+ perror(hexfile);
+ return -errno;
+ }
+ INFO("Loading FPGA firmware version %s\n", hexdata->version_info);
+#if 0
+ FILE *fp;
+ if((fp = fopen("fpga_dump_new.txt", "w")) == NULL) {
+ perror("dump");
+ exit(1);
+ }
+#endif
+ if((ret = mpp_send_start(astribank, DEST_FPGA)) < 0) {
+ ERR("Failed FPGA send start: %d\n", ret);
+ return ret;
+ }
+ for(i = 0; i < hexdata->maxlines; i++) {
+ struct hexline *hexline = hexdata->lines[i];
+
+ if(!hexline)
+ break;
+ if(finished) {
+ ERR("Extra data after End Of Data Record (line %d)\n", i);
+ return 0;
+ }
+ if(hexline->d.content.header.tt == TT_EOF) {
+ DBG("End of data\n");
+ finished = 1;
+ continue;
+ }
+ if((ret = handle_hexline(astribank, hexline)) < 0) {
+ ERR("Failed FPGA sending in lineno %d (ret=%d)\n", i, ret);;
+ return ret;
+ }
+ }
+ if((ret = mpp_send_end(astribank)) < 0) {
+ ERR("Failed FPGA send end: %d\n", ret);
+ return ret;
+ }
+#if 0
+ fclose(fp);
+#endif
+ free_hexdata(hexdata);
+ INFO("FPGA firmware loaded successfully\n");
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ char *devpath = NULL;
+ struct astribank_device *astribank;
+ int opt_fpga = 0;
+ int opt_pic = 0;
+ const char options[] = "vd:D:Fp";
+ int iface_num;
+ int ret;
+
+ progname = argv[0];
+ while (1) {
+ int c;
+
+ c = getopt (argc, argv, options);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'D':
+ devpath = optarg;
+ break;
+ case 'F':
+ opt_fpga = 1;
+ break;
+ case 'p':
+ opt_pic = 1;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'd':
+ debug_mask = strtoul(optarg, NULL, 0);
+ break;
+ case 'h':
+ default:
+ ERR("Unknown option '%c'\n", c);
+ return 1;
+ }
+ }
+ if((opt_fpga ^ opt_pic) == 0) {
+ ERR("The -F and -p options are mutually exclusive.\n");
+ usage();
+ }
+ iface_num = (opt_fpga) ? 1 : 0;
+ if(opt_fpga) {
+ if(optind != argc - 1) {
+ ERR("The -F option requires exacly one hexfile argument\n");
+ usage();
+ }
+ }
+ if(!devpath) {
+ ERR("Missing device path.\n");
+ usage();
+ }
+ if((astribank = astribank_open(devpath, iface_num)) == NULL) {
+ ERR("Opening astribank failed\n");
+ return 1;
+ }
+ show_astribank_info(astribank);
+ if(opt_fpga) {
+ if(load_fpga(astribank, argv[optind]) < 0) {
+ ERR("Loading FPGA firmware failed\n");
+ return 1;
+ }
+ } else if(opt_pic) {
+ if((ret = load_pic(astribank, argc - optind, argv + optind)) < 0) {
+ ERR("Loading PIC's failed\n");
+ return 1;
+ }
+ }
+ astribank_close(astribank, 0);
+ return 0;
+}
diff --git a/kernel/xpp/utils/astribank_tool.8 b/kernel/xpp/utils/astribank_tool.8
new file mode 100644
index 0000000..0507ad5
--- /dev/null
+++ b/kernel/xpp/utils/astribank_tool.8
@@ -0,0 +1,79 @@
+.TH "ASTRIBANK_TOOL" "8" "29 March 2009" "" ""
+
+.SH NAME
+astribank_tool \- Xorcom Astribank (xpp) control tool
+.SH SYNOPSIS
+.B astribank_tool -D \fIdevice-path\fR [ options ]
+
+.B astribank_tool [-h]
+
+.SH DESCRIPTION
+.B astribank_tool
+is a tool to control the USB-level functionality of an Astribank.
+
+.SH OPTIONS
+.B -D
+.I device-path
+.RS
+Required. The device to read from/write to. On modern UDEV-based system
+this is usually /dev/bus/usb/\fIbus_num\fR/\fIdevice_num\fR,
+where \fIbus_num\fR and \fIdevice_num\fR are the first two numbers in the
+output of lsusb(8).
+On older systems that use usbfs, it is usually
+/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR.
+.RE
+
+.B -p \fInum\fR
+.RS
+Set the TwinStar port number. Either 0 or 1.
+
+(TODO: explain).
+.RE
+
+.B -r \fItype\fR
+.RS
+Reset the Astribank and renumerate its USB connection to power on product ID.
+
+Tyep can be: \fBhalf\fR or \fBfull\fR.
+
+(TODO: explain those).
+.RE
+
+.B -w 0|1
+.RS
+Enable (1) or disable (0) the TwinStar watchdog. When enabled, the
+Astribank will jump to the second port if this system is "not working"
+and the system on the second port is available.
+.RE
+
+.B -n
+.RS
+Renumerate the Astribank product number (e.g: from 1161 to 1162).
+.RE
+
+.B -v
+.RS
+Increase verbosity. May be used multiple times.
+.RE
+
+.B -d \fImask\fR
+.RS
+Set debug mask to \fImask\fR. Default is 0, 0xFF is "everything".
+.RE
+
+.B -h
+.RS
+Displays usage message.
+.RE
+
+.SH SEE ALSO
+fxload(8), lsusb(8), astribank_hextool(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/kernel/xpp/utils/astribank_tool.c b/kernel/xpp/utils/astribank_tool.c
new file mode 100644
index 0000000..d5ba667
--- /dev/null
+++ b/kernel/xpp/utils/astribank_tool.c
@@ -0,0 +1,202 @@
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2008, 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <getopt.h>
+#include <arpa/inet.h>
+#include "mpp_funcs.h"
+#include "debug.h"
+
+#define DBG_MASK 0x80
+
+static char *progname;
+
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [options...] -D {/proc/bus/usb|/dev/bus/usb}/<bus>/<dev>\n", progname);
+ fprintf(stderr, "\tOptions: {-n|-r kind}\n");
+ fprintf(stderr, "\t\t[-n] # Renumerate device\n");
+ fprintf(stderr, "\t\t[-r kind] # Reset: kind = {half|full}\n");
+ fprintf(stderr, "\t\t[-p port] # TwinStar: USB port number [0, 1]\n");
+ fprintf(stderr, "\t\t[-w (0|1)] # TwinStar: Watchdog off or on guard\n");
+ fprintf(stderr, "\t\t[-v] # Increase verbosity\n");
+ fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n");
+ exit(1);
+}
+
+static int reset_kind(const char *arg)
+{
+ static const struct {
+ const char *name;
+ int type_code;
+ } reset_kinds[] = {
+ { "half", 0 },
+ { "full", 1 },
+ };
+ int i;
+
+ for(i = 0; i < sizeof(reset_kinds)/sizeof(reset_kinds[0]); i++) {
+ if(strcasecmp(reset_kinds[i].name, arg) == 0)
+ return reset_kinds[i].type_code;
+ }
+ ERR("Uknown reset kind '%s'\n", arg);
+ return -1;
+}
+
+
+static int show_hardware(struct astribank_device *astribank)
+{
+ uint8_t unit;
+ uint8_t card_status;
+ uint8_t card_type;
+ int ret;
+ struct eeprom_table eeprom_table;
+ struct capabilities capabilities;
+ struct extrainfo extrainfo;
+
+ show_astribank_info(astribank);
+ ret = mpp_caps_get(astribank, &eeprom_table, &capabilities, NULL);
+ if(ret < 0)
+ return ret;
+ show_eeprom(&eeprom_table, stdout);
+ show_astribank_status(astribank, stdout);
+ if(astribank->eeprom_type == EEPROM_TYPE_LARGE) {
+ show_capabilities(&capabilities, stdout);
+ if(STATUS_FPGA_LOADED(astribank->status)) {
+ for(unit = 0; unit < 4; unit++) {
+ ret = mpps_card_info(astribank, unit, &card_type, &card_status);
+ if(ret < 0)
+ return ret;
+ printf("CARD %d: type=%x.%x %s\n", unit,
+ ((card_type >> 4) & 0xF), (card_type & 0xF),
+ ((card_status & 0x1) ? "PIC" : "NOPIC"));
+ }
+ }
+ ret = mpp_extrainfo_get(astribank, &extrainfo);
+ if(ret < 0)
+ return ret;
+ show_extrainfo(&extrainfo, stdout);
+ if(CAP_EXTRA_TWINSTAR(&capabilities)) {
+ twinstar_show(astribank, stdout);
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ char *devpath = NULL;
+ struct astribank_device *astribank;
+ const char options[] = "vd:D:nr:p:w:";
+ int opt_renumerate = 0;
+ char *opt_port = NULL;
+ char *opt_watchdog = NULL;
+ char *opt_reset = NULL;
+ int tws_portnum;
+ int full_reset;
+ int ret;
+
+ progname = argv[0];
+ while (1) {
+ int c;
+
+ c = getopt (argc, argv, options);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'D':
+ devpath = optarg;
+ break;
+ case 'n':
+ opt_renumerate++;
+ break;
+ case 'p':
+ opt_port = optarg;
+ break;
+ case 'w':
+ opt_watchdog = optarg;
+ break;
+ case 'r':
+ opt_reset = optarg;
+ if((full_reset = reset_kind(opt_reset)) < 0)
+ usage();
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'd':
+ debug_mask = strtoul(optarg, NULL, 0);
+ break;
+ case 'h':
+ default:
+ ERR("Unknown option '%c'\n", c);
+ usage();
+ }
+ }
+ if(!devpath) {
+ ERR("Missing device path\n");
+ usage();
+ }
+ DBG("Startup %s\n", devpath);
+ if((astribank = mpp_init(devpath)) == NULL) {
+ ERR("Failed initializing MPP\n");
+ return 1;
+ }
+ show_hardware(astribank);
+ if(opt_reset) {
+ if((ret = mpp_reset(astribank, full_reset)) < 0) {
+ ERR("%s Reseting astribank failed: %d\n",
+ (full_reset) ? "Full" : "Half", ret);
+ }
+ } else if(opt_renumerate) {
+ if((ret = mpp_renumerate(astribank)) < 0) {
+ ERR("Renumerating astribank failed: %d\n", ret);
+ }
+ } else if(opt_watchdog) {
+ int watchdogstate = strtoul(opt_watchdog, NULL, 0);
+
+ INFO("TWINSTAR: Setting watchdog %s-guard\n",
+ (watchdogstate) ? "on" : "off");
+ if((ret = mpp_tws_setwatchdog(astribank, watchdogstate)) < 0) {
+ ERR("Failed to set watchdog to %d\n", watchdogstate);
+ return 1;
+ }
+ } else if(opt_port) {
+ int new_portnum = strtoul(opt_port, NULL, 0);
+ char *msg = (new_portnum == tws_portnum)
+ ? " Same same, never mind..."
+ : "";
+
+ INFO("TWINSTAR: Setting portnum to %d.%s\n", new_portnum, msg);
+ if((ret = mpp_tws_setportnum(astribank, new_portnum)) < 0) {
+ ERR("Failed to set USB portnum to %d\n", new_portnum);
+ return 1;
+ }
+ }
+ mpp_exit(astribank);
+ return 0;
+}
diff --git a/kernel/xpp/utils/astribank_usb.c b/kernel/xpp/utils/astribank_usb.c
new file mode 100644
index 0000000..088d360
--- /dev/null
+++ b/kernel/xpp/utils/astribank_usb.c
@@ -0,0 +1,536 @@
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2008, 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.
+ *
+ */
+
+#define _GNU_SOURCE /* for memrchr() */
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <arpa/inet.h>
+#include "astribank_usb.h"
+#include "debug.h"
+
+static const char rcsid[] = "$Id$";
+
+#define DBG_MASK 0x01
+#define TIMEOUT 500
+
+#define TYPE_ENTRY(t,ni,n,ne,out,in,...) \
+ [t] = { \
+ .type_code = (t), \
+ .num_interfaces = (ni), \
+ .my_interface_num = (n), \
+ .num_endpoints = (ne), \
+ .my_ep_in = (in), \
+ .my_ep_out = (out), \
+ .name = #t, \
+ .endpoints = { __VA_ARGS__ }, \
+ }
+
+static const struct interface_type interface_types[] = {
+ TYPE_ENTRY(USB_11xx, 1, 0, 4, MP_EP_OUT, MP_EP_IN,
+ XPP_EP_OUT,
+ MP_EP_OUT,
+ XPP_EP_IN,
+ MP_EP_IN),
+ TYPE_ENTRY(USB_FIRMWARE_II, 2, 1, 2, MP_EP_OUT, MP_EP_IN,
+ MP_EP_OUT,
+ MP_EP_IN),
+ TYPE_ENTRY(USB_PIC, 2, 0, 2, XPP_EP_OUT, XPP_EP_IN,
+ XPP_EP_OUT,
+ XPP_EP_IN),
+
+};
+#undef TYPE_ENTRY
+
+//static int verbose = LOG_DEBUG;
+
+/*
+ * USB handling
+ */
+
+/* return 1 if:
+ * - str has a number
+ * - It is larger than 0
+ * - It equals num
+ */
+static int num_matches(int num, const char* str) {
+ int str_val = atoi(str);
+ if (str_val <= 0)
+ return 0;
+ return (str_val == num);
+}
+
+struct usb_device *dev_of_path(const char *path)
+{
+ struct usb_bus *bus;
+ struct usb_device *dev;
+ char dirname[PATH_MAX];
+ char filename[PATH_MAX];
+ const char *p;
+ int bnum;
+ int dnum;
+ int ret;
+
+ assert(path != NULL);
+ if(access(path, F_OK) < 0) {
+ perror(path);
+ return NULL;
+ }
+ /* Find last '/' */
+ if((p = memrchr(path, '/', strlen(path))) == NULL) {
+ ERR("Missing a '/' in %s\n", path);
+ return NULL;
+ }
+ /* Get the device number */
+ ret = sscanf(p + 1, "%d", &dnum);
+ if(ret != 1) {
+ ERR("Path tail is not a device number: '%s'\n", p);
+ return NULL;
+ }
+ /* Search for a '/' before that */
+ p = memrchr(path, '/', p - path);
+ if(p == NULL)
+ p = path; /* Relative path */
+ else
+ p++; /* skip '/' */
+ /* Get the bus number */
+ ret = sscanf(p, "%d", &bnum);
+ if(ret != 1) {
+ ERR("Path tail is not a bus number: '%s'\n", p);
+ return NULL;
+ }
+ sprintf(dirname, "%03d", bnum);
+ sprintf(filename, "%03d", dnum);
+ for (bus = usb_busses; bus; bus = bus->next) {
+ if (! num_matches(bnum, bus->dirname))
+ //if(strcmp(bus->dirname, dirname) != 0)
+ continue;
+ for (dev = bus->devices; dev; dev = dev->next) {
+ //if(strcmp(dev->filename, filename) == 0)
+ if (num_matches(dnum, dev->filename))
+ return dev;
+ }
+ }
+ ERR("no usb device match '%s'\n", path);
+ return NULL;
+}
+
+int get_usb_string(struct astribank_device *astribank, uint8_t item, char *buf, unsigned int len)
+{
+ char tmp[BUFSIZ];
+ int ret;
+
+ assert(astribank->handle);
+ if (!item)
+ return 0;
+ ret = usb_get_string_simple(astribank->handle, item, tmp, BUFSIZ);
+ if (ret <= 0)
+ return ret;
+ return snprintf(buf, len, "%s", tmp);
+}
+
+static int match_interface(const struct astribank_device *astribank,
+ const struct interface_type *itype)
+{
+ struct usb_interface *interface;
+ struct usb_interface_descriptor *iface_desc;
+ struct usb_config_descriptor *config_desc;
+ int i = itype - interface_types;
+ int inum;
+ int num_altsetting;
+
+ DBG("Checking[%d]: interfaces=%d interface num=%d endpoints=%d: \"%s\"\n",
+ i,
+ itype->num_interfaces,
+ itype->my_interface_num,
+ itype->num_endpoints,
+ itype->name);
+ config_desc = astribank->dev->config;
+ if (!config_desc) {
+ ERR("No configuration descriptor: strange USB1 controller?\n");
+ return 0;
+ }
+ if(config_desc->bNumInterfaces <= itype->my_interface_num) {
+ DBG("Too little interfaces: have %d need %d\n",
+ config_desc->bNumInterfaces, itype->my_interface_num + 1);
+ return 0;
+ }
+ if(astribank->my_interface_num != itype->my_interface_num) {
+ DBG("Wrong match -- not my interface num (wanted %d)\n", astribank->my_interface_num);
+ return 0;
+ }
+ inum = itype->my_interface_num;
+ interface = &config_desc->interface[inum];
+ assert(interface != NULL);
+ iface_desc = interface->altsetting;
+ num_altsetting = interface->num_altsetting;
+ assert(num_altsetting != 0);
+ assert(iface_desc != NULL);
+ if(iface_desc->bInterfaceClass != 0xFF) {
+ DBG("Bad interface class 0x%X\n", iface_desc->bInterfaceClass);
+ return 0;
+ }
+ if(iface_desc->bInterfaceNumber != itype->my_interface_num) {
+ DBG("Bad interface number %d\n", iface_desc->bInterfaceNumber);
+ return 0;
+ }
+ if(iface_desc->bNumEndpoints != itype->num_endpoints) {
+ DBG("Different number of endpoints %d\n", iface_desc->bNumEndpoints);
+ return 0;
+ }
+ return 1;
+}
+
+static int astribank_init(struct astribank_device *astribank)
+{
+ struct usb_device_descriptor *dev_desc;
+ struct usb_config_descriptor *config_desc;
+ struct usb_interface *interface;
+ struct usb_interface_descriptor *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ const struct interface_type *fwtype;
+ int i;
+
+ assert(astribank);
+ astribank->handle = usb_open(astribank->dev);
+ if(!astribank->handle) {
+ ERR("Failed to open usb device '%s/%s': %s\n",
+ astribank->dev->bus->dirname, astribank->dev->filename, usb_strerror());
+ return 0;
+ }
+ fwtype = astribank->fwtype;
+ if(usb_claim_interface(astribank->handle, fwtype->my_interface_num) != 0) {
+ ERR("usb_claim_interface: %s\n", usb_strerror());
+ return 0;
+ }
+ dev_desc = &astribank->dev->descriptor;
+ config_desc = astribank->dev->config;
+ if (!config_desc) {
+ ERR("usb interface without a configuration\n");
+ return 0;
+ }
+ DBG("Got config_desc. Looking for interface %d\n", fwtype->my_interface_num);
+ interface = &config_desc->interface[fwtype->my_interface_num];
+ iface_desc = interface->altsetting;
+ endpoint = iface_desc->endpoint;
+ astribank->is_usb2 = (endpoint->wMaxPacketSize == 512);
+ for(i = 0; i < iface_desc->bNumEndpoints; i++, endpoint++) {
+ DBG("Validating endpoint @ %d (interface %d)\n", i, fwtype->my_interface_num);
+ if(endpoint->bEndpointAddress != fwtype->endpoints[i]) {
+ ERR("Wrong endpoint 0x%X != 0x%X (at index %d)\n",
+ endpoint->bEndpointAddress,
+ fwtype->endpoints[i],
+ i);
+ return 0;
+ }
+ if(endpoint->bEndpointAddress == MP_EP_OUT || endpoint->bEndpointAddress == MP_EP_IN) {
+ if(endpoint->wMaxPacketSize > PACKET_SIZE) {
+ ERR("Endpoint #%d wMaxPacketSize too large (%d)\n", i, endpoint->wMaxPacketSize);
+ return 0;
+ }
+ }
+ }
+ astribank->my_ep_in = fwtype->my_ep_in;
+ astribank->my_ep_out = fwtype->my_ep_out;
+ if(get_usb_string(astribank, dev_desc->iManufacturer, astribank->iManufacturer, BUFSIZ) < 0)
+ return 0;
+ if(get_usb_string(astribank, dev_desc->iProduct, astribank->iProduct, BUFSIZ) < 0)
+ return 0;
+ if(get_usb_string(astribank, dev_desc->iSerialNumber, astribank->iSerialNumber, BUFSIZ) < 0)
+ return 0;
+ if(get_usb_string(astribank, iface_desc->iInterface, astribank->iInterface, BUFSIZ) < 0)
+ return 0;
+ INFO("ID=%04X:%04X Manufacturer=[%s] Product=[%s] SerialNumber=[%s] Interface=[%s]\n",
+ dev_desc->idVendor,
+ dev_desc->idProduct,
+ astribank->iManufacturer,
+ astribank->iProduct,
+ astribank->iSerialNumber,
+ astribank->iInterface);
+ if(usb_clear_halt(astribank->handle, astribank->my_ep_out) != 0) {
+ ERR("Clearing output endpoint: %s\n", usb_strerror());
+ return 0;
+ }
+ if(usb_clear_halt(astribank->handle, astribank->my_ep_in) != 0) {
+ ERR("Clearing input endpoint: %s\n", usb_strerror());
+ return 0;
+ }
+ if((i = flush_read(astribank)) < 0) {
+ ERR("flush_read failed: %d\n", i);
+ return 0;
+ }
+ return 1;
+}
+
+struct astribank_device *astribank_open(const char devpath[], int iface_num)
+{
+ struct astribank_device *astribank;
+ int i;
+
+ DBG("devpath='%s' iface_num=%d\n", devpath, iface_num);
+ if((astribank = malloc(sizeof(*astribank))) == NULL) {
+ ERR("Out of memory");
+ return NULL;
+ }
+ memset(astribank, 0, sizeof(*astribank));
+ astribank->my_interface_num = iface_num;
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+ astribank->dev = dev_of_path(devpath);
+ if(!astribank->dev) {
+ ERR("Bailing out\n");
+ goto fail;
+ }
+ DBG("Scan interface types (astribank has %d interfaces)\n", astribank->dev->config->bNumInterfaces);
+ for(i = 0; i < sizeof(interface_types)/sizeof(interface_types[0]); i++) {
+ if(match_interface(astribank, &interface_types[i])) {
+ DBG("Identified[%d]: interfaces=%d endpoints=%d: \"%s\"\n",
+ i,
+ interface_types[i].num_interfaces,
+ interface_types[i].num_endpoints,
+ interface_types[i].name);
+ astribank->fwtype = &interface_types[i];
+ goto found;
+ }
+ }
+ ERR("Didn't find suitable device\n");
+fail:
+ free(astribank);
+ return NULL;
+found:
+ if(!astribank_init(astribank))
+ goto fail;
+ astribank->tx_sequenceno = 1;
+ return astribank;
+}
+
+/*
+ * MP device handling
+ */
+void show_astribank_info(const struct astribank_device *astribank)
+{
+ assert(astribank != NULL);
+ printf("USB Firmware Type: [%s]\n", astribank->fwtype->name);
+ printf("USB iManufacturer: [%s]\n", astribank->iManufacturer);
+ printf("USB iProduct: [%s]\n", astribank->iProduct);
+ printf("USB iSerialNumber: [%s]\n", astribank->iSerialNumber);
+}
+
+void astribank_close(struct astribank_device *astribank, int disconnected)
+{
+ assert(astribank != NULL);
+ if(!astribank->handle)
+ return; /* Nothing to do */
+ if(!disconnected) {
+ if(usb_release_interface(astribank->handle, astribank->fwtype->my_interface_num) != 0) {
+ ERR("Releasing interface: usb: %s\n", usb_strerror());
+ }
+ }
+ if(usb_close(astribank->handle) != 0) {
+ ERR("Closing device: usb: %s\n", usb_strerror());
+ }
+ astribank->tx_sequenceno = 0;
+ astribank->handle = NULL;
+}
+
+int send_usb(struct astribank_device *astribank, char *buf, int len, int timeout)
+{
+ int ret;
+
+ dump_packet(LOG_DEBUG, __FUNCTION__, buf, len);
+ if(astribank->my_ep_out & USB_ENDPOINT_IN) {
+ ERR("send_usb called with an input endpoint 0x%x\n", astribank->my_ep_out);
+ return -EINVAL;
+ }
+ ret = usb_bulk_write(astribank->handle, astribank->my_ep_out, buf, len, timeout);
+ if(ret < 0) {
+ /*
+ * If the device was gone, it may be the
+ * result of renumeration. Ignore it.
+ */
+ if(ret != -ENODEV) {
+ ERR("bulk_write to endpoint 0x%x failed: (%d) %s\n",
+ astribank->my_ep_out, ret, usb_strerror());
+ dump_packet(LOG_ERR, "send_usb[ERR]", buf, len);
+ exit(2);
+ } else {
+ DBG("bulk_write to endpoint 0x%x got ENODEV\n", astribank->my_ep_out);
+ astribank_close(astribank, 1);
+ }
+ return ret;
+ } else if(ret != len) {
+ ERR("bulk_write to endpoint 0x%x short write: (%d) %s\n",
+ astribank->my_ep_out, ret, usb_strerror());
+ dump_packet(LOG_ERR, "send_usb[ERR]", buf, len);
+ return -EFAULT;
+ }
+ return ret;
+}
+
+int recv_usb(struct astribank_device *astribank, char *buf, size_t len, int timeout)
+{
+ int ret;
+
+ if(astribank->my_ep_in & USB_ENDPOINT_OUT) {
+ ERR("recv_usb called with an output endpoint 0x%x\n", astribank->my_ep_in);
+ return -EINVAL;
+ }
+ ret = usb_bulk_read(astribank->handle, astribank->my_ep_in, buf, len, timeout);
+ if(ret < 0) {
+ DBG("bulk_read from endpoint 0x%x failed: (%d) %s\n",
+ astribank->my_ep_in, ret, usb_strerror());
+ memset(buf, 0, len);
+ return ret;
+ }
+ dump_packet(LOG_DEBUG, __FUNCTION__, buf, ret);
+ return ret;
+}
+
+int flush_read(struct astribank_device *astribank)
+{
+ char tmpbuf[BUFSIZ];
+ int ret;
+
+ DBG("starting...\n");
+ memset(tmpbuf, 0, BUFSIZ);
+ ret = recv_usb(astribank, tmpbuf, BUFSIZ, 1);
+ if(ret < 0 && ret != -ETIMEDOUT) {
+ ERR("ret=%d\n", ret);
+ return ret;
+ } else if(ret > 0) {
+ DBG("Got %d bytes:\n", ret);
+ dump_packet(LOG_DEBUG, __FUNCTION__, tmpbuf, ret);
+ }
+ return 0;
+}
+
+
+int release_isvalid(uint16_t release)
+{
+ uint8_t rmajor = (release >> 8) & 0xFF;
+ uint8_t rminor = release & 0xFF;
+
+ return (rmajor > 0) &&
+ (rmajor < 10) &&
+ (rminor > 0) &&
+ (rminor < 10);
+}
+
+int label_isvalid(const char *label)
+{
+ int len;
+ int goodlen;
+ const char GOOD_CHARS[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789"
+ "-_.";
+
+ len = strlen(label);
+ goodlen = strspn(label, GOOD_CHARS);
+ if(len > LABEL_SIZE) {
+ ERR("Label too long (%d > %d)\n", len, LABEL_SIZE);
+ return 0;
+ }
+ if(goodlen != len) {
+ ERR("Bad character in label (pos=%d)\n", goodlen);
+ return 0;
+ }
+ return 1;
+}
+
+int eeprom_fill(struct eeprom_table *eprm,
+ const char *vendor,
+ const char *product,
+ const char *release,
+ const char *label)
+{
+ uint16_t val;
+
+ eprm->source = 0xC0;
+ eprm->config_byte = 0;
+ if(vendor) {
+ val = strtoul(vendor, NULL, 0);
+ if(!val) {
+ ERR("Invalid vendor '%s'\n",
+ vendor);
+ return -EINVAL;
+ }
+ eprm->vendor = val;
+ }
+ if(product) {
+ val = strtoul(product, NULL, 0);
+ if(!val) {
+ ERR("Invalid product '%s'\n",
+ product);
+ return -EINVAL;
+ }
+ eprm->product = val;
+ }
+ if(release) {
+ int release_major = 0;
+ int release_minor = 0;
+ uint16_t value;
+
+ if(sscanf(release, "%d.%d", &release_major, &release_minor) != 2) {
+ ERR("Failed to parse release number '%s'\n", release);
+ return -EINVAL;
+ }
+ value = (release_major << 8) | release_minor;
+ DBG("Parsed release(%d): major=%d, minor=%d\n",
+ value, release_major, release_minor);
+ if(!release_isvalid(value)) {
+ ERR("Invalid release number 0x%X\n", value);
+ return -EINVAL;
+ }
+ eprm->release = value;
+ }
+ if(label) {
+ /* padding */
+ if(!label_isvalid(label)) {
+ ERR("Invalid label '%s'\n", label);
+ return -EINVAL;
+ }
+ memset(eprm->label, 0, LABEL_SIZE);
+ memcpy(eprm->label, label, strlen(label));
+ }
+ return 0;
+}
+
+int astribank_has_twinstar(struct astribank_device *astribank)
+{
+ struct usb_device_descriptor *dev_desc;
+ uint16_t product_series;
+
+ assert(astribank != NULL);
+ dev_desc = &astribank->dev->descriptor;
+ product_series = dev_desc->idProduct;
+ product_series &= 0xFFF0;
+ if(product_series == 0x1160) /* New boards */
+ return 1;
+ return 0;
+}
+
diff --git a/kernel/xpp/utils/astribank_usb.h b/kernel/xpp/utils/astribank_usb.h
new file mode 100644
index 0000000..6f9a429
--- /dev/null
+++ b/kernel/xpp/utils/astribank_usb.h
@@ -0,0 +1,102 @@
+#ifndef ASTRIBANK_USB_H
+#define ASTRIBANK_USB_H
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2008, 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 <stdio.h>
+#include <usb.h>
+#include "mpp.h"
+
+/*
+ * Astribank handling
+ */
+
+#define PACKET_SIZE 512
+
+/* USB Endpoints */
+#define MP_EP_OUT 0x04 /* Managment processor */
+#define MP_EP_IN 0x88 /* Managment processor */
+
+#define XPP_EP_OUT 0x02 /* XPP */
+#define XPP_EP_IN 0x86 /* XPP */
+
+/* USB firmware types */
+#define USB_11xx 0
+#define USB_FIRMWARE_II 1
+#define USB_PIC 2
+
+struct interface_type {
+ int type_code;
+ int num_interfaces;
+ int my_interface_num;
+ int num_endpoints;
+ int my_ep_out;
+ int my_ep_in;
+ char *name;
+ int endpoints[4]; /* for matching */
+};
+
+enum eeprom_burn_state {
+ BURN_STATE_NONE = 0,
+ BURN_STATE_STARTED = 1,
+ BURN_STATE_ENDED = 2,
+ BURN_STATE_FAILED = 3,
+};
+
+struct astribank_device {
+ struct usb_device *dev;
+ usb_dev_handle *handle;
+ int my_interface_num;
+ int my_ep_out;
+ int my_ep_in;
+ char iManufacturer[BUFSIZ];
+ char iProduct[BUFSIZ];
+ char iSerialNumber[BUFSIZ];
+ char iInterface[BUFSIZ];
+ int is_usb2;
+ enum eeprom_type eeprom_type;
+ enum eeprom_burn_state burn_state;
+ uint8_t status;
+ uint8_t mpp_proto_version;
+ struct eeprom_table *eeprom;
+ const struct interface_type *fwtype;
+ uint16_t tx_sequenceno;
+};
+
+/*
+ * Prototypes
+ */
+struct astribank_device *astribank_open(const char devpath[], int iface_num);
+void astribank_close(struct astribank_device *astribank, int disconnected);
+void show_astribank_info(const struct astribank_device *astribank);
+int send_usb(struct astribank_device *astribank, char *buf, int len, int timeout);
+int recv_usb(struct astribank_device *astribank, char *buf, size_t len, int timeout);
+int flush_read(struct astribank_device *astribank);
+int eeprom_fill(struct eeprom_table *eprm,
+ const char *vendor,
+ const char *product,
+ const char *release,
+ const char *label);
+int astribank_has_twinstar(struct astribank_device *astribank);
+int label_isvalid(const char *label);
+
+#endif /* ASTRIBANK_USB_H */
diff --git a/kernel/xpp/utils/debug.c b/kernel/xpp/utils/debug.c
new file mode 100644
index 0000000..f188a2d
--- /dev/null
+++ b/kernel/xpp/utils/debug.c
@@ -0,0 +1,53 @@
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2008, 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 <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include "debug.h"
+
+int verbose = LOG_DEBUG;
+int debug_mask = 0;
+
+void log_function(int level, int mask, const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ if(verbose >= level) {
+ if(level < LOG_DEBUG || (mask & debug_mask))
+ vfprintf(stderr, msg, ap);
+ }
+ va_end(ap);
+}
+
+void dump_packet(int loglevel, const char *msg, const char *buf, int len)
+{
+ int i;
+
+ log_function(loglevel, ~0, "%-15s:", msg);
+ for(i = 0; i < len; i++)
+ log_function(loglevel, ~0, " %02X", (uint8_t)buf[i]);
+ log_function(loglevel, ~0, "\n");
+}
+
diff --git a/kernel/xpp/utils/debug.h b/kernel/xpp/utils/debug.h
new file mode 100644
index 0000000..185848a
--- /dev/null
+++ b/kernel/xpp/utils/debug.h
@@ -0,0 +1,46 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2008, 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 <syslog.h>
+
+/*
+ * Each module should define a unique DBG_MASK
+ */
+
+extern int verbose;
+extern int debug_mask;
+
+/*
+ * Logging
+ */
+void log_function(int level, int mask, const char *msg, ...) __attribute__(( format(printf, 3, 4) ));
+
+#define ERR(fmt, arg...) log_function(LOG_ERR, 0, "%s:%d: ERROR(%s): " fmt, __FILE__, __LINE__, __FUNCTION__, ## arg)
+#define INFO(fmt, arg...) log_function(LOG_INFO, 0, "INFO: " fmt, ## arg)
+#define DBG(fmt, arg...) log_function(LOG_DEBUG, DBG_MASK, \
+ "%s:%d: DBG(%s): " fmt, __FILE__, __LINE__, __FUNCTION__, ## arg)
+
+void dump_packet(int loglevel, const char *msg, const char *buf, int len);
+
+#endif /* DEBUG_H */
diff --git a/kernel/xpp/utils/genconf_parameters b/kernel/xpp/utils/genconf_parameters
index d1b8f62..66adab9 100644
--- a/kernel/xpp/utils/genconf_parameters
+++ b/kernel/xpp/utils/genconf_parameters
@@ -1,19 +1,19 @@
#
-# /etc/dahdi/genconf_parameters
+# /etc/genconf_parameters
#
# This file contains parameters that affect the
-# dahdi_genconf configurator generator.
+# zapconf configuration generator.
#
# Syntax:
# * A comment from '#' to end of line
# * Blank lines ignored
# * Whitespace at end of line trimmed
# * Single valued items:
-# key <whitespaces...> value
+# key <whitespace...> value
# * List valued items:
# key
-# <whitespaces...>value1
-# <whitespaces...>value2
+# <whitespace...>value1
+# <whitespace...>value2
# ...
#
@@ -21,27 +21,27 @@
# extension number will be channel_number+base_exten . The default is:
#base_exten 4000
#
-# Make FXS (analog phones) extentions answer immediately (sets
+# Make FXS (analog phones) extensions answer immediately (sets
# 'immediate = yes' for them in zapata.conf). Don't enable this before
# you're read documentation about this option.
#fxs_immediate yes
#
# For FXS (analog phones) - use KS or LS? ks is the only method for
# Asterisk to provide disconnect supervision and thus it would normally
-# be preffered and is the default.
+# be preferred and is the default.
#fxs_default_start ls
#
# For FXO (analog lines) - use KS or LS? KS is the default and is
-# normally the better choice as it allows detecting handups on many
+# normally the better choice as it allows detecting hang-ups on many
# lines.
#fxo_default_start ls
-# Set tone zone values. This is used for playing tones (busy, dialtone
+# Set tone zone values. This is used for playing tones (busy, dial-tone
# and such). The default is 'us'. This sets the value for both loadzone
# and defaultzone in zaptel.conf .
#lc_country il
-# The dialplan contenxt into which to send trunks in zapata.conf or
+# The dialplan context into which to send trunks in zapata.conf or
# users.conf. The default value is:
#context_lines from-pstn
#
@@ -49,7 +49,7 @@
# users.conf. The default value is:
#context_phones from-internal
#
-# Two extea contexts for the input ports and output ports of an
+# Two extra contexts for the input ports and output ports of an
# Astribank. Default values are:
#context_input astbank-input
#context_output astbank-output
@@ -78,16 +78,23 @@
# phones.
#brint_overlap
-# bri_hardhdlc: If this parameter is set to 'yes', in the entries for
-# BRI cards 'hardhdlc' will be used instead of 'dchan' (an alias for
-# 'fcshdlc').
-#bri_hardhdlc yes
+# bri_hardhdlc:
+# 'yes' - forces BRI cards to use 'hardhdlc' signalling.
+# 'no' - forces BRI cards to use 'dchan' (an alias for 'fcshdlc').
+# It is usefull only for zaptel with the bristuff patch.
+#
+# If it is left out or set to 'auto':
+# * Information supplied by the driver is used to decide:
+# - Currently implemented for Astribanks.
+# - Taken from /sys/bus/xpds/drivers/bri/dchan_hardhdlc.
+# * Without this info, falls back to 'dchan'.
+#bri_hardhdlc auto
# For MFC/R2 Support: 'R2' will make E1 spans CAS and with the
# 'r2_idle_bits' bit in zaptel.conf . It will also make zapconf default
# to generating the channels of this card in unicall.conf rather than in
# zapata.conf . The meaning of this may be extended somehow to support
-# R2 through openr2/chan_dahdi later on.
+# R2 through openr2/chan_zap later on.
#pri_connection_type R2
#r2_idle_bits 1101
diff --git a/kernel/xpp/utils/hexfile.c b/kernel/xpp/utils/hexfile.c
index 2a01b3f..1227b26 100644
--- a/kernel/xpp/utils/hexfile.c
+++ b/kernel/xpp/utils/hexfile.c
@@ -1,6 +1,6 @@
/*
* Written by Oron Peled <oron@actcom.co.il>
- * Copyright (C) 2006, Xorcom
+ * Copyright (C) 2006, 2007, 2008, Xorcom
*
* All rights reserved.
*
@@ -426,6 +426,7 @@ struct hexdata *parse_hexfile(const char *fname, unsigned int maxlines)
report_func(LOG_ERR, "Failed to open hexfile '%s'\n", fname);
goto err;
}
+ snprintf(hexdata->fname, PATH_MAX, "%s", fname);
for(line = 1; fgets(buf, BUFSIZ, fp); line++) {
if(dos_eof) {
if(report_func)
diff --git a/kernel/xpp/utils/hexfile.h b/kernel/xpp/utils/hexfile.h
index f8bf6a9..27c71e7 100644
--- a/kernel/xpp/utils/hexfile.h
+++ b/kernel/xpp/utils/hexfile.h
@@ -1,6 +1,6 @@
/*
* Written by Oron Peled <oron@actcom.co.il>
- * Copyright (C) 2006, Xorcom
+ * Copyright (C) 2006, 2007, 2008, Xorcom
*
* All rights reserved.
*
@@ -24,49 +24,12 @@
#define PARSE_HEXFILE_H
#include <stdarg.h>
-
-/*
- * Some portability workarounds
- */
-#ifdef _WINDOWS
-
-#include <windows.h> /* for UCHAR USHORT */
-typedef UCHAR uint8_t;
-typedef USHORT uint16_t;
-#define PACKED
-#define sscanf sscanf_s
-#define ZERO_SIZE 1
-
-/* From /usr/include/syslog.h */
-#define LOG_EMERG 0 /* system is unusable */
-#define LOG_ALERT 1 /* action must be taken immediately */
-#define LOG_CRIT 2 /* critical conditions */
-#define LOG_ERR 3 /* error conditions */
-#define LOG_WARNING 4 /* warning conditions */
-#define LOG_NOTICE 5 /* normal but significant condition */
-#define LOG_INFO 6 /* informational */
-#define LOG_DEBUG 7 /* debug-level messages */
-
-#ifdef __cplusplus
-# define __BEGIN_DECLS extern "C" {
-# define __END_DECLS }
-#else
-# define __BEGIN_DECLS
-# define __END_DECLS
-#endif
-
-#elif __GNUC__
-
+#include <stdio.h>
#include <stdint.h>
+#include <sys/param.h>
#include <syslog.h>
#define PACKED __attribute__((packed))
-#define ZERO_SIZE 1
-
-#else
-
-#error "Cannot compile on this platform"
-
-#endif
+#define ZERO_SIZE 0
/* Record types in hexfile */
enum {
@@ -101,6 +64,7 @@ struct hexdata {
unsigned int maxlines;
unsigned int last_line;
int got_eof;
+ char fname[PATH_MAX];
char version_info[BUFSIZ];
struct hexline *lines[ZERO_SIZE];
};
diff --git a/kernel/xpp/utils/lszaptel b/kernel/xpp/utils/lszaptel
index d365ca1..71a95d1 100755
--- a/kernel/xpp/utils/lszaptel
+++ b/kernel/xpp/utils/lszaptel
@@ -17,7 +17,7 @@ use Zaptel::Xpp;
use Zaptel::Xpp::Xbus;
use Zaptel::Xpp::Xpd;
-my @xbuses = Zaptel::Xpp::xbuses("SORT_CONNECTOR");
+my @xbuses = Zaptel::Xpp::xbuses;
my @xpds = map { $_->xpds } @xbuses;
foreach my $span (Zaptel::spans()) {
diff --git a/kernel/xpp/utils/mpp.h b/kernel/xpp/utils/mpp.h
new file mode 100644
index 0000000..b71eb30
--- /dev/null
+++ b/kernel/xpp/utils/mpp.h
@@ -0,0 +1,324 @@
+#ifndef MPP_H
+#define MPP_H
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2008, 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.
+ *
+ */
+
+/*
+ * MPP - Managment Processor Protocol definitions
+ */
+
+#ifdef __GNUC__
+#define PACKED __attribute__((packed))
+#else
+#error "We do not know how your compiler packs structures"
+#endif
+
+#define MK_PROTO_VERSION(major, minor) (((major) << 4) | (0x0F & (minor)))
+
+#define MPP_PROTOCOL_VERSION MK_PROTO_VERSION(1,3)
+
+/*
+ * The eeprom_table is common to all eeprom types.
+ */
+#define LABEL_SIZE 8
+struct eeprom_table {
+ uint8_t source; /* C0 - small eeprom, C2 - large eeprom */
+ uint16_t vendor;
+ uint16_t product;
+ uint16_t release; /* BCD encoded release */
+ uint8_t config_byte; /* Must be 0 */
+ uint8_t label[LABEL_SIZE];
+} PACKED;
+
+struct capabilities {
+ uint8_t ports_fxs;
+ uint8_t ports_fxo;
+ uint8_t ports_bri;
+ uint8_t ports_pri;
+ uint8_t extra_features; /* BIT(0) - TwinStar */
+ uint8_t reserved[3];
+ uint32_t timestamp;
+} PACKED;
+
+#define CAP_EXTRA_TWINSTAR(c) ((c)->extra_features & 0x01)
+#define CAP_EXTRA_TWINSTAR_SET(c) do {(c)->extra_features |= 0x01;} while (0)
+#define CAP_EXTRA_TWINSTAR_CLR(c) do {(c)->extra_features &= ~0x01;} while (0)
+
+#define KEYSIZE 16
+
+struct capkey {
+ uint8_t k[KEYSIZE];
+} PACKED;
+
+struct extrainfo {
+ char text[24];
+} PACKED;
+
+enum mpp_command_ops {
+ /* MSB of op signifies a reply from device */
+ MPP_ACK = 0x80,
+
+ MPP_PROTO_QUERY = 0x01,
+ MPP_PROTO_REPLY = 0x81,
+
+ MPP_RENUM = 0x0B, /* Trigger USB renumeration */
+
+ MPP_EEPROM_SET = 0x0D,
+
+ MPP_CAPS_GET = 0x0E,
+ MPP_CAPS_GET_REPLY = 0x8E,
+ MPP_CAPS_SET = 0x0F, /* Set AB capabilities */
+
+ MPP_DEV_SEND_START = 0x05,
+ MPP_DEV_SEND_SEG = 0x07,
+ MPP_DEV_SEND_END = 0x09,
+
+ MPP_STATUS_GET = 0x11, /* Get Astribank Status */
+ MPP_STATUS_GET_REPLY = 0x91,
+
+ MPP_EXTRAINFO_GET = 0x13, /* Get extra vendor information */
+ MPP_EXTRAINFO_GET_REPLY = 0x93,
+ MPP_EXTRAINFO_SET = 0x15, /* Set extra vendor information */
+
+ MPP_EEPROM_BLK_RD = 0x27,
+ MPP_EEPROM_BLK_RD_REPLY = 0xA7,
+
+ MPP_SER_SEND = 0x37,
+ MPP_SER_RECV = 0xB7,
+
+ MPP_RESET = 0x45, /* Reset both FPGA and USB firmwares */
+ MPP_HALF_RESET = 0x47, /* Reset only FPGA firmware */
+
+ /* Twinstar */
+ MPP_TWS_WD_MODE_SET = 0x31, /* Set watchdog off/on guard */
+ MPP_TWS_WD_MODE_GET = 0x32, /* Current watchdog mode */
+ MPP_TWS_WD_MODE_GET_REPLY = 0xB2, /* Current watchdog mode */
+ MPP_TWS_PORT_SET = 0x34, /* USB-[0/1] */
+ MPP_TWS_PORT_GET = 0x35, /* USB-[0/1] */
+ MPP_TWS_PORT_GET_REPLY = 0xB5, /* USB-[0/1] */
+ MPP_TWS_PWR_GET = 0x36, /* Power: bits -> USB ports */
+ MPP_TWS_PWR_GET_REPLY = 0xB6, /* Power: bits -> USB ports */
+};
+
+struct mpp_header {
+ uint16_t len;
+ uint16_t seq;
+ uint8_t op; /* MSB: 0 - to device, 1 - from device */
+} PACKED;
+
+enum mpp_ser_op {
+ SER_CARD_INFO_GET = 0x1,
+ SER_STAT_GET = 0x3,
+};
+
+/* Individual commands structure */
+
+#define CMD_DEF(name, ...) struct d_ ## name { __VA_ARGS__ } PACKED d_ ## name
+
+CMD_DEF(ACK,
+ uint8_t stat;
+ );
+
+CMD_DEF(PROTO_QUERY,
+ uint8_t proto_version;
+ uint8_t reserved;
+ );
+
+CMD_DEF(PROTO_REPLY,
+ uint8_t proto_version;
+ uint8_t reserved;
+ );
+
+CMD_DEF(STATUS_GET);
+
+CMD_DEF(STATUS_GET_REPLY,
+ uint8_t i2cs_data;
+
+#define STATUS_FPGA_LOADED(x) ((x) & 0x01)
+ uint8_t status; /* BIT(0) - FPGA is loaded */
+ );
+
+CMD_DEF(EEPROM_SET,
+ struct eeprom_table data;
+ );
+
+CMD_DEF(CAPS_GET);
+
+CMD_DEF(CAPS_GET_REPLY,
+ struct eeprom_table data;
+ struct capabilities capabilities;
+ struct capkey key;
+ );
+
+CMD_DEF(CAPS_SET,
+ struct eeprom_table data;
+ struct capabilities capabilities;
+ struct capkey key;
+ );
+
+CMD_DEF(EXTRAINFO_GET);
+
+CMD_DEF(EXTRAINFO_GET_REPLY,
+ struct extrainfo info;
+ );
+
+CMD_DEF(EXTRAINFO_SET,
+ struct extrainfo info;
+ );
+
+CMD_DEF(RENUM);
+
+CMD_DEF(EEPROM_BLK_RD,
+ uint16_t offset;
+ uint16_t len;
+ );
+
+CMD_DEF(EEPROM_BLK_RD_REPLY,
+ uint16_t offset;
+ uint8_t data[0];
+ );
+
+CMD_DEF(DEV_SEND_START,
+ uint8_t dest;
+ );
+
+CMD_DEF(DEV_SEND_END);
+
+CMD_DEF(DEV_SEND_SEG,
+ uint16_t offset;
+ uint8_t data[0];
+ );
+
+CMD_DEF(RESET);
+CMD_DEF(HALF_RESET);
+
+CMD_DEF(SER_SEND,
+ uint8_t data[0];
+ );
+
+CMD_DEF(SER_RECV,
+ uint8_t data[0];
+ );
+
+CMD_DEF(TWS_WD_MODE_SET,
+ uint8_t wd_active;
+ );
+
+CMD_DEF(TWS_WD_MODE_GET);
+CMD_DEF(TWS_WD_MODE_GET_REPLY,
+ uint8_t wd_active;
+ );
+
+CMD_DEF(TWS_PORT_SET,
+ uint8_t portnum;
+ );
+
+CMD_DEF(TWS_PORT_GET);
+CMD_DEF(TWS_PORT_GET_REPLY,
+ uint8_t portnum;
+ );
+
+CMD_DEF(TWS_PWR_GET);
+CMD_DEF(TWS_PWR_GET_REPLY,
+ uint8_t power;
+ );
+
+#undef CMD_DEF
+
+#define MEMBER(n) struct d_ ## n d_ ## n
+
+struct mpp_command {
+ struct mpp_header header;
+ union {
+ MEMBER(ACK);
+ MEMBER(PROTO_QUERY);
+ MEMBER(PROTO_REPLY);
+ MEMBER(STATUS_GET);
+ MEMBER(STATUS_GET_REPLY);
+ MEMBER(EEPROM_SET);
+ MEMBER(CAPS_GET);
+ MEMBER(CAPS_GET_REPLY);
+ MEMBER(CAPS_SET);
+ MEMBER(EXTRAINFO_GET);
+ MEMBER(EXTRAINFO_GET_REPLY);
+ MEMBER(EXTRAINFO_SET);
+ MEMBER(RENUM);
+ MEMBER(EEPROM_BLK_RD);
+ MEMBER(EEPROM_BLK_RD_REPLY);
+ MEMBER(DEV_SEND_START);
+ MEMBER(DEV_SEND_SEG);
+ MEMBER(DEV_SEND_END);
+ MEMBER(RESET);
+ MEMBER(HALF_RESET);
+ MEMBER(SER_SEND);
+ MEMBER(SER_RECV);
+ /* Twinstar */
+ MEMBER(TWS_WD_MODE_SET);
+ MEMBER(TWS_WD_MODE_GET);
+ MEMBER(TWS_WD_MODE_GET_REPLY);
+ MEMBER(TWS_PORT_SET);
+ MEMBER(TWS_PORT_GET);
+ MEMBER(TWS_PORT_GET_REPLY);
+ MEMBER(TWS_PWR_GET);
+ MEMBER(TWS_PWR_GET_REPLY);
+ uint8_t raw_data[0];
+ } PACKED alt;
+} PACKED;
+#undef MEMBER
+
+#define CMD_FIELD(cmd, name, field) ((cmd)->alt.d_ ## name.field)
+
+enum mpp_ack_stat {
+ STAT_OK = 0x00, /* acknowledges previous command */
+ STAT_FAIL = 0x01, /* Last command failed */
+ STAT_RESET_FAIL = 0x02, /* reset failed */
+ STAT_NODEST = 0x03, /* No destination is selected */
+ STAT_MISMATCH = 0x04, /* Data mismatch */
+ STAT_NOACCESS = 0x05, /* No access */
+ STAT_BAD_CMD = 0x06, /* Bad command */
+ STAT_TOO_SHORT = 0x07, /* Packet is too short */
+ STAT_ERROFFS = 0x08, /* Offset error */
+ STAT_NOCODE = 0x09, /* Source was not burned before */
+ STAT_NO_LEEPROM = 0x0A, /* Large EEPROM was not found */
+ STAT_NO_EEPROM = 0x0B, /* No EEPROM was found */
+ STAT_WRITE_FAIL = 0x0C, /* Writing to device failed */
+ STAT_FPGA_ERR = 0x0D, /* FPGA error */
+ STAT_KEY_ERR = 0x0E, /* Bad Capabilities Key */
+ STAT_NOCAPS_ERR = 0x0F, /* No matching capability */
+ STAT_NOPWR_ERR = 0x10, /* No power on USB connector */
+ STAT_CAPS_FPGA_ERR = 0x11, /* Setting of the capabilities while FPGA is loaded */
+};
+
+enum eeprom_type { /* EEPROM_QUERY: i2cs(ID1, ID0) */
+ EEPROM_TYPE_NONE = 0,
+ EEPROM_TYPE_SMALL = 1,
+ EEPROM_TYPE_LARGE = 2,
+ EEPROM_TYPE_UNUSED = 3,
+};
+
+enum dev_dest {
+ DEST_NONE = 0x00,
+ DEST_FPGA = 0x01,
+ DEST_EEPROM = 0x02,
+};
+
+#endif /* MPP_H */
diff --git a/kernel/xpp/utils/mpp_funcs.c b/kernel/xpp/utils/mpp_funcs.c
new file mode 100644
index 0000000..c52397f
--- /dev/null
+++ b/kernel/xpp/utils/mpp_funcs.c
@@ -0,0 +1,1028 @@
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2008, 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 <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include "hexfile.h"
+#include "astribank_usb.h"
+#include "mpp_funcs.h"
+#include "debug.h"
+
+static const char rcsid[] = "$Id$";
+
+#define DBG_MASK 0x02
+
+const char *ack_status_msg(uint8_t status)
+{
+ const static char *msgs[] = {
+ [STAT_OK] = "Acknowledges previous command",
+ [STAT_FAIL] = "Last command failed",
+ [STAT_RESET_FAIL] = "Reset failed",
+ [STAT_NODEST] = "No destination is selected",
+ [STAT_MISMATCH] = "Data mismatch",
+ [STAT_NOACCESS] = "No access",
+ [STAT_BAD_CMD] = "Bad command",
+ [STAT_TOO_SHORT] = "Packet is too short",
+ [STAT_ERROFFS] = "Offset error",
+ [STAT_NOCODE] = "Source was not burned before",
+ [STAT_NO_LEEPROM] = "Large EEPROM was not found",
+ [STAT_NO_EEPROM] = "No EEPROM was found",
+ [STAT_WRITE_FAIL] = "Writing to device failed",
+ [STAT_FPGA_ERR] = "FPGA error",
+ [STAT_KEY_ERR] = "Bad Capabilities Key",
+ [STAT_NOCAPS_ERR] = "No matching capability",
+ [STAT_NOPWR_ERR] = "No power on USB connector",
+ [STAT_CAPS_FPGA_ERR] = "Setting of the capabilities while FPGA is loaded",
+ };
+ if(status > sizeof(msgs)/sizeof(msgs[0]))
+ return "ERROR CODE TOO LARGE";
+ if(!msgs[status])
+ return "MISSING ERROR CODE";
+ return msgs[status];
+}
+
+const char *eeprom_type2str(enum eeprom_type et)
+{
+ const static char *msgs[] = {
+ [EEPROM_TYPE_NONE] = "NONE",
+ [EEPROM_TYPE_SMALL] = "SMALL",
+ [EEPROM_TYPE_LARGE] = "LARGE",
+ [EEPROM_TYPE_UNUSED] = "UNUSED",
+ };
+ if(et > sizeof(msgs)/sizeof(msgs[0]))
+ return NULL;
+ return msgs[et];
+};
+
+struct command_desc {
+ uint8_t op;
+ const char *name;
+ uint16_t len;
+};
+
+#define CMD_RECV(o) [MPP_ ## o] { \
+ .op = MPP_ ## o, \
+ .name = #o, \
+ .len = sizeof(struct mpp_header) + sizeof(struct d_ ## o), \
+ }
+
+#define CMD_SEND(o) [MPP_ ## o] { \
+ .op = MPP_ ## o, \
+ .name = #o, \
+ .len = sizeof(struct mpp_header) + sizeof(struct d_ ## o), \
+ }
+
+static const struct command_desc command_table[] = {
+ CMD_RECV(ACK),
+ CMD_SEND(PROTO_QUERY),
+ CMD_SEND(STATUS_GET),
+ CMD_SEND(STATUS_GET_REPLY),
+ CMD_SEND(EEPROM_SET),
+ CMD_SEND(CAPS_GET),
+ CMD_RECV(CAPS_GET_REPLY),
+ CMD_SEND(CAPS_SET),
+ CMD_SEND(EXTRAINFO_GET),
+ CMD_SEND(EXTRAINFO_GET_REPLY),
+ CMD_SEND(EXTRAINFO_SET),
+ CMD_RECV(PROTO_REPLY),
+ CMD_SEND(RENUM),
+ CMD_SEND(EEPROM_BLK_RD),
+ CMD_RECV(EEPROM_BLK_RD_REPLY),
+ CMD_SEND(DEV_SEND_SEG),
+ CMD_SEND(DEV_SEND_START),
+ CMD_SEND(DEV_SEND_END),
+ CMD_SEND(RESET),
+ CMD_SEND(HALF_RESET),
+ CMD_SEND(SER_SEND),
+ CMD_SEND(SER_RECV),
+ /* Twinstar */
+ CMD_SEND(TWS_WD_MODE_SET),
+ CMD_SEND(TWS_WD_MODE_GET),
+ CMD_RECV(TWS_WD_MODE_GET_REPLY),
+ CMD_SEND(TWS_PORT_SET),
+ CMD_SEND(TWS_PORT_GET),
+ CMD_RECV(TWS_PORT_GET_REPLY),
+ CMD_SEND(TWS_PWR_GET),
+ CMD_RECV(TWS_PWR_GET_REPLY),
+};
+#undef CMD_SEND
+#undef CMD_RECV
+
+struct cmd_queue {
+ struct cmd_queue *next;
+ struct cmd_queue *prev;
+ struct mpp_command *cmd;
+};
+
+static struct cmd_queue output_queue = {
+ .next = &output_queue,
+ .prev = &output_queue,
+ .cmd = NULL
+ };
+
+void free_command(struct mpp_command *cmd)
+{
+ memset(cmd, 0, cmd->header.len);
+ free(cmd);
+}
+
+struct mpp_command *new_command(uint8_t op, uint16_t extra_data)
+{
+ struct mpp_command *cmd;
+ const struct command_desc *desc;
+ uint16_t len;
+
+ DBG("OP=0x%X (extra_data %d)\n", op, extra_data);
+ if(op > sizeof(command_table)/sizeof(command_table[0])) {
+ ERR("Invalid op=0x%X. Bigger than max valid op\n", op);
+ return NULL;
+ }
+ desc = &command_table[op];
+ if(!desc->name) {
+ ERR("Unknown op=0x%X.\n", op);
+ return NULL;
+ }
+ len = desc->len + extra_data;
+ if((cmd = malloc(len)) == NULL) {
+ ERR("Out of memory\n");
+ return NULL;
+ }
+ cmd->header.op = op;
+ cmd->header.len = len;
+ cmd->header.seq = 0; /* Overwritten in send_usb() */
+ return cmd;
+}
+
+const struct command_desc *get_command_desc(uint8_t op)
+{
+ const struct command_desc *desc;
+
+ if(op > sizeof(command_table)/sizeof(command_table[0])) {
+ //ERR("Invalid op=0x%X. Bigger than max valid op\n", op);
+ return NULL;
+ }
+ desc = &command_table[op];
+ if(!desc->name)
+ return NULL;
+ return desc;
+}
+
+const char *get_command_name(uint8_t op)
+{
+ const struct command_desc *desc;
+
+ if((desc = get_command_desc(op)) == NULL)
+ return NULL;
+ return desc->name;
+}
+
+void dump_command(struct mpp_command *cmd)
+{
+ uint16_t len;
+ int i;
+
+ len = cmd->header.len;
+ if(len < sizeof(struct mpp_header)) {
+ ERR("Command too short (%d)\n", len);
+ return;
+ }
+ INFO("DUMP: OP=0x%X len=%d seq=%d\n",
+ cmd->header.op, cmd->header.len, cmd->header.seq);
+ for(i = 0; i < len - sizeof(struct mpp_header); i++) {
+ INFO(" %2d. 0x%X\n", i, cmd->alt.raw_data[i]);
+ }
+}
+
+int send_command(struct astribank_device *astribank, struct mpp_command *cmd, int timeout)
+{
+ int ret;
+ int len;
+ char *buf;
+
+ len = cmd->header.len;
+ cmd->header.seq = astribank->tx_sequenceno;
+
+ buf = (char *)cmd;
+ //printf("%s: len=%d\n", __FUNCTION__, len);
+#if 0
+ extern FILE *fp;
+ if(fp) {
+ int i;
+
+ fprintf(fp, "%05d:", cmd->header.seq);
+ for(i = 0; i < len; i++)
+ fprintf(fp, " %02X", (uint8_t)buf[i]);
+ fprintf(fp, "\n");
+ }
+#endif
+ ret = send_usb(astribank, (char *)cmd, len, timeout);
+ if(ret < 0) {
+ ERR("send_usb failed ret=%d\n", ret);
+ }
+ astribank->tx_sequenceno++;
+ return ret;
+}
+
+struct mpp_command *recv_command(struct astribank_device *astribank, int timeout)
+{
+ struct mpp_command *reply;
+ int ret;
+
+ if((reply = malloc(PACKET_SIZE)) == NULL) {
+ ERR("Out of memory\n");
+ goto err;
+ }
+ reply->header.len = 0;
+ ret = recv_usb(astribank, (char *)reply, PACKET_SIZE, timeout);
+ if(ret < 0) {
+ ERR("Receive from usb failed.\n");
+ goto err;
+ }
+ if(ret != reply->header.len) {
+ ERR("Wrong length received: got %d bytes, but length field says %d bytes%s\n",
+ ret, reply->header.len,
+ (ret == 1)? ". Old USB firmware?": "");
+ goto err;
+ }
+ //dump_packet(LOG_DEBUG, __FUNCTION__, (char *)reply, ret);
+ return reply;
+err:
+ if(reply) {
+ memset(reply, 0, PACKET_SIZE);
+ free_command(reply);
+ }
+ return NULL;
+}
+
+
+int process_command(struct astribank_device *astribank, struct mpp_command *cmd, struct mpp_command **reply_ref)
+{
+ struct mpp_command *reply = NULL;
+ const struct command_desc *reply_desc;
+ const struct command_desc *expected;
+ uint8_t reply_op;
+ int ret;
+
+ if(reply_ref)
+ *reply_ref = NULL; /* So the caller knows if a reply was received */
+ reply_op = cmd->header.op | 0x80;
+ expected = get_command_desc(reply_op);
+ //printf("%s: len=%d\n", __FUNCTION__, cmd->header.len);
+ ret = send_command(astribank, cmd, TIMEOUT);
+ if(ret < 0) {
+ ERR("send_command failed: %d\n", ret);
+ goto out;
+ }
+ if(!reply_ref) {
+ DBG("No reply requested\n");
+ goto out;
+ }
+ reply = recv_command(astribank, TIMEOUT);
+ if(!reply) {
+ ERR("recv_command failed\n");
+ ret = -EPROTO;
+ goto out;
+ }
+ *reply_ref = reply;
+ if((reply->header.op & 0x80) != 0x80) {
+ ERR("Unexpected reply op=0x%02X, should have MSB set.\n", reply->header.op);
+ ret = -EPROTO;
+ goto out;
+ }
+ DBG("REPLY OP: 0x%X\n", reply->header.op);
+ reply_desc = get_command_desc(reply->header.op);
+ if(!reply_desc) {
+ ERR("Unknown reply op=0x%02X\n", reply->header.op);
+ ret = -EPROTO;
+ goto out;
+ }
+ DBG("REPLY NAME: %s\n", reply_desc->name);
+ if(reply->header.op == MPP_ACK) {
+ int status = CMD_FIELD(reply, ACK, stat);
+
+ if(expected) {
+ ERR("Expected OP=0x%02X: Got ACK(%d): %s\n",
+ reply_op, status, ack_status_msg(status));
+ ret = -EPROTO;
+ goto out;
+ } else if(status != STAT_OK) {
+
+ ERR("Got ACK (for OP=0x%X): %d - %s\n",
+ cmd->header.op,
+ status,
+ ack_status_msg(status));
+#if 0
+ extern FILE *fp;
+ if(fp) {
+ fprintf(fp, "Got ACK(%d)\n", status);
+ }
+#endif
+ ret = -EPROTO;
+ goto out;
+ }
+ /* Good expected ACK ... */
+ } else if(reply->header.op != reply_op) {
+ ERR("Expected OP=0x%02X: Got OP=0x%02X\n",
+ reply_op, reply->header.op);
+ ret = -EPROTO;
+ goto out;
+ }
+ if(expected && expected->op != MPP_SER_RECV && expected->len != reply->header.len) {
+ ERR("Expected len=%d: Got len=%d\n",
+ expected->len, reply->header.len);
+ ret = -EPROTO;
+ goto out;
+ }
+ if(cmd->header.seq != reply->header.seq) {
+ ERR("Expected seq=%d: Got seq=%d\n",
+ cmd->header.seq, reply->header.seq);
+ ret = -EPROTO;
+ goto out;
+ }
+ ret = reply->header.len; /* All good, return the length */
+ DBG("returning reply op 0x%X (%d bytes)\n", reply->header.op, ret);
+out:
+ free_command(cmd);
+ if(!reply_ref && reply)
+ free_command(reply);
+ return ret;
+}
+
+/*
+ * Protocol Commands
+ */
+
+int mpp_proto_query(struct astribank_device *astribank)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_PROTO_QUERY, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ CMD_FIELD(cmd, PROTO_QUERY, proto_version) = MPP_PROTOCOL_VERSION; /* Protocol Version */
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ astribank->mpp_proto_version = CMD_FIELD(reply, PROTO_REPLY, proto_version);
+ if(astribank->mpp_proto_version != MPP_PROTOCOL_VERSION) {
+ ERR("Got mpp protocol version: %02x (expected %02x)\n",
+ astribank->mpp_proto_version,
+ MPP_PROTOCOL_VERSION);
+ ret = -EPROTO;
+ goto out;
+ }
+ INFO("Protocol version: %02x\n", astribank->mpp_proto_version);
+ free_command(reply);
+out:
+ return ret;
+}
+
+int mpp_status_query(struct astribank_device *astribank)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_STATUS_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ astribank->eeprom_type = 0x3 & (CMD_FIELD(reply, STATUS_GET_REPLY, i2cs_data) >> 3);
+ astribank->status = CMD_FIELD(reply, STATUS_GET_REPLY, status);
+ DBG("EEPROM TYPE: %02x\n", astribank->eeprom_type);
+ DBG("FPGA Firmware: %s\n", (astribank->status & 0x1) ? "Loaded" : "Empty");
+ free_command(reply);
+ return ret;
+}
+
+int mpp_eeprom_set(struct astribank_device *astribank, const struct eeprom_table *et)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_EEPROM_SET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ memcpy(&CMD_FIELD(cmd, EEPROM_SET, data), et, sizeof(*et));
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ free_command(reply);
+ return 0;
+}
+
+int mpp_renumerate(struct astribank_device *astribank)
+{
+ struct mpp_command *cmd;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_RENUM, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, NULL);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+int mpp_caps_get(struct astribank_device *astribank,
+ struct eeprom_table *eeprom_table,
+ struct capabilities *capabilities,
+ struct capkey *key)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_CAPS_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ assert(reply->header.op == MPP_CAPS_GET_REPLY);
+ if(eeprom_table) {
+ memcpy(eeprom_table, (void *)&CMD_FIELD(reply, CAPS_GET_REPLY, data), sizeof(*eeprom_table));
+ }
+ if(capabilities) {
+ const struct capabilities *cap = &CMD_FIELD(reply, CAPS_GET_REPLY, capabilities);
+
+ memcpy(capabilities, cap, sizeof(*capabilities));
+ }
+ if(key) {
+ const struct capkey *k = &CMD_FIELD(reply, CAPS_GET_REPLY, key);
+
+ memcpy(key, k, sizeof(*key));
+ }
+ free_command(reply);
+ return 0;
+}
+
+int mpp_caps_set(struct astribank_device *astribank,
+ const struct eeprom_table *eeprom_table,
+ const struct capabilities *capabilities,
+ const struct capkey *key)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_CAPS_SET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ memcpy(&CMD_FIELD(cmd, CAPS_SET, data), eeprom_table, sizeof(*eeprom_table));
+ memcpy(&CMD_FIELD(cmd, CAPS_SET, capabilities), capabilities, sizeof(*capabilities));
+ memcpy(&CMD_FIELD(cmd, CAPS_SET, key), key, sizeof(*key));
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ free_command(reply);
+ return 0;
+}
+
+int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_EXTRAINFO_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ assert(reply->header.op == MPP_EXTRAINFO_GET_REPLY);
+ if(info) {
+ memcpy(info, (void *)&CMD_FIELD(reply, EXTRAINFO_GET_REPLY, info), sizeof(*info));
+ }
+ free_command(reply);
+ return 0;
+}
+
+int mpp_extrainfo_set(struct astribank_device *astribank, const struct extrainfo *info)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_EXTRAINFO_SET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ memcpy(&CMD_FIELD(cmd, EXTRAINFO_SET, info), info, sizeof(*info));
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ free_command(reply);
+ return 0;
+}
+
+int mpp_eeprom_blk_rd(struct astribank_device *astribank, uint8_t *buf, uint16_t offset, uint16_t len)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+ int size;
+
+ DBG("len = %d, offset = %d\n", len, offset);
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_EEPROM_BLK_RD, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ CMD_FIELD(cmd, EEPROM_BLK_RD, len) = len;
+ CMD_FIELD(cmd, EEPROM_BLK_RD, offset) = offset;
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ size = ret;
+ goto out;
+ }
+ INFO("size=%d offset=0x%X\n", size, CMD_FIELD(reply, EEPROM_BLK_RD_REPLY, offset));
+ dump_packet(LOG_DEBUG, "BLK_RD", (char *)reply, ret);
+ size = reply->header.len - sizeof(struct mpp_header) - sizeof(struct d_EEPROM_BLK_RD_REPLY);
+ if(size > len) {
+ ERR("Truncating reply (was %d, now %d)\n", size, len);
+ size = len;
+ }
+ memcpy(buf, CMD_FIELD(reply, EEPROM_BLK_RD_REPLY, data), size);
+out:
+ free_command(reply);
+ return size;
+}
+
+int mpp_send_start(struct astribank_device *astribank, enum dev_dest dest)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply = NULL;
+ int ret = 0;
+
+ DBG("dest = %d\n", dest);
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_DEV_SEND_START, 0)) == NULL) {
+ ERR("new_command failed\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+ CMD_FIELD(cmd, DEV_SEND_START, dest) = dest;
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ goto out;
+ }
+out:
+ if(reply)
+ free_command(reply);
+ astribank->burn_state = (ret == 0)
+ ? BURN_STATE_STARTED
+ : BURN_STATE_FAILED;
+ return ret;
+}
+
+int mpp_send_end(struct astribank_device *astribank)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply = NULL;
+ int ret = 0;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_DEV_SEND_END, 0)) == NULL) {
+ ERR("new_command failed\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ goto out;
+ }
+out:
+ if(reply)
+ free_command(reply);
+ astribank->burn_state = (ret == 0)
+ ? BURN_STATE_ENDED
+ : BURN_STATE_FAILED;
+ return ret;
+}
+
+int mpp_send_seg(struct astribank_device *astribank, const uint8_t *data, uint16_t offset, uint16_t len)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ if(!astribank->burn_state == BURN_STATE_STARTED) {
+ ERR("Tried to send a segment while burn_state=%d\n",
+ astribank->burn_state);
+ return -EINVAL;
+ }
+ DBG("len = %d, offset = %d (0x%02X, 0x%02X)\n", len, offset, *data, *(data + 1));
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_DEV_SEND_SEG, len)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ CMD_FIELD(cmd, DEV_SEND_SEG, offset) = offset;
+ memcpy(CMD_FIELD(cmd, DEV_SEND_SEG, data), data, len);
+#if 0
+ {
+ FILE *fp;
+ if((fp = fopen("seg_data.bin", "a")) == NULL) {
+ perror("seg_data.bin");
+ exit(1);
+ }
+ if(fwrite(CMD_FIELD(cmd, DEV_SEND_SEG, data), len, 1, fp) != 1) {
+ perror("fwrite");
+ exit(1);
+ }
+ fclose(fp);
+ }
+#endif
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ free_command(reply);
+ return 0;
+}
+
+int mpp_reset(struct astribank_device *astribank, int full_reset)
+{
+ struct mpp_command *cmd;
+ int ret;
+ int op = (full_reset) ? MPP_RESET: MPP_HALF_RESET;
+
+ DBG("full = %s\n", (full_reset) ? "YES" : "NO");
+ assert(astribank != NULL);
+ if((cmd = new_command(op, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, NULL);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+int mpp_serial_cmd(struct astribank_device *astribank, const uint8_t *in, uint8_t *out, uint16_t len)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+ uint8_t *data;
+
+ DBG("len=%d\n", len);
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_SER_SEND, len)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ data = CMD_FIELD(cmd, SER_SEND, data);
+ memcpy(data, in, len);
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ assert(reply->header.op == MPP_SER_RECV);
+ data = CMD_FIELD(reply, SER_RECV, data);
+ memcpy(out, data, len);
+ free_command(reply);
+ return 0;
+}
+
+int mpps_card_info(struct astribank_device *astribank, int unit, uint8_t *card_type, uint8_t *card_status)
+{
+ struct card_info_send {
+ uint8_t ser_op;
+ uint8_t addr;
+ } *card_info_send;
+ struct card_info_recv {
+ uint8_t ser_op_undef; /* invalid data */
+ uint8_t addr;
+ uint8_t card_full_type; /* (type << 4 | subtype) */
+ uint8_t card_status; /* BIT(0) - PIC burned */
+ } *card_info_recv;
+ uint8_t in[sizeof(struct card_info_recv)];
+ uint8_t out[sizeof(struct card_info_recv)];
+ int len;
+ int ret;
+
+ len = sizeof(struct card_info_recv);
+ memset(in, 0, len);
+ memset(out, 0, len);
+ card_info_send = (struct card_info_send *)&in;
+ card_info_recv = (struct card_info_recv *)&out;
+ card_info_send->ser_op = SER_CARD_INFO_GET;
+ card_info_send->addr = (unit << 4); /* low nibble is subunit */
+ ret = mpp_serial_cmd(astribank, in, out, len);
+ if(ret < 0)
+ return ret;
+ *card_type = card_info_recv->card_full_type;
+ *card_status = card_info_recv->card_status;
+ return 0;
+}
+
+int mpp_tws_watchdog(struct astribank_device *astribank)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_TWS_WD_MODE_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ ret = CMD_FIELD(reply, TWS_WD_MODE_GET_REPLY, wd_active);
+ DBG("wd_active=0x%X\n", ret);
+ free_command(reply);
+ return ret == 1;
+}
+
+int mpp_tws_setwatchdog(struct astribank_device *astribank, int yes)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("%s\n", (yes) ? "YES" : "NO");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_TWS_WD_MODE_SET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ CMD_FIELD(cmd, TWS_WD_MODE_SET, wd_active) = (yes) ? 1 : 0;
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ free_command(reply);
+ return 0;
+}
+
+int mpp_tws_powerstate(struct astribank_device *astribank)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_TWS_PWR_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ ret = CMD_FIELD(reply, TWS_PWR_GET_REPLY, power);
+ DBG("power=0x%X\n", ret);
+ free_command(reply);
+ return ret;
+}
+
+int mpp_tws_portnum(struct astribank_device *astribank)
+{
+ struct mpp_command *cmd;
+ struct mpp_command *reply;
+ int ret;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if((cmd = new_command(MPP_TWS_PORT_GET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ ret = CMD_FIELD(reply, TWS_PORT_GET_REPLY, portnum);
+ DBG("portnum=0x%X\n", ret);
+ free_command(reply);
+ return ret;
+}
+
+int mpp_tws_setportnum(struct astribank_device *astribank, uint8_t portnum)
+{
+ struct mpp_command *cmd;
+ int ret;
+ struct mpp_command *reply;
+
+ DBG("\n");
+ assert(astribank != NULL);
+ if(portnum >= 2) {
+ ERR("Invalid portnum (%d)\n", portnum);
+ return -EINVAL;
+ }
+ if((cmd = new_command(MPP_TWS_PORT_SET, 0)) == NULL) {
+ ERR("new_command failed\n");
+ return -ENOMEM;
+ }
+ CMD_FIELD(cmd, TWS_PORT_SET, portnum) = portnum;
+ ret = process_command(astribank, cmd, &reply);
+ if(ret < 0) {
+ ERR("process_command failed: %d\n", ret);
+ return ret;
+ }
+ free_command(reply);
+ return 0;
+}
+
+/*
+ * Wrappers
+ */
+
+struct astribank_device *mpp_init(const char devpath[])
+{
+ struct astribank_device *astribank;
+ int ret;
+
+ DBG("devpath='%s'\n", devpath);
+ if((astribank = astribank_open(devpath, 1)) == NULL) {
+ ERR("Opening astribank failed\n");
+ return NULL;
+ }
+ ret = mpp_proto_query(astribank);
+ if(ret < 0) {
+ ERR("Protocol handshake failed: %d\n", ret);
+ goto err;
+ }
+ ret = mpp_status_query(astribank);
+ if(ret < 0) {
+ ERR("Status query failed: %d\n", ret);
+ goto err;
+ }
+ return astribank;
+
+err:
+ if (astribank)
+ astribank_close(astribank, 0);
+ return NULL;
+}
+
+void mpp_exit(struct astribank_device *astribank)
+{
+ DBG("\n");
+ astribank_close(astribank, 0);
+}
+
+/*
+ * data structures
+ */
+
+void show_eeprom(const struct eeprom_table *eprm, FILE *fp)
+{
+ int rmajor = (eprm->release >> 8) & 0xFF;
+ int rminor = eprm->release & 0xFF;;
+ char buf[BUFSIZ];
+
+ memset(buf, 0, LABEL_SIZE + 1);
+ memcpy(buf, eprm->label, LABEL_SIZE);
+ fprintf(fp, "EEPROM: %-15s: 0x%02X\n", "Source", eprm->source);
+ fprintf(fp, "EEPROM: %-15s: 0x%04X\n", "Vendor", eprm->vendor);
+ fprintf(fp, "EEPROM: %-15s: 0x%04X\n", "Product", eprm->product);
+ fprintf(fp, "EEPROM: %-15s: %d.%d\n", "Release", rmajor, rminor);
+ fprintf(fp, "EEPROM: %-15s: 0x%02X\n", "Config", eprm->config_byte);
+ fprintf(fp, "EEPROM: %-15s: '%s'\n", "Label", buf);
+}
+
+void show_capabilities(const struct capabilities *capabilities, FILE *fp)
+{
+ fprintf(fp, "Capabilities: FXS ports: %2d\n", capabilities->ports_fxs);
+ fprintf(fp, "Capabilities: FXO ports: %2d\n", capabilities->ports_fxo);
+ fprintf(fp, "Capabilities: BRI ports: %2d\n", capabilities->ports_bri);
+ fprintf(fp, "Capabilities: PRI ports: %2d\n", capabilities->ports_pri);
+ fprintf(fp, "Capabilities: TwinStar : %s\n",
+ (CAP_EXTRA_TWINSTAR(capabilities)) ? "Yes" : "No");
+}
+
+void show_astribank_status(struct astribank_device *astribank, FILE *fp)
+{
+ fprintf(fp, "Astribank: EEPROM : %s\n", eeprom_type2str(astribank->eeprom_type));
+ fprintf(fp, "Astribank: FPGA status : %s\n",
+ STATUS_FPGA_LOADED(astribank->status) ? "Loaded" : "Empty");
+}
+
+void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp)
+{
+ fprintf(fp, "Extrainfo: : %s\n", (const char *)(extrainfo->text));
+}
+
+int twinstar_show(struct astribank_device *astribank, FILE *fp)
+{
+ int watchdog;
+ int powerstate;
+ int portnum;
+ int i;
+
+ if(!astribank_has_twinstar(astribank)) {
+ fprintf(fp, "TwinStar: NO\n");
+ return 0;
+ }
+ if((watchdog = mpp_tws_watchdog(astribank)) < 0) {
+ ERR("Failed getting TwinStar information\n");
+ return watchdog;
+ }
+ if((powerstate = mpp_tws_powerstate(astribank)) < 0) {
+ ERR("Failed getting TwinStar powerstate\n");
+ return powerstate;
+ }
+ if((portnum = mpp_tws_portnum(astribank)) < 0) {
+ ERR("Failed getting TwinStar portnum\n");
+ return portnum;
+ }
+ fprintf(fp, "TwinStar: Connected to : USB-%1d\n", portnum);
+ fprintf(fp, "TwinStar: Watchdog : %s\n",
+ (watchdog) ? "on-guard" : "off-guard");
+ for(i = 0; i < 2; i++) {
+ int pw = (1 << i) & powerstate;
+
+ fprintf(fp, "TwinStar: USB-%1d POWER : %s\n",
+ i, (pw) ? "ON" : "OFF");
+ }
+ return 0;
+}
+
diff --git a/kernel/xpp/utils/mpp_funcs.h b/kernel/xpp/utils/mpp_funcs.h
new file mode 100644
index 0000000..8ab4b3a
--- /dev/null
+++ b/kernel/xpp/utils/mpp_funcs.h
@@ -0,0 +1,78 @@
+#ifndef MPP_FUNCS_H
+#define MPP_FUNCS_H
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2008, 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 "mpp.h"
+#include "astribank_usb.h"
+
+#define TIMEOUT 2000
+
+/* high-level */
+struct astribank_device *mpp_init(const char devpath[]);
+void mpp_exit(struct astribank_device *astribank);
+int mpp_proto_query(struct astribank_device *astribank);
+int mpp_status_query(struct astribank_device *astribank);
+int mpp_eeprom_set(struct astribank_device *astribank, const struct eeprom_table *et);
+int mpp_renumerate(struct astribank_device *astribank);
+int mpp_caps_get(struct astribank_device *astribank,
+ struct eeprom_table *et,
+ struct capabilities *cap,
+ struct capkey *key);
+int mpp_caps_set(struct astribank_device *astribank,
+ const struct eeprom_table *eeprom_table,
+ const struct capabilities *capabilities,
+ const struct capkey *key);
+int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info);
+int mpp_extrainfo_set(struct astribank_device *astribank, const struct extrainfo *info);
+int mpp_eeprom_blk_rd(struct astribank_device *astribank, uint8_t *buf, uint16_t offset, uint16_t len);
+int mpp_send_start(struct astribank_device *astribank, enum dev_dest dest);
+int mpp_send_end(struct astribank_device *astribank);
+int mpp_send_seg(struct astribank_device *astribank, const uint8_t *data, uint16_t offset, uint16_t len);
+int mpp_reset(struct astribank_device *astribank, int full_reset);
+int mpp_serial_cmd(struct astribank_device *astribank, const uint8_t *in, uint8_t *out, uint16_t len);
+void show_eeprom(const struct eeprom_table *eprm, FILE *fp);
+void show_capabilities(const struct capabilities *capabilities, FILE *fp);
+void show_astribank_status(struct astribank_device *astribank, FILE *fp);
+void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp);
+int twinstar_show(struct astribank_device *astribank, FILE *fp);
+
+/*
+ * Serial commands to FPGA
+ */
+int mpps_card_info(struct astribank_device *astribank, int unit, uint8_t *card_type, uint8_t *card_status);
+
+/*
+ * Twinstar
+ */
+int mpp_tws_watchdog(struct astribank_device *astribank);
+int mpp_tws_setwatchdog(struct astribank_device *astribank, int yes);
+int mpp_tws_powerstate(struct astribank_device *astribank);
+int mpp_tws_portnum(struct astribank_device *astribank);
+int mpp_tws_setportnum(struct astribank_device *astribank, uint8_t portnum);
+
+/* low-level */
+int process_command(struct astribank_device *astribank, struct mpp_command *cmd, struct mpp_command **reply_ref);
+struct mpp_command *new_command(uint8_t op, uint16_t extra_data);
+void free_command(struct mpp_command *cmd);
+
+#endif /* MPP_FUNCS_H */
diff --git a/kernel/xpp/utils/pic_loader.c b/kernel/xpp/utils/pic_loader.c
new file mode 100644
index 0000000..c74718e
--- /dev/null
+++ b/kernel/xpp/utils/pic_loader.c
@@ -0,0 +1,275 @@
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2008, 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 <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <regex.h>
+#include "hexfile.h"
+#include "pic_loader.h"
+#include "debug.h"
+
+#define DBG_MASK 0x03
+#define MAX_HEX_LINES 10000
+#define TIMEOUT 500
+
+enum xpp_packet_types {
+ PIC_REQ_XOP = 0x09,
+ PIC_REP_XOP = 0x0A
+};
+
+struct xpp_packet_header {
+ struct {
+ uint16_t len;
+ uint8_t op;
+ uint8_t unit;
+ } PACKED header;
+ union {
+ struct {
+ struct {
+ uint8_t flags;
+ uint8_t card_type;
+ uint16_t offs;
+ } pic_header;
+ uint8_t data[3];
+ } PACKED pic_packet;
+ } d;
+} PACKED;
+
+int send_picline(struct astribank_device *astribank, uint8_t card_type, enum pic_command pcmd, int offs, uint8_t *data, int data_len)
+{
+ int recv_answer = 0;
+ char buf[PACKET_SIZE];
+ struct xpp_packet_header *phead = (struct xpp_packet_header *)buf;
+ int pack_len;
+ int ret;
+
+ assert(astribank != NULL);
+ pack_len = data_len + sizeof(phead->header) + sizeof(phead->d.pic_packet.pic_header);
+ phead->header.len = pack_len;
+ phead->header.op = PIC_REQ_XOP;
+ phead->header.unit = 0x00;
+ phead->d.pic_packet.pic_header.flags = pcmd;
+ phead->d.pic_packet.pic_header.card_type = card_type;
+ phead->d.pic_packet.pic_header.offs = offs;
+ if(data)
+ memcpy(phead->d.pic_packet.data, data, data_len);
+ switch (pcmd) {
+ case PIC_START_FLAG:
+ break;
+ case PIC_DATA_FLAG:
+ break;
+ case PIC_END_FLAG:
+ recv_answer = 1;
+ break;
+ case PIC_ENDS_FLAG:
+ break;
+ }
+
+ DBG("PICLINE: pack_len=%d pcmd=%d\n", pack_len, pcmd);
+ dump_packet(LOG_DEBUG, "dump:picline[W]", (char *)phead, pack_len);
+
+ ret = send_usb(astribank, buf, pack_len, TIMEOUT);
+ if(ret < 0) {
+ ERR("send_usb failed: %d\n", ret);
+ return ret;
+ }
+ DBG("send_usb: Written %d bytes\n", ret);
+ if (recv_answer) {
+ ret = recv_usb(astribank, buf, sizeof(buf), TIMEOUT);
+ if(ret <= 0) {
+ ERR("No USB packs to read\n");
+ return ret;
+ } else {
+ phead = (struct xpp_packet_header *)buf;
+ if(phead->header.op != PIC_REP_XOP) {
+ ERR("Got unexpected reply OP=0x%02X\n", phead->header.op);
+ dump_packet(LOG_ERR, "hexline[ERR]", buf, ret);
+ return -EINVAL;
+ }
+ DBG("received OP=0x%02X, checksum=%02X\n", phead->header.op, phead->d.pic_packet.data[0]);
+ if(phead->d.pic_packet.data[0] != 0) {
+ ERR("PIC burning, bad checksum\n");
+ return -EINVAL;
+ }
+ }
+ }
+ return 0;
+}
+
+static const char *pic_basename(const char *fname, uint8_t *card_type)
+{
+ const char *basename;
+ regex_t regex;
+ char ebuf[BUFSIZ];
+ const char re[] = "PIC_TYPE_([0-9]+)\\.hex";
+ regmatch_t pmatch[2]; /* One for the whole match, one for the number */
+ int nmatch = (sizeof(pmatch)/sizeof(pmatch[0]));
+ int len;
+ int ret;
+
+ basename = strrchr(fname, '/');
+ if(!basename)
+ basename = fname;
+ if((ret = regcomp(&regex, re, REG_ICASE | REG_EXTENDED)) != 0) {
+ regerror(ret, &regex, ebuf, sizeof(ebuf));
+ ERR("regcomp: %s\n", ebuf);
+ return NULL;
+ }
+ if((ret = regexec(&regex, basename, nmatch, pmatch, 0)) != 0) {
+ regerror(ret, &regex, ebuf, sizeof(ebuf));
+ ERR("regexec: %s\n", ebuf);
+ regfree(&regex);
+ return NULL;
+ }
+ /*
+ * Should have both complete match and a parentheses match
+ */
+ if(pmatch[0].rm_so == -1 || pmatch[1].rm_so == -1) {
+ ERR("pic_basename: Bad match: pmatch[0].rm_so=%d pmatch[1].rm_so=%d\n",
+ pmatch[0].rm_so, pmatch[1].rm_so == -1);
+ regfree(&regex);
+ return NULL;
+ }
+ len = pmatch[1].rm_eo - pmatch[1].rm_so;
+ if(len >= sizeof(ebuf) - 1)
+ len = sizeof(ebuf) - 1;
+ memcpy(ebuf, basename + pmatch[1].rm_so, len);
+ ebuf[len] = '\0';
+ DBG("match: %s\n", ebuf);
+ ret = atoi(ebuf);
+ if(ret <= 0 || ret > 9) {
+ ERR("pic_basename: Bad type number %d\n", ret);
+ regfree(&regex);
+ return NULL;
+ }
+ *card_type = ret;
+ regfree(&regex);
+ return basename;
+}
+
+/*
+ * Returns: true on success, false on failure
+ */
+static int pic_burn(struct astribank_device *astribank, const struct hexdata *hexdata)
+{
+ const char *v = hexdata->version_info;
+ const char *basename;
+ uint8_t *data;
+ unsigned char check_sum = 0;
+ uint8_t card_type;
+ int ret;
+ unsigned int i;
+
+ v = (v[0]) ? v : "Unknown";
+ assert(astribank != NULL);
+ assert(hexdata != NULL);
+ if(!astribank->is_usb2) {
+ ERR("Skip PIC burning (not USB2)\n");
+ return 0;
+ }
+ INFO("Load PIC: %s\n", hexdata->fname);
+ basename = pic_basename(hexdata->fname, &card_type);
+ if(!basename) {
+ ERR("Bad PIC filename '%s'. Abort.\n", hexdata->fname);
+ return 0;
+ }
+ DBG("basename=%s card_type=%d maxlines=%d\n",
+ basename, card_type, hexdata->maxlines);
+ /*
+ * Try to read extra left-overs from USB controller
+ */
+ for(i = 2; i; i--) {
+ char buf[PACKET_SIZE];
+
+ if(usb_bulk_read(astribank->handle, astribank->my_ep_in, buf, sizeof(buf), 1) <= 0)
+ break;
+ }
+ if((ret = send_picline(astribank, card_type, PIC_START_FLAG, 0, NULL, 0)) != 0) {
+ perror("Failed sending start hexline");
+ return 0;
+ }
+ for(i = 0; i < hexdata->maxlines; i++) {
+ struct hexline *hexline;
+ unsigned int len;
+
+ hexline = hexdata->lines[i];
+ if(!hexline) {
+ ERR("hexdata finished early (line %d)", i);
+ return 0;
+ }
+ if(hexline->d.content.header.tt == TT_DATA) {
+ len = hexline->d.content.header.ll; /* don't send checksum */
+ if(len != 3) {
+ ERR("Bad line len %d\n", len);
+ return 0;
+ }
+ data = hexline->d.content.tt_data.data;
+ check_sum ^= data[0] ^ data[1] ^ data[2];
+ ret = send_picline(astribank, card_type, PIC_DATA_FLAG,
+ hexline->d.content.header.offset, data, len);
+ if(ret) {
+ perror("Failed sending data hexline");
+ return 0;
+ }
+ } else if(hexline->d.content.header.tt == TT_EOF) {
+ break;
+ } else {
+ ERR("Unexpected TT = %d in line %d\n",
+ hexline->d.content.header.tt, i);
+ return 0;
+ }
+ }
+ if((ret = send_picline(astribank, card_type, PIC_END_FLAG, 0, &check_sum, 1)) != 0) {
+ perror("Failed sending end hexline");
+ return 0;
+ }
+ DBG("Finished...\n");
+ return 1;
+}
+
+int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[])
+{
+ int i;
+
+ INFO("Loading %d PIC files...\n", numfiles);
+ for(i = 0; i < numfiles; i++) {
+ struct hexdata *picdata;
+ const char *curr = filelist[i];
+
+ DBG("%s\n", curr);
+ if((picdata = parse_hexfile(curr, MAX_HEX_LINES)) == NULL) {
+ perror(curr);
+ return -errno;
+ }
+ if(!pic_burn(astribank, picdata)) {
+ ERR("PIC %s burning failed\n", curr);
+ return -ENODEV;
+ }
+ free_hexdata(picdata);
+ }
+ if((i = send_picline(astribank, 0, PIC_ENDS_FLAG, 0, NULL, 0)) != 0) {
+ ERR("PIC end burning failed\n");
+ return -ENODEV;
+ }
+ return 0;
+}
diff --git a/kernel/xpp/utils/pic_loader.h b/kernel/xpp/utils/pic_loader.h
new file mode 100644
index 0000000..f871bca
--- /dev/null
+++ b/kernel/xpp/utils/pic_loader.h
@@ -0,0 +1,46 @@
+#ifndef PIC_LOADER_H
+#define PIC_LOADER_H
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2008, 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 <stdint.h>
+#include "astribank_usb.h"
+
+/*
+ * Astribank PIC loading
+ */
+
+enum pic_command {
+ PIC_DATA_FLAG = 0x00,
+ PIC_START_FLAG = 0x01,
+ PIC_END_FLAG = 0x02,
+ PIC_ENDS_FLAG = 0x04,
+};
+
+#define PIC_PACK_LEN 0x0B
+#define PIC_LINE_LEN 0x03
+
+int send_picline(struct astribank_device *astribank, uint8_t card_type,
+ enum pic_command pcmd, int offs, uint8_t *data, int data_len);
+int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[]);
+
+#endif /* PIC_LOADER_H */
diff --git a/kernel/xpp/utils/twinstar b/kernel/xpp/utils/twinstar
new file mode 100755
index 0000000..1c4fe78
--- /dev/null
+++ b/kernel/xpp/utils/twinstar
@@ -0,0 +1,160 @@
+#! /usr/bin/perl -w
+#
+# Written by Oron Peled <oron@actcom.co.il>
+# Copyright (C) 2007, Xorcom
+# This program is free software; you can redistribute and/or
+# modify it under the same terms as Perl itself.
+#
+# $Id$
+#
+use strict;
+use File::Basename;
+use Getopt::Std;
+BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); }
+
+use Zaptel;
+use Zaptel::Hardware;
+use Zaptel::Span;
+use Zaptel::Xpp;
+use Zaptel::Xpp::Xbus;
+use Zaptel::Xpp::Mpp;
+
+sub usage {
+ die "Usage: $0 {status|jump|enable-wd|disable-wd|ports}\n";
+}
+
+our ($opt_v, $opt_x);
+getopts('vx') || usage;
+@ARGV == 1 or usage;
+
+
+# Find USB bus toplevel
+my $usb_top;
+$usb_top = '/dev/bus/usb';
+$usb_top = '/proc/bus/usb' unless -d $usb_top;
+die "No USB toplevel found\n" unless -d $usb_top;
+
+sub tws_devs() {
+ my @devs;
+ foreach my $dev (Zaptel::Hardware->device_list) {
+ next unless $dev->is_astribank;
+ next unless $dev->product =~ /116./;
+ push(@devs, $dev->hardware_name);
+ }
+ return @devs;
+}
+
+sub tws_usb_devfile($) {
+ my $name = shift || die;
+ # Remove prefix
+ if($name !~ s/usb://) {
+ die "$name is not a USB name\n";
+ }
+ return "$usb_top/$name";
+}
+
+sub tws_show(@) {
+ my @usb_devs = @_;
+ my $format = "%-15s %-10s %-15s %-10s %-10s\n";
+
+ printf $format, 'DEVICE', 'PORT', 'WATCHDOG', 'POWER0', 'POWER1';
+ foreach my $dev (@usb_devs) {
+ my $mppinfo = $dev->mppinfo;
+ if(!defined $mppinfo) {
+ printf STDERR "%s: no MPP information\n", $dev->hardware_name;
+ next;
+ }
+ if(!defined $mppinfo->{TWINSTAR_PORT}) {
+ printf STDERR "%s: no TWINSTAR_PORT information\n", $dev->hardware_name;
+ next;
+ }
+ my $power = $mppinfo->twinstar_power;
+ printf $format,
+ $dev->hardware_name,
+ $mppinfo->twinstar_port,
+ ($mppinfo->twinstar_watchdog) ? "on" : "off",
+ ($power->[0]) ? "yes" : "no",
+ ($power->[1]) ? "yes" : "no";
+ }
+}
+
+sub tws_portnum($) {
+ my $dev = shift || die "Missing dev";
+ my $mppinfo = $dev->mppinfo;
+ if(!defined $mppinfo) {
+ printf STDERR "%s: no MPP information\n", $dev->hardware_name;
+ return undef;
+ }
+ return $mppinfo->twinstar_port;
+}
+
+sub tws_showports(@) {
+ my @usb_devs = @_;
+ foreach my $dev (@usb_devs) {
+ my $mppinfo = $dev->mppinfo;
+ if(!defined $mppinfo) {
+ printf STDERR "%s: no MPP information\n", $dev->hardware_name;
+ next;
+ }
+ if(!defined $mppinfo->{TWINSTAR_PORT}) {
+ printf STDERR "%s: no TWINSTAR_PORT information\n", $dev->hardware_name;
+ next;
+ }
+ printf "%s\n", $mppinfo->{TWINSTAR_PORT};
+ }
+}
+
+sub tws_watchdog($@) {
+ my $on = shift;
+ die "tws_watchdog() on/off?" unless defined $on;
+ my @usb_devs = @_;
+
+ foreach my $dev (@usb_devs) {
+ my $mppinfo = $dev->mppinfo;
+ if(!defined $mppinfo) {
+ printf STDERR "%s: no MPP information\n", $dev->hardware_name;
+ next;
+ }
+ $mppinfo->mpp_setwatchdog($on);
+ }
+}
+
+sub tws_jump(@) {
+ my @usb_devs = @_;
+
+ foreach my $dev (@usb_devs) {
+ my $mppinfo = $dev->mppinfo;
+ if(!defined $mppinfo) {
+ printf STDERR "%s: no MPP information\n", $dev->hardware_name;
+ next;
+ }
+ $mppinfo->mpp_jump;
+ }
+}
+
+sub dev_list() {
+ my @devs;
+ foreach my $dev (Zaptel::Hardware->device_list) {
+ next unless $dev->is_astribank;
+ next unless $dev->product =~ /116./;
+ Zaptel::Xpp::Mpp->mpp_addinfo($dev);
+ push(@devs, $dev);
+ }
+ return @devs;
+}
+
+my @usb_devices = dev_list();
+
+if($ARGV[0] eq 'status') {
+ tws_show(@usb_devices);
+} elsif($ARGV[0] eq 'jump') {
+ tws_jump(@usb_devices);
+} elsif($ARGV[0] eq 'disable-wd') {
+ tws_watchdog(0, @usb_devices);
+} elsif($ARGV[0] eq 'enable-wd') {
+ tws_watchdog(1, @usb_devices);
+} elsif($ARGV[0] eq 'ports') {
+ tws_showports(@usb_devices);
+}
+
+__END__
diff --git a/kernel/xpp/utils/twinstar_hook b/kernel/xpp/utils/twinstar_hook
new file mode 100755
index 0000000..c934e7e
--- /dev/null
+++ b/kernel/xpp/utils/twinstar_hook
@@ -0,0 +1,132 @@
+#! /bin/sh
+#
+# Written by Oron Peled <oron@actcom.co.il>
+# Copyright (C) 2009, 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.
+#
+
+#
+# This is an experimental script to activate an Astribank TwinStar
+# during failover.
+#
+# The script assume that there is an /etc/xpp_order file
+# specifying the Astribanks' labels according to the required
+# registration order.
+#
+# This file can be easily generated by running:
+# zapconf xpporder
+# after the system is configured and working.
+#
+
+me=`basename $0`
+dir=`dirname $0`
+LOGGER="logger -i -t '$me'"
+
+# Always redirect stderr somewhere, otherwise the shell script will die
+# when it tries to do I/O related stuff on closed file descriptor.
+# Our default is to throw it down the bit-bucket.
+#exec 2> /dev/console
+## If you wish to trace this script:
+#exec 2> "/tmp/${me}_$XBUS_NAME" 1>&2
+
+# Our directory in the beginning, so we can use local lab setup
+PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin"
+
+set -e
+
+# For lab testing
+liveconf="$dir/liveconf/zaptel"
+
+if [ -d "$liveconf" ]; then
+ zaptel_conf="$liveconf"
+else
+ zaptel_conf="/etc"
+fi
+
+export XPPORDER_CONF="$zaptel_conf/xpp_order"
+if [ ! -r "$XPPORDER_CONF" ]; then
+ echo "Skip($ACTION): No '$XPPORDER_CONF'" | $LOGGER
+ exit 0
+fi
+ZAPTELCONF="$zaptel_conf/zaptel.conf"
+
+TWS_DIR="/var/tmp"
+TWS_PREFIX="$TWS_DIR/twinstar-"
+LABELFILE="/sys/$DEVPATH/label"
+export XBUS_SORT='SORT_LABEL'
+
+echo "starting($ACTION): setup from $XPPORDER_CONF" | $LOGGER
+STAMP="${TWS_PREFIX}${XBUS_NAME}"
+TWS_TOTAL=`sed -e 's/#.*//' -e '/^[ ]*$/d' -e 'y/\t/ /' "$XPPORDER_CONF" | wc -l`
+
+case "$ACTION" in
+online)
+ if [ ! -f "$LABELFILE" ]; then
+ echo "Missing labelfile '$LABELFILE'" | $LOGGER
+ exit 1
+ fi
+ LABEL=`cat $LABELFILE`
+ TWS_LINE=`awk "/^$LABEL/" $XPPORDER_CONF`
+ if [ "$TWS_LINE" = "" ]; then
+ echo "online($XBUS_NAME): '$LABEL' is not in '$XPPORDER_CONF'" | $LOGGER
+ exit 1
+ fi
+ echo "$LABEL" > "$STAMP"
+ HOW_MANY=`ls ${TWS_PREFIX}* | wc -l`
+ echo "online($XBUS_NAME): $LABEL (${HOW_MANY}/${TWS_TOTAL})" | $LOGGER
+ twinstar enable-wd
+ if [ "$HOW_MANY" -eq "$TWS_TOTAL" ]; then
+ echo "online: GOT ALL $TWS_TOTAL" | $LOGGER
+ zt_registration on
+ zt_registration 2>&1 | tr '\t' ' ' | $LOGGER
+ echo "Using '$ZAPTELCONF'" 2>&1 | $LOGGER
+ ztcfg -v -c "$ZAPTELCONF" 2>&1 | $LOGGER
+ sleep 1 # Just for visual effect
+ asterisk -rx 'module load chan_zap.so' 2>&1 | $LOGGER
+ xpp_blink bzzt xpd "$XBUS_NUM"
+ ports=`twinstar ports`
+ if [ "$ports" = 0 ]; then
+ play /usr/share/zaptel/primary-pbx-is-ready.wav || :
+ elif [ "$ports" = 1 ]; then
+ play /usr/share/zaptel/backup-pbx-is-ready.wav || :
+ fi
+ echo "online: READY" | $LOGGER
+ fi
+ ;;
+offline)
+ LABEL=`cat $STAMP`
+ TWS_LINE=`awk "/^$LABEL/" $XPPORDER_CONF`
+ rm -f "$STAMP"
+ if [ "$TWS_LINE" = "" ]; then
+ echo "offline($XBUS_NAME): $LABEL is not in $XPPORDER_CONF" | $LOGGER
+ exit 1
+ fi
+ echo "offline($XBUS_NAME): $LABEL" | $LOGGER
+ twinstar disable-wd
+ # If we want to disconnect everybody
+ twinstar jump
+ asterisk -rx 'module unload chan_zap.so'
+ ;;
+*)
+ echo "$0: Unknown ACTION='$ACTION'" | $LOGGER
+ echo "$0: ARGS='$*'" | $LOGGER
+ echo "$0: ENV:" | $LOGGER
+ env | $LOGGER
+ exit 1
+esac
+
diff --git a/kernel/xpp/utils/twinstar_setup b/kernel/xpp/utils/twinstar_setup
new file mode 100644
index 0000000..d2686b6
--- /dev/null
+++ b/kernel/xpp/utils/twinstar_setup
@@ -0,0 +1,155 @@
+#! /usr/bin/perl -w
+#
+# Written by Oron Peled <oron@actcom.co.il>
+# Copyright (C) 2009, Xorcom
+# This program is free software; you can redistribute and/or
+# modify it under the same terms as Perl itself.
+#
+# $Id$
+#
+use strict;
+use File::Basename;
+BEGIN {
+ my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf");
+ $ENV{PATH} = "$dir:$ENV{PATH}";
+}
+
+use Zaptel::Config::Gen qw(is_true);
+use Zaptel::Hardware;
+use Zaptel::Xpp::Mpp;
+use Zaptel::Xpp::Xbus;
+
+my $xpporder_file = $ENV{XPPORDER_CONF} || "/etc/xpp_order";
+
+my @devices = Zaptel::Hardware->device_list;
+my @xbuses = Zaptel::Xpp::xbuses;
+
+my $format = "%-20s %-10s # %s\n";
+
+sub bad_xpds($) {
+ my $xbus = shift || die;
+ my $bad_xpds = 0;
+
+ foreach my $xpd ($xbus->xpds) {
+ if(! $xpd->spanno) {
+ my $fqn = $xpd->fqn;
+ warn "\t$fqn -- Not registered with ZAPTEL\n";
+ $bad_xpds++;
+ }
+ }
+ return $bad_xpds;
+}
+
+sub twinstar_checks() {
+ my @twinstar_good;
+ my $first_port;
+ if(! -d "/sys/bus/astribanks") {
+ die "CANNOT generate TwinStar setup -- xpp drivers are not loaded\n";
+ }
+ foreach my $dev (@devices) {
+ my $hwname = $dev->hardware_name;
+ my $xbus;
+ my $loaded;
+ my $tws_port;
+ my $tws_power;
+ my $tws_watchdog;
+ my $mppinfo;
+ if(! $dev->is_astribank) {
+ warn "SKIP $hwname -- Only Astribanks can be used for TwinStar\n";
+ next;
+ }
+ Zaptel::Xpp::Mpp->mpp_addinfo($dev);
+ $mppinfo = $dev->mppinfo;
+ if(! defined $mppinfo) {
+ warn "SKIP $hwname -- is not TwinStar ready\n";
+ next;
+ }
+ if(! defined $mppinfo->{MPP_TALK}) {
+ warn "SKIP $hwname -- USB firmware is not loaded\n";
+ next;
+ }
+ if(! $mppinfo->{TWINSTAR_CAPABLE}) {
+ warn "SKIP $hwname -- is not TwinStar capable\n";
+ next;
+ }
+ $xbus = $dev->xbus;
+ if(! defined $xbus) {
+ warn "SKIP $hwname -- No XBUS for this device (FPGA firmware? Initialization?)\n";
+ next;
+ }
+ my $dev = $xbus->transport;
+ my $connector = $xbus->connector;
+ my $label = $xbus->label;
+ my $xbusstr = sprintf "%s (%s) [%s]", $xbus->name, $connector, $label;
+ if(bad_xpds($xbus)) {
+ warn "SKIP $xbusstr -- Not registered with ZAPTEL\n";
+ next;
+ }
+ my $port = $mppinfo->{TWINSTAR_PORT};
+ if(! defined $port) {
+ warn "SKIP $xbusstr -- Cannot read USB port info\n";
+ next;
+ }
+ my $power = $mppinfo->{TWINSTAR_POWER};
+ if(! defined $power) {
+ warn "SKIP $xbusstr -- Cannot read USB power info\n";
+ next;
+ }
+ if(!$power->[0] || !$power->[1]) {
+ warn "WARNING: Only one cable: $xbusstr\n";
+ }
+ $first_port = $port unless defined $first_port;
+ printf "GOOD: %-15s port=%d %s\n", $label, $port, $connector;
+ push(@twinstar_good, $xbus);
+ if($first_port != $port) {
+ die
+ "$0: ",
+ "XBUS($connector, $label) ",
+ "connected to PORT $port ",
+ "(others to $first_port)\n";
+ }
+ }
+ return @twinstar_good;
+}
+
+my @twinstar_good = twinstar_checks;
+if(!@twinstar_good) {
+ print STDERR "Abort. No Twinstar capable Astribanks found\n";
+ exit 1;
+}
+print "Generating Configuration\n";
+system("zapconf -v xpporder");
+die "Failed: $?\n" if $?;
+
+1;
+
+__END__
+
+=head1 NAME
+
+twinstar_setup - Prepares a server for Astribank TwinStar operation.
+
+=head1 DESCRIPTION
+
+This script prepares a server for Astribank TwinStar operation.
+The stages are:
+
+=over
+
+=item Preliminary checks
+
+Check that we have only TwinStar capable Astribanks, that the drivers are already loaded.
+
+=item Configuration Generation
+
+Indirectly generate the F</etc/xpp_order> file that describes the current configuration.
+This is done by running C<zapconf xpporder>
+
+This configuration file is used by twinstar_hook(8) to know when all Astribanks has reconnected
+to the backup server.
+
+=item Deployment to Backup Server
+
+Not implemented yet. Should be done manualy.
+
+=back
diff --git a/kernel/xpp/utils/xpp.rules b/kernel/xpp/utils/xpp.rules
index d3cc226..4a26484 100644
--- a/kernel/xpp/utils/xpp.rules
+++ b/kernel/xpp/utils/xpp.rules
@@ -3,7 +3,7 @@ KERNEL=="*_ep*", GOTO="xpp_usb_add_end"
KERNEL=="[0-9]*", GOTO="xpp_usb_add_end"
# Load firmware into the Xorcom Astribank device:
-SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="11[345][01]", \
+SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="11[3456][01]", \
RUN+="/usr/share/zaptel/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/$sysfs{bcdDevice}"
LABEL="xpp_usb_add_end"
diff --git a/kernel/xpp/utils/xpp_fxloader b/kernel/xpp/utils/xpp_fxloader
index 925ee97..feaf712 100755
--- a/kernel/xpp/utils/xpp_fxloader
+++ b/kernel/xpp/utils/xpp_fxloader
@@ -2,13 +2,34 @@
# xpp_fxloader: load Xorcom Astribank (XPP) firmware
#
+# Written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
+# Copyright (C) 2006, 2007, 2008, 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.
+#
+
+#
# This script can be run manually or from hotplug/udev.
#
# Firmware files should be located in $FIRMWARE_DIR which defaults:
# 1. /usr/share/zaptel
# 2. Can be overidden by setting $FIRMWARE_DIR in the environment
-# 3. Can be overidden by setting $FIRMWARE_DIR in /etc/default/zaptel
-#
+# 3. Can be overidden by setting $FIRMWARE_DIR in /etc/sysconfig/zaptel (Red Hat derivatives)
+# or /etc/default/zaptel (Debian derivatives)
# Manual Run
# ##########
#
@@ -76,10 +97,9 @@ DEVUSB_PREFIX=/dev/bus/usb
USB_PREFIX=
FIRMWARE_DIR="${FIRMWARE_DIR:-/usr/share/zaptel}"
+ASTRIBANK_HEXLOAD=${ASTRIBANK_HEXLOAD:-/usr/sbin/astribank_hexload}
+ASTRIBANK_TOOL=${ASTRIBANK_TOOL:-/usr/sbin/astribank_tool}
-FIRM_FXS=$FIRMWARE_DIR/FPGA_FXS.hex
-
-FPGA_LOAD=${FPGA_LOAD:-/usr/sbin/fpga_load}
USB_FW="${USB_FW:-USB_FW.hex}"
if [ -r "$DEFAULTS" ]; then
@@ -112,12 +132,37 @@ find_dev() {
lsusb | tr -d : | awk "/ ID $v_id$p_id/{printf \"$USB_PREFIX/%s/%s \",\$2,\$4}"
}
-do_fxload() {
+run_fxload() {
sleep_if_race
- ( fxload -t fx2 $* 2>&1 1>/dev/null || exit 1 ) | $LOGGER
+ fxload -t fx2 $* 2>&1 1>/dev/null | $LOGGER
+ status=$PIPESTATUS
+ if [ $status != 0 ]; then
+ $LOGGER "fxload failed with status $status"
+ exit 55
+ fi
}
-load_fw() {
+run_astribank_hexload() {
+ $LOGGER "Running: $ASTRIBANK_HEXLOAD $*"
+ $ASTRIBANK_HEXLOAD "$@" | $LOGGER
+ status=$PIPESTATUS
+ if [ $status != 0 ]; then
+ $LOGGER "$ASTRIBANK_HEXLOAD failed with status $status"
+ exit 77
+ fi
+}
+
+run_astribank_tool() {
+ $LOGGER "Running: $ASTRIBANK_TOOL $*"
+ $ASTRIBANK_TOOL "$@" | $LOGGER
+ status=$PIPESTATUS
+ if [ $status != 0 ]; then
+ $LOGGER "$ASTRIBANK_TOOL failed with status $status"
+ exit 77
+ fi
+}
+
+load_usb_fw() {
v_id=$1
p_id=$2
fw=$3
@@ -125,34 +170,48 @@ load_fw() {
devices=`find_dev $v_id $p_id`
for dev in $devices
do
- $LOGGER "USB Firmware $FIRMWARE_DIR/$fw into $dev"
- do_fxload -D $dev -I $FIRMWARE_DIR/$fw || exit 1
+ ver=$(awk '/\$Id:/ { print $4 }' $FIRMWARE_DIR/$fw)
+ $LOGGER "USB Firmware $FIRMWARE_DIR/$fw (Version=$ver) into $dev"
+ run_fxload -D $dev -I $FIRMWARE_DIR/$fw || exit 1
done
}
-load_fpga() {
+load_fw_device() {
+ dev=$1
+ fw=$2
+ $LOGGER "FPGA loading $fw into $dev"
+ run_astribank_hexload -D "$dev" -F "$FIRMWARE_DIR/$fw"
+ pic_files=`echo "$FIRMWARE_DIR"/PIC_TYPE_[1-4].hex`
+ $LOGGER "PIC burning into $dev: $pic_files"
+ run_astribank_hexload -D "$dev" -p $pic_files
+ run_astribank_tool -D "$dev" -n # Do renumeration!
+ $LOGGER "PIC burning finished $pic_files"
+}
+
+#
+# Use in manual loading. Parallelize loading
+# firmwares to all of our devices
+#
+firmware_by_id() {
v_id=$1
p_id=$2
fw=$3
devices=`find_dev $v_id $p_id`
+ childs=""
for dev in $devices
do
(
- card_ver=`$FPGA_LOAD -g -D $dev | sed -n 's/^.*Release: *//'`
+ set -e
- $LOGGER "FPGA Firmware into $dev"
+ load_fw_device "$dev" "$fw"
sleep_if_race
- $FPGA_LOAD -D "$dev" -I "$FIRMWARE_DIR/$fw" -i | $LOGGER
- status=$PIPESTATUS
- if [ $status != 0 ]; then
- echo "fpga_load failed with status $status" | $LOGGER
- exit 77
- fi
) &
+ childs="$childs $!"
sleep 0.4
done
- wait
+ # Wait for specific childs to get their exit status
+ wait $childs
}
numdevs() {
@@ -188,23 +247,26 @@ wait_renumeration() {
reset_fpga() {
totaldevs=`numdevs e4e4 '11[3456][012]'`
devices=`find_dev e4e4 '11[3456][12]'`
- echo "Reseting devices [$totaldevs devices]"
+ $LOGGER "Reseting devices [$totaldevs devices]"
for dev in $devices
do
$LOGGER "Resetting FPGA Firmware on $dev"
sleep_if_race
- $FPGA_LOAD -D "$dev" -r 2>&1 >/dev/null | $LOGGER
- status=$PIPESTATUS
- if [ "$status" != 0 ]; then
- echo "fpga_load failed removing with status $status" | $LOGGER
- exit 78
- fi
+ run_astribank_tool -D "$dev" -r full 2>&1 >/dev/null
done
if [ "$1" = 'wait' ]; then
wait_renumeration $totaldevs e4e4 '11[3456]0'
fi
}
+usage() {
+ echo "$0: Astribank firmware loading script."
+ echo "Usage: "
+ echo "$0 load : manual firmware loading."
+ echo "$0 usb : manual firmware loading: USB firmware only."
+ echo "$0 help : this text."
+}
+
#########################
##
## Manual run
@@ -226,36 +288,38 @@ reset)
;;
xppdetect|load|usb)
numdevs=`numdevs e4e4 '11[3456][01]'`
- echo "--------- FIRMWARE LOADING: ($1) [$numdevs devices]"
+ $LOGGER -- "--------- FIRMWARE LOADING: ($1) [$numdevs devices]"
- load_fw e4e4 1130 $USB_FW
- load_fw e4e4 1140 $USB_FW
- load_fw e4e4 1150 $USB_FW
- load_fw e4e4 1160 $USB_FW
+ load_usb_fw e4e4 1130 $USB_FW
+ load_usb_fw e4e4 1140 $USB_FW
+ load_usb_fw e4e4 1150 $USB_FW
+ load_usb_fw e4e4 1160 $USB_FW
wait_renumeration $numdevs e4e4 '11[3456]1'
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
- load_fpga e4e4 1161 FPGA_1161.hex
+ firmware_by_id e4e4 1131 FPGA_FXS.hex
+ firmware_by_id e4e4 1141 FPGA_1141.hex
+ firmware_by_id e4e4 1151 FPGA_1151.hex
+ firmware_by_id e4e4 1161 FPGA_1161.hex
wait_renumeration $numdevs e4e4 '11[3456]2'
fi
sleep 3 # Let it stabilize
- echo "--------- FIRMWARE IS LOADED"
+ $LOGGER -- "--------- FIRMWARE IS LOADED"
exit 0
;;
help)
- echo "$0: Astribank firmware loading script."
- echo "Usage: "
- echo "$0 load : manual firmware loading."
- echo "$0 usb : manual firmware loading: USB firmware only."
- echo "$0 help : this text."
- echo ""
- echo "('xppdetect' is an alias of 'load')"
+ usage
exit 0
;;
+*)
+ if [ "$ACTION" = '' ]; then # not called from hotplug
+ echo "$0: Error: unknown command \"$1\""
+ echo ''
+ usage
+ exit 1
+ fi
+ ;;
esac
#########################
@@ -274,19 +338,19 @@ then
$LOGGER "Trying to find what to do for product $PRODUCT, device $DEVICE"
prod_id=`echo "$PRODUCT" | cut -d/ -f2`
case "$PRODUCT" in
- e4e4/11[345]0/*)
+ e4e4/11[3456]0/*)
FIRM_USB="$FIRMWARE_DIR/$USB_FW"
$LOGGER "Loading firmware '$FIRM_USB' into '$DEVICE'"
- do_fxload -D "$DEVICE" -I "$FIRM_USB"
+ run_fxload -D "$DEVICE" -I "$FIRM_USB"
;;
- e4e4/11[345]1/*)
+ e4e4/11[3456]1/*)
if [ "$prod_id" = 1131 ]; then
- FIRM_FPGA="$FIRMWARE_DIR/FPGA_FXS.hex" # Legacy
+ FIRM_FPGA="FPGA_FXS.hex" # Legacy
else
- FIRM_FPGA="$FIRMWARE_DIR/FPGA_$prod_id.hex"
+ FIRM_FPGA="FPGA_$prod_id.hex"
fi
sleep_if_race
- $FPGA_LOAD -D "$DEVICE" -I "$FIRM_FPGA" 2>&1 >/dev/null | $LOGGER
+ load_fw_device "$DEVICE" "$FIRM_FPGA"
;;
esac
fi
diff --git a/kernel/xpp/utils/xpp_sync b/kernel/xpp/utils/xpp_sync
index 2840271..8167eb1 100755
--- a/kernel/xpp/utils/xpp_sync
+++ b/kernel/xpp/utils/xpp_sync
@@ -39,7 +39,7 @@ if(@ARGV == 1) {
sub get_sorted_xpds() {
my @good_xpds;
- foreach my $xbus (Zaptel::Xpp::xbuses('SORT_CONNECTOR')) {
+ foreach my $xbus (Zaptel::Xpp::xbuses) {
next unless $xbus->status eq 'CONNECTED';
foreach my $xpd ($xbus->xpds()) {
my $isreg = $xpd->zt_registration();
@@ -198,7 +198,7 @@ from the '+' beside it.
xpp_sync is normally called from the zaptel init.d script.
The parameter it is called with defaults to
I<auto>, but it is possible to override that parameter (e.g: set it to
-I<zaptel>) through the value of XPP_SYNC in either /etc/defualt/zaptel
+I<zaptel>) through the value of XPP_SYNC in either /etc/default/zaptel
or /etc/sysconfig/zaptel .
=head1 FILES
@@ -207,8 +207,13 @@ or /etc/sysconfig/zaptel .
=item /proc/xpp/sync
+(Deprecated: no longer supported)
xpp_sync is essentially a nicer interface to /proc/xpp/sync . That file
shows the current xpp sync master (and in what format you need to write
to it to set the master).
+=head1 SEE ALSO
+
+zt_registration(1), ztcfg(1), README.Astribank
+
=back
diff --git a/kernel/xpp/utils/zapconf b/kernel/xpp/utils/zapconf
index ac1af0b..9991611 100755
--- a/kernel/xpp/utils/zapconf
+++ b/kernel/xpp/utils/zapconf
@@ -128,7 +128,7 @@ It uses two information sources:
The actual zaptel hardware is automatically detected on the host.
-=item /etc/genconf_params
+=item /etc/genconf_parameters
A configuration file that supplements the hardware information.
Its location may be overriden via the C<GENCONF_PARAMETERS> environment
diff --git a/kernel/xpp/utils/zaptel_drivers b/kernel/xpp/utils/zaptel_drivers
index 5ace08b..e53d56f 100755
--- a/kernel/xpp/utils/zaptel_drivers
+++ b/kernel/xpp/utils/zaptel_drivers
@@ -24,7 +24,7 @@ if(-f $zaptel_redhat) {
die "$0: Could not find '$zaptel_redhat' nor '$zaptel_debian'\n";
}
-my $hardware = Zaptel::Hardware->scan;
+my @drivers = Zaptel::Hardware->drivers;
sub update_zaptel_distro(@) {
my @driver_list = @_;
@@ -110,14 +110,14 @@ sub update_etc_modules(@) {
}
if($opts{'d'}) {
- update_etc_modules($hardware->drivers);
+ update_etc_modules(@drivers);
}
if($opts{'M'}) {
- update_zaptel_distro($hardware->drivers);
+ update_zaptel_distro(@drivers);
}
if(!$opts{'d'} && !$opts{'M'}) {
- print join("\n", $hardware->drivers),"\n";
+ print join("\n", @drivers),"\n";
}
__END__
diff --git a/kernel/xpp/utils/zaptel_hardware b/kernel/xpp/utils/zaptel_hardware
index 004a44b..81823f1 100755
--- a/kernel/xpp/utils/zaptel_hardware
+++ b/kernel/xpp/utils/zaptel_hardware
@@ -17,16 +17,16 @@ use Zaptel::Span;
use Zaptel::Xpp;
use Zaptel::Xpp::Xbus;
use Zaptel::Hardware;
+use Zaptel::Xpp::Mpp;
sub usage {
- die "Usage: $0 [-v][-x]\n";
+ die "Usage: $0 [-v][-x][-t]\n";
}
-our ($opt_v, $opt_x);
-getopts('vx') || usage;
+my %opts;
+getopts('vxt', \%opts) || usage;
@ARGV == 0 or usage;
-my $hardware = Zaptel::Hardware->scan;
my @spans = Zaptel::spans;
sub show_xbus($) {
@@ -37,6 +37,7 @@ sub show_xbus($) {
printf " LABEL=%-20s CONNECTOR=%-20s\n", $label, $connector;
foreach my $xpd (@xpds) {
my $reg = $xpd->zt_registration;
+ my $channels = '(' . $xpd->channels . ')';
my $span;
my $spanstr;
if($reg && @spans) {
@@ -48,7 +49,7 @@ sub show_xbus($) {
my $master = '';
#$master = "XPP-SYNC" if $xpd->is_sync_master;
$master .= " ZAPTEL-SYNC" if defined($span) && $span->is_zaptel_sync_master;
- printf "\t%-10s: %-8s %s %s\n", $xpd->fqn, $xpd->type, $spanstr, $master;
+ printf "\t%-10s: %-8s %-5s %s %s\n", $xpd->fqn, $xpd->type, $channels, $spanstr, $master;
}
}
@@ -59,37 +60,68 @@ sub show_disconnected(%) {
my %seen = @_;
my $notified_lost = 0;
- foreach my $xbus (Zaptel::Xpp::xbuses('SORT_CONNECTOR')) {
+ foreach my $xbus (Zaptel::Xpp::xbuses) {
if(!$seen{$xbus->name}) {
print "----------- XPP Spans with disconnected hardware -----------\n"
unless $notified_lost++;
printf($format, $xbus->name, '', '', '', "NO HARDWARE");
- show_xbus($xbus) if $opt_v;
+ show_xbus($xbus) if $opts{'v'};
}
}
}
-foreach my $dev ($hardware->device_list) {
+# FIXME: For verbose display we also need to see the XPP devices.
+# If no spans are registered, this won't happen. A brute-force
+# methood for making it happe:
+Zaptel::Xpp::xbuses if ($opts{'v'});
+
+my @devices = Zaptel::Hardware->device_list;
+foreach my $dev (@devices) {
my $driver = $dev->driver || "";
my $xbus;
my $loaded;
+ my $tws_port;
+ my $tws_power;
+ my $tws_watchdog;
+ my $mppinfo;
if($dev->is_astribank) {
$xbus = $dev->xbus;
+ if($opts{'v'} || $opts{'t'}) {
+ Zaptel::Xpp::Mpp->mpp_addinfo($dev);
+ $mppinfo = $dev->mppinfo;
+ if(defined $mppinfo) {
+ $tws_port = $mppinfo->{TWINSTAR_PORT};
+ $tws_power = $mppinfo->{TWINSTAR_POWER};
+ $tws_watchdog = $mppinfo->{TWINSTAR_WATCHDOG};
+ }
+ }
}
$loaded = $dev->loaded;
warn "driver should be '$driver' but is actually '$loaded'\n"
if defined($loaded) && $driver ne $loaded;
$driver = "$driver" . (($loaded) ? "+" : "-");
+ if(defined $tws_power && defined $tws_watchdog) {
+ my $tws_active = $tws_watchdog && $tws_power->[0] && $tws_power->[1];
+ $driver .= "[T]" if $tws_active;
+ }
my $description = $dev->description || "";
printf $format, $dev->hardware_name, $driver, $dev->vendor, $dev->product, $description;
+ if($opts{'v'} && defined $mppinfo && exists $mppinfo->{MPP_TALK}) {
+ printf " MPP: TWINSTAR_PORT=$tws_port\n" if defined $tws_port;
+ printf " MPP: TWINSTAR_WATCHDOG=$tws_watchdog\n" if defined $tws_watchdog;
+ for(my $i = 0; $i < 2; $i++) {
+ printf " MPP: TWINSTAR_POWER[%d]=%d\n",
+ $i, $tws_power->[$i] if defined $tws_power;
+ }
+ }
if(!defined $xbus || !$xbus) {
next;
}
$seen{$xbus->name} = 1;
- show_xbus($xbus) if $opt_v;
+ show_xbus($xbus) if $opts{'v'};
}
-show_disconnected(%seen) if $opt_x;
+show_disconnected(%seen) if $opts{'x'};
__END__
diff --git a/kernel/xpp/utils/zconf/Zaptel.pm b/kernel/xpp/utils/zconf/Zaptel.pm
index 1b73d5b..a7784f9 100644
--- a/kernel/xpp/utils/zconf/Zaptel.pm
+++ b/kernel/xpp/utils/zconf/Zaptel.pm
@@ -46,6 +46,7 @@ sub spans() {
-d $proc_base or return ();
foreach my $zfile (glob "$proc_base/*") {
$zfile =~ s:$proc_base/::;
+ next unless ($zfile =~ /^\d+$/);
my $span = Zaptel::Span->new($zfile);
push(@spans, $span);
}
diff --git a/kernel/xpp/utils/zconf/Zaptel/Chans.pm b/kernel/xpp/utils/zconf/Zaptel/Chans.pm
index aa58d1d..3090b8a 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Chans.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Chans.pm
@@ -139,21 +139,25 @@ sub new($$$$$$) {
$type = "FXS"; # likely Rhino
} elsif ($fqn =~ m{\bFXO/.*}) {
$type = "FXO"; # likely Rhino
- } elsif ($fqn =~ m{\b---/.*}) {
+ } elsif ($fqn =~ m{---/.*}) {
$type = "EMPTY"; # likely Rhino, empty slot.
- } elsif ($fqn =~ m{\b(TE[24]|WCT1|Tor2|TorISA|WP[TE]1|cwain[12])/.*}) {
+ } elsif ($fqn =~ m{\b(TE[24]|WCT1|Tor2|TorISA|WP[TE]1|cwain[12]|R[124]T1)/.*}) {
# TE[24]: Digium wct4xxp
# WCT1: Digium single span card drivers?
# Tor2: Tor PCI cards
# TorISA: ISA ones (still used?)
# WP[TE]1: Sangoma. TODO: this one tells us if it is TE or NT.
# cwain: Junghanns E1 card.
+ # R[124]: Rhino r1t1/rxt1 cards
$type = "PRI";
} elsif ($fqn =~ m{\b(B4|ZTHFC\d*|ztqoz\d*)/.*}) {
# B4: The Digium wcb4xxp ZAPTEL driver
# ZTHFC: HFC-s single-port card (zaphfc/vzaphfc)
# ztqoz: qozap (Junghanns) multi-port HFC card
$type = "BRI";
+ } elsif ($fqn =~ m{\bZTD/.*}) {
+ # DYN : Dynamic span (TDMOE)
+ $type = "ZTD"
} elsif ($fqn =~ m{\bztgsm/.*}) {
# Junghanns GSM card
$type = "GSM";
@@ -189,7 +193,7 @@ sub probe_type($) {
my $num = $self->num;
my $type;
- if($fqn =~ m:WCTDM/| WRTDM/|OPVXA1200/:) {
+ if($fqn =~ m:WCTDM/|WRTDM/|OPVXA1200/:) {
my %maybe;
undef %maybe;
diff --git a/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Unicall.pm b/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Unicall.pm
index 3e1048d..6d9552f 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Unicall.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Unicall.pm
@@ -32,7 +32,9 @@ sub generate($) {
print "Generating $file\n" if $genopts->{verbose};
open(F, ">$file") || die "$0: Failed to open $file: $!\n";
my $old = select F;
- printf "; Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime);
+ printf "; Autogenerated by $0 on %s\n", scalar(localtime);
+ print "; If you edit this file and execute $0 again,\n";
+ print "; your manual changes will be LOST.\n";
print "; This file should be #included in unicall.conf\n\n";
foreach my $span (@spans) {
next unless $span->is_digital();
diff --git a/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Users.pm b/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Users.pm
index 7c9e937..dbbf9d2 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Users.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Users.pm
@@ -88,6 +88,8 @@ sub generate($) {
;! Filename: @{[basename($file)]} ($file)
;! Generator: $0
;! Creation Date: @{[scalar(localtime)]}
+;! If you edit this file and execute $0 again,\n";
+;! your manual changes will be LOST.\n";
;!
[general]
;
diff --git a/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Xpporder.pm b/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Xpporder.pm
new file mode 100644
index 0000000..0d34d93
--- /dev/null
+++ b/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Xpporder.pm
@@ -0,0 +1,142 @@
+package Zaptel::Config::Gen::Xpporder;
+use strict;
+
+use Zaptel::Config::Gen qw(is_true);
+use Zaptel::Xpp;
+
+sub new($$$) {
+ my $pack = shift || die;
+ my $gconfig = shift || die;
+ my $genopts = shift || die;
+ my $file = $ENV{XPPORDER_CONF} || "/etc/xpp_order";
+ my $self = {
+ FILE => $file,
+ GCONFIG => $gconfig,
+ GENOPTS => $genopts,
+ };
+ bless $self, $pack;
+ return $self;
+}
+
+#
+# Returns list of xbuses sorted by the span numbers assigned
+# to their XPD's. Also checks that each XBUS span numbers are sequential.
+sub get_sorted_xbuses(@) {
+ my @spans = @_; # Verify our spans
+ my @xbuses = Zaptel::Xpp::xbuses;
+ my %xbus_of_span;
+ my %xbus_beginning;
+ my %seen_spans;
+ my @sorted_xbuses;
+ foreach my $xbus (@xbuses) {
+ my $last_spanno;
+ foreach my $xpd ($xbus->xpds) {
+ my $spanno = $xpd->spanno;
+ if(!$spanno) {
+ printf STDERR "%s: Is not registered. Skipping.\n", $xpd->fqn;
+ next;
+ }
+ $seen_spans{$spanno}++;
+ if($xbus_of_span{$spanno}) {
+ printf STDERR "%s: Span %d already seen on %s\n",
+ $xpd->fqn, $spanno, $xbus_of_span{$spanno}->name;
+ die;
+ }
+ $xbus_of_span{$spanno} = $xbus;
+ # Check XPD's sequential numbering
+ if(defined $last_spanno) {
+ if($last_spanno + 1 != $spanno) {
+ printf STDERR "%s: Bad span numbers (%d, %d)\n",
+ $xpd->fqn, $last_spanno, $spanno;
+ die;
+ }
+ } else {
+ $xbus_beginning{$xbus} = $spanno;
+ }
+ $last_spanno = $spanno;
+ }
+ }
+ foreach my $span (@spans) {
+ my $spanno = $span->num;
+ if(!defined($seen_spans{$spanno})) {
+ warn "Span $spanno: Ignored: Does not belong to any XPD\n";
+ }
+ }
+ @sorted_xbuses = sort { $xbus_beginning{$a} <=> $xbus_beginning{$b} } @xbuses;
+ return @sorted_xbuses;
+}
+
+sub generate($$$) {
+ my $self = shift || die;
+ my $file = $self->{FILE};
+ my $gconfig = $self->{GCONFIG};
+ my $genopts = $self->{GENOPTS};
+ my @spans = @_; # Verify it's all our spans
+ my @xbuses = get_sorted_xbuses(@spans);
+ warn "Empty configuration -- no xbuses\n" unless @xbuses;
+ rename "$file", "$file.bak"
+ or $! == 2 # ENOENT (No dependency on Errno.pm)
+ or die "Failed to backup old config: $!\n";
+ #$gconfig->dump;
+ print "Generating $file\n" if $genopts->{verbose};
+ open(F, ">$file") || die "$0: Failed to open $file: $!\n";
+ my $old = select F;
+ printf "# Autogenerated by $0 on %s\n", scalar(localtime);
+ print "# If you edit this file and execute $0 again,\n";
+ print "# your manual changes will be LOST.\n";
+ print <<'HEAD';
+#
+# This is an optional configuration file for ordering
+# Zaptel registration.
+#
+# It is read from /etc/xpp_order. This location
+# may be overridden via the environment variable XPPORDER_CONF
+#
+# Lines may contain:
+# - The Astribank label (verbatim)
+# - The Astribank connector string (prefixed with @)
+# Ordering number of each listed Astribank is determined
+# by its position in this file.
+# Astribanks not listed in this file, get an ordering
+# number of 99 (last).
+#
+# Astribanks with same ordering number are sorted by their
+# connectors (to preserve legacy behavior).
+#
+# Examples:
+#usb:1234
+#@usb-0000:06:02.2-2
+HEAD
+ foreach my $xbus (@xbuses) {
+ my $label = $xbus->label;
+ my $connector = $xbus->connector;
+ my $name = $xbus->name;
+ printf "%s\t# %s (%s)\n", $label, $connector, $name;
+ }
+ close F;
+ select $old;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Xpporder - Generate Astribank ordering information for zt_registration.
+
+=head1 SYNOPSIS
+
+ use Zaptel::Config::Gen::Xpporder;
+
+ my $cfg = new Zaptel::Config::Gen::Xpporder(\%global_config, \%genopts);
+ $cfg->generate;
+
+=head1 DESCRIPTION
+
+Generate the F</etc/xpp_order>.
+This is the configuration for zt_registration(1).
+The order is determined according to current Zaptel registration
+order.
+
+Its location may be overriden via the environment variable F<XPPORDER_CONF>.
diff --git a/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zapata.pm b/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zapata.pm
index e8fd733..8e0ebce 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zapata.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zapata.pm
@@ -140,7 +140,9 @@ sub generate($) {
print "Generating $file\n" if $genopts->{verbose};
open(F, ">$file") || die "$0: Failed to open $file: $!\n";
my $old = select F;
- printf "; Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime);
+ printf "; Autogenerated by $0 on %s\n", scalar(localtime);
+ print "; If you edit this file and execute $0 again,\n";
+ print "; your manual changes will be LOST.\n";
print <<"HEAD";
; Zaptel Channels Configurations (zapata.conf)
;
diff --git a/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zaptel.pm b/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zaptel.pm
index 2c30c33..892442f 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zaptel.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zaptel.pm
@@ -39,11 +39,6 @@ sub gen_digital($$) {
$span_crc4 = '';
$framing = 'cas';
}
- my $dchan_type = 'dchan';
- if ($span->is_bri() && is_true($gconfig->{'bri_hardhdlc'})) {
- $dchan_type = 'hardhdlc';
- }
-
$timing = ($termtype eq 'NT') ? 0 : $bri_te_last_timing++;
printf "span=%d,%d,%d,%s,%s%s%s\n",
$num,
@@ -54,14 +49,42 @@ sub gen_digital($$) {
$span_crc4,
$span_yellow;
printf "# termtype: %s\n", lc($termtype);
- if ($gconfig->{'pri_connection_type'} eq 'PRI') {
+ my $dchan_type;
+ if ($span->is_bri()) {
+ my $use_bristuff = 0;
+ my $cfg_hardhdlc = $gconfig->{'bri_hardhdlc'};
+ my $xpd = $span->xpd();
+ if(!defined($cfg_hardhdlc) || $cfg_hardhdlc =~ /AUTO/i) {
+ # Autodetect
+ if(defined($xpd)) {
+ # Bristuff?
+ if(defined($xpd->dchan_hardhdlc) && !is_true($xpd->dchan_hardhdlc)) {
+ $use_bristuff = 1;
+ }
+ }
+ } elsif(!is_true($cfg_hardhdlc)) {
+ $use_bristuff = 1;
+ }
+ if($use_bristuff) {
+ $dchan_type = 'dchan';
+ } else {
+ $dchan_type = 'hardhdlc';
+ }
printf "bchan=%s\n", Zaptel::Config::Gen::bchan_range($span);
my $dchan = $span->dchan();
printf "$dchan_type=%d\n", $dchan->num();
- } elsif ($gconfig->{'pri_connection_type'} eq 'R2' ) {
- my $idle_bits = $gconfig->{'r2_idle_bits'};
- printf "cas=%s:$idle_bits\n", Zaptel::Config::Gen::bchan_range($span);
- printf "dchan=%d\n", $span->dchan()->num();
+ } elsif($span->is_pri()) {
+ if ($gconfig->{'pri_connection_type'} eq 'PRI') {
+ printf "bchan=%s\n", Zaptel::Config::Gen::bchan_range($span);
+ my $dchan = $span->dchan();
+ printf "dchan=%d\n", $dchan->num();
+ } elsif ($gconfig->{'pri_connection_type'} eq 'R2' ) {
+ my $idle_bits = $gconfig->{'r2_idle_bits'};
+ printf "cas=%s:$idle_bits\n", Zaptel::Config::Gen::bchan_range($span);
+ printf "dchan=%d\n", $span->dchan()->num();
+ }
+ } else {
+ die "Digital span $num is not BRI, nor PRI?";
}
}
@@ -100,7 +123,9 @@ sub generate($$$) {
print "Generating $file\n" if $genopts->{verbose};
open(F, ">$file") || die "$0: Failed to open $file: $!\n";
my $old = select F;
- printf "# Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime);
+ printf "# Autogenerated by $0 on %s\n", scalar(localtime);
+ print "# If you edit this file and execute $0 again,\n";
+ print "# your manual changes will be LOST.\n";
print <<"HEAD";
# Zaptel Configuration File
#
diff --git a/kernel/xpp/utils/zconf/Zaptel/Config/Params.pm b/kernel/xpp/utils/zconf/Zaptel/Config/Params.pm
index 7f6ae80..35ded3b 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Config/Params.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Config/Params.pm
@@ -106,7 +106,7 @@ sub item($$) {
brint_overlap => 'no',
bri_sig_style => 'bri_ptmp',
echo_can => 'mg2',
- bri_hardhdlc => 'no',
+ bri_hardhdlc => 'auto',
pri_connection_type => 'PRI',
r2_idle_bits => '1101',
'pri_termtype' => [ 'SPAN/* TE' ],
diff --git a/kernel/xpp/utils/zconf/Zaptel/Hardware.pm b/kernel/xpp/utils/zconf/Zaptel/Hardware.pm
index ff7aeea..b12368b 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Hardware.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Hardware.pm
@@ -8,8 +8,6 @@ package Zaptel::Hardware;
# $Id$
#
use strict;
-use Zaptel::Hardware::USB;
-use Zaptel::Hardware::PCI;
=head1 NAME
@@ -44,6 +42,7 @@ system. It identifies devices by (USB/PCI) bus IDs.
=head1 Device Attributes
+
As usual, object attributes can be used in either upp-case or
lower-case, or lower-case functions.
@@ -92,22 +91,27 @@ attributes).
Astribank.
=cut
+#
+# A global hardware handle
+#
-sub device_detected($$) {
- my $dev = shift || die;
- my $name = shift || die;
- die unless defined $dev->{'BUS_TYPE'};
+my %hardware_list = (
+ 'PCI' => [],
+ 'USB' => [],
+ );
+
+
+sub new($$) {
+ my $pack = shift || die "Wasn't called as a class method\n";
+ my $name = shift || die "$0: Missing device name";
+ my $type = shift || die "$0: Missing device type";
+ my $dev = {};
+ $dev->{'BUS_TYPE'} = $type;
$dev->{IS_ASTRIBANK} = 0 unless defined $dev->{'IS_ASTRIBANK'};
$dev->{'HARDWARE_NAME'} = $name;
+ return $dev;
}
-sub device_removed($) {
- my $dev = shift || die;
- my $name = $dev->hardware_name;
- die "Missing zaptel device hardware name" unless $name;
-}
-
-
=head1 device_list()
Returns a list of the hardware devices on the system.
@@ -117,17 +121,28 @@ You must run scan() first for this function to run meaningful output.
=cut
sub device_list($) {
- my $self = shift || die;
+ my $pack = shift || die;
my @types = @_;
my @list;
@types = qw(USB PCI) unless @types;
foreach my $t (@types) {
- @list = ( @list, @{$self->{$t}} );
+ my $lst = $hardware_list{$t};
+ @list = ( @list, @{$lst} );
}
return @list;
}
+sub device_by_hwname($$) {
+ my $pack = shift || die;
+ my $name = shift || die;
+ my @list = device_list('localcall');
+
+ my @good = grep { $_->hardware_name eq $name } @list;
+ return undef unless @good;
+ @good > 1 && die "$pack: Multiple matches for '$name': @good";
+ return $good[0];
+}
=head1 drivers()
@@ -139,7 +154,7 @@ loaded.
sub drivers($) {
my $self = shift || die;
- my @devs = $self->device_list;
+ my @devs = device_list('localcall');
my @drvs = map { $_->{DRIVER} } @devs;
# Make unique
my %drivers;
@@ -155,14 +170,52 @@ must be run to initialize the module.
=cut
+my $hardware_scanned;
+
sub scan($) {
my $pack = shift || die;
- my $self = {};
- bless $self, $pack;
- $self->{USB} = [ Zaptel::Hardware::USB->devices ];
- $self->{PCI} = [ Zaptel::Hardware::PCI->scan_devices ];
- return $self;
+ return if $hardware_scanned++;
+ foreach my $type (qw(PCI USB)) {
+ eval "use Zaptel::Hardware::$type";
+ die $@ if $@;
+ $hardware_list{$type} = [ "Zaptel::Hardware::$type"->scan_devices ];
+ }
+}
+
+sub import {
+ Zaptel::Hardware->scan unless grep(/\bnoscan\b/i, @_);
+}
+
+sub showall {
+ my $pack = shift || die;
+ my @devs;
+
+ my $printer = sub {
+ my $title = shift;
+ my @devs = @_;
+
+ return unless @devs;
+ printf "%s:\n", $title;
+ foreach my $dev (@devs) {
+ printf "\t%s\n", $dev->hardware_name;
+ foreach my $k (sort keys %{$dev}) {
+ my $v = $dev->{$k};
+ if($k eq 'MPPINFO') {
+ printf "\t\tMPPINFO:\n";
+ eval "use Zaptel::Xpp::Mpp";
+ die $@ if $@;
+ $v->showinfo("\t\t ");
+ } else {
+ printf "\t\t%-20s %s\n", $k, $v;
+ }
+ }
+ }
+ };
+ foreach my $type (qw(USB PCI)) {
+ my $lst = $hardware_list{$type};
+ &$printer("$type devices", @{$lst});
+ }
}
1;
diff --git a/kernel/xpp/utils/zconf/Zaptel/Hardware/PCI.pm b/kernel/xpp/utils/zconf/Zaptel/Hardware/PCI.pm
index e9166c7..73e3e71 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Hardware/PCI.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Hardware/PCI.pm
@@ -134,12 +134,13 @@ sub pci_sorter {
return $a->priv_device_name() cmp $b->priv_device_name();
}
-sub new($$) {
- my $pack = shift or die "Wasn't called as a class method\n";
- my $self = { @_ };
+sub new($@) {
+ my $pack = shift || die "Wasn't called as a class method\n";
+ my %attr = @_;
+ my $name = sprintf("pci:%s", $attr{PRIV_DEVICE_NAME});
+ my $self = Zaptel::Hardware->new($name, 'PCI');
+ %{$self} = (%{$self}, %attr);
bless $self, $pack;
- Zaptel::Hardware::device_detected($self,
- sprintf("pci:%s", $self->{PRIV_DEVICE_NAME}));
return $self;
}
@@ -197,7 +198,6 @@ sub scan_devices($) {
next unless defined $pci_ids{$key};
my $d = Zaptel::Hardware::PCI->new(
- BUS_TYPE => 'PCI',
PRIV_DEVICE_NAME => $dev->{PRIV_DEVICE_NAME},
VENDOR => $dev->{VENDOR},
PRODUCT => $dev->{PRODUCT},
diff --git a/kernel/xpp/utils/zconf/Zaptel/Hardware/USB.pm b/kernel/xpp/utils/zconf/Zaptel/Hardware/USB.pm
index a2dc08f..4ac0c17 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Hardware/USB.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Hardware/USB.pm
@@ -10,8 +10,7 @@ package Zaptel::Hardware::USB;
use strict;
use Zaptel::Utils;
use Zaptel::Hardware;
-use Zaptel::Xpp;
-use Zaptel::Xpp::Xbus;
+use Zaptel::Xpp::Mpp;
our @ISA = qw(Zaptel::Hardware);
@@ -34,46 +33,83 @@ my %usb_ids = (
'e4e4:1160' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular no-firmware' },
'e4e4:1161' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular USB-firmware' },
'e4e4:1162' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular FPGA-firmware' },
+
+ # Sangoma USB FXO:
+ '10c4:8461' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma WANPIPE USB-FXO Device' },
);
$ENV{PATH} .= ":/usr/sbin:/sbin:/usr/bin:/bin";
-my @xbuses = Zaptel::Xpp::xbuses('SORT_CONNECTOR');
-
sub usb_sorter() {
return $a->hardware_name cmp $b->hardware_name;
}
-sub xbus_of_usb($) {
- my $priv_device_name = shift;
- my $dev = shift;
+sub mpp_addinfo($) {
+ my $self = shift || die;
- my ($wanted) = grep {
- defined($_->usb_devname) &&
- $priv_device_name eq $_->usb_devname
- } @xbuses;
- return $wanted;
+ my $mppinfo = Zaptel::Xpp::Mpp->new($self);
+ $self->{MPPINFO} = $mppinfo if defined $mppinfo;
}
-sub new($$) {
+sub new($@) {
my $pack = shift or die "Wasn't called as a class method\n";
- my $self = { @_ };
+ my %attr = @_;
+ my $name = sprintf("usb:%s", $attr{PRIV_DEVICE_NAME});
+ my $self = Zaptel::Hardware->new($name, 'USB');
+ %{$self} = (%{$self}, %attr);
bless $self, $pack;
- my $xbus = xbus_of_usb($self->priv_device_name);
- if(defined $xbus) {
- $self->{XBUS} = $xbus;
- $self->{LOADED} = 'xpp_usb';
- } else {
- $self->{XBUS} = undef;
- $self->{LOADED} = undef;
- }
- Zaptel::Hardware::device_detected($self,
- sprintf("usb:%s", $self->{PRIV_DEVICE_NAME}));
return $self;
}
-sub devices($) {
+sub readval($) {
+ my $fname = shift || warn;
+ open(F, $fname) || warn "Failed opening '$fname': $!";
+ my $val = <F>;
+ close F;
+ chomp $val;
+ warn "$fname is empty" unless defined $val and $val;
+ return $val;
+}
+
+sub set_transport($$) {
+ my $pack = shift || die;
+ my $xbus = shift || die;
+ my $xbus_dir = shift;
+ my $transportdir = "$xbus_dir/transport";
+ my $hwdev;
+ if(! -e "$transportdir/ep_00") {
+ warn "A trasnport in '$transportdir' is not USB";
+ return undef;
+ }
+ my ($usbdev) = glob("$transportdir/usb_device:*");
+ my $busnum;
+ my $devnum;
+ # Different kernels...
+ if(defined $usbdev) { # It's USB
+ if($usbdev =~ /.*usb_device:usbdev(\d+)\.(\d+)/) {
+ $busnum = $1;
+ $devnum = $2;
+ } else {
+ warn "Bad USB transportdir='$transportdir' usbdev='$usbdev'\n";
+ }
+ } elsif(-d "$transportdir/usb_endpoint") {
+ $busnum = readval("$transportdir/busnum");
+ $devnum = readval("$transportdir/devnum");
+ }
+ my $usbname = sprintf("%03d/%03d", $busnum, $devnum);
+ #printf STDERR "DEBUG: %03d/%03d\n", $busnum, $devnum;
+ $xbus->{USB_DEVNAME} = $usbname;
+ $hwdev = Zaptel::Hardware->device_by_hwname("usb:$usbname");
+ #print "set_transport: ", $hwdev, "\n";
+ $xbus->{TRANSPORT} = $hwdev;
+ $hwdev->{XBUS} = $xbus;
+ $hwdev->{LOADED} = 'xpp_usb';
+ $xbus->{IS_TWINSTAR} = $hwdev->is_twinstar;
+ return $hwdev;
+}
+
+sub scan_devices($) {
my $pack = shift || die;
my $usb_device_list = "/proc/bus/usb/devices";
return unless (-r $usb_device_list);
@@ -99,7 +135,6 @@ sub devices($) {
next unless defined $model;
my $d = Zaptel::Hardware::USB->new(
IS_ASTRIBANK => ($model->{DRIVER} eq 'xpp_usb')?1:0,
- BUS_TYPE => 'USB',
PRIV_DEVICE_NAME => $devname,
VENDOR => $vendor,
PRODUCT => $product,
@@ -111,6 +146,7 @@ sub devices($) {
}
close F;
@devices = sort usb_sorter @devices;
+ return @devices;
}
1;
diff --git a/kernel/xpp/utils/zconf/Zaptel/Span.pm b/kernel/xpp/utils/zconf/Zaptel/Span.pm
index c771a26..23e02b6 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Span.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Span.pm
@@ -95,7 +95,7 @@ Suggested sane framing type (e.g.: "ccs", "esf") for this type of span.
=head2 yellow(), crc4()
Likewise, suggestions ofr the respective fields in the span= line in
-zaptel.conf for this span.
+/etc/zaptel.conf for this span.
=head2 signalling()
@@ -147,6 +147,9 @@ my @pri_strings = (
'Wildcard TE121', # wcte12xp
'Wildcard TE122', # wcte12xp
'T[24]XXP \(PCI\) Card ', # wct4xxp
+ 'R[24]T1 \(PCI\) Card', # rxt1
+ 'Rhino R1T1 (E1)/PRA Card', # r1t1
+ 'Rhino R1T1 (T1)/PRI Card', # r1t1
);
our $ZAPBRI_NET = 'bri_net';
diff --git a/kernel/xpp/utils/zconf/Zaptel/Xpp.pm b/kernel/xpp/utils/zconf/Zaptel/Xpp.pm
index b626bfa..8473b79 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Xpp.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Xpp.pm
@@ -8,6 +8,7 @@ package Zaptel::Xpp;
# $Id$
#
use strict;
+use Zaptel::Hardware;
use Zaptel::Xpp::Xbus;
=head1 NAME
@@ -28,12 +29,29 @@ Zaptel::Xpp - Perl interface to the Xorcom Astribank drivers.
}
=cut
+#
+# A global handle for all xbuses
+#
+my @xbuses;
my $proc_base = "/proc/xpp";
our $sysfs_astribanks = "/sys/bus/astribanks/devices";
our $sysfs_xpds = "/sys/bus/xpds/devices";
our $sysfs_ab_driver = "/sys/bus/astribanks/drivers/xppdrv";
+sub scan($) {
+ my $pack = shift || die;
+
+ opendir(D, $sysfs_astribanks) || return();
+ while(my $entry = readdir D) {
+ next unless $entry =~ /xbus-(\d+)/;
+ my $xbus = Zaptel::Xpp::Xbus->new($1);
+ push(@xbuses, $xbus);
+ }
+ closedir D;
+ return @xbuses;
+}
+
# Nominal sorters for xbuses
sub by_name {
return $a->name cmp $b->name;
@@ -72,6 +90,11 @@ sub by_type {
return $res;
}
+sub by_xpporder {
+ my $cmp = $a->xpporder cmp $b->xpporder;
+ return $cmp if $cmp != 0;
+ return $a->connector cmp $b->connector;
+}
=head1 xbuses([sort_order])
@@ -91,6 +114,19 @@ The built in sorters are:
=over
+=item SORT_XPPORDER
+
+Sort by ordering defined in F</etc/xpp_order> file.
+Astribanks can be listed in this file by their label or by
+their connector string (prefixed with <@>).
+
+Astribanks not listed in the F<xpp_order> file are sorted
+via ordering number 999 -- So they come after the Astribanks
+that are listed.
+
+Astribanks with same ordering number (e.g: 999) are sorted
+by their connector string (to preserve legacy behaviour).
+
=item SORT_CONNECTOR
Sort by the connector string. For USB this defines the "path" to get to
@@ -129,38 +165,73 @@ sub sorters {
SORT_NAME => \&by_name,
SORT_LABEL => \&by_label,
SORT_TYPE => \&by_type,
+ SORT_XPPORDER => \&by_xpporder,
# Aliases
connector => \&by_connector,
name => \&by_name,
label => \&by_label,
type => \&by_type,
+ xpporder => \&by_xpporder,
);
my $which_sorter = shift || return sort keys %sorter_table;
return $which_sorter if ref($which_sorter) eq 'CODE';
return $sorter_table{$which_sorter};
}
+sub add_xpporder(@) {
+ my @xbuses = @_;
+ my $cfg = $ENV{XPPORDER_CONF} || '/etc/xpp_order';
+ my %order;
+
+ # Set defaults
+ foreach my $xbus (@xbuses) {
+ $xbus->{XPPORDER} = 99;
+ }
+ # Read from optional config file
+ if(!open(F, $cfg)) {
+ warn "$0: Failed opening '$cfg': $!"
+ unless $! == 2; # ENOENT
+ return;
+ }
+ my $count = 1;
+ while(<F>) {
+ chomp;
+ s/#.*//;
+ s/^\s*//;
+ s/\s*$//;
+ next unless /\S/;
+ $order{$_} = $count++;
+ }
+ close F;
+ # Overrides from config file
+ foreach my $xbus (@xbuses) {
+ my $label = $xbus->label;
+ my $connector = '@' . $xbus->connector;
+ my $val;
+ $val = $order{$label};
+ $val = $order{$connector} unless defined $val;
+ $xbus->{XPPORDER} = $val if defined $val;
+ }
+}
+
sub xbuses {
- my $optsort = shift || 'SORT_CONNECTOR';
- my @xbuses;
+ my $optsort = shift || 'SORT_XPPORDER';
+ my @sorted_xbuses;
- opendir(D, $sysfs_astribanks) || return();
- while(my $entry = readdir D) {
- next unless $entry =~ /xbus-(\d+)/;
- my $xbus = Zaptel::Xpp::Xbus->new($1);
- push(@xbuses, $xbus);
+ if(! @xbuses) {
+ @xbuses = Zaptel::Xpp->scan();
}
- closedir D;
+ add_xpporder(@xbuses);
my $sorter = sorters($optsort);
die "Unknown optional sorter '$optsort'" unless defined $sorter;
- @xbuses = sort $sorter @xbuses;
- return @xbuses;
+ @sorted_xbuses = sort $sorter @xbuses;
+ return @sorted_xbuses;
}
sub xpd_of_span($) {
my $span = shift or die "Missing span parameter";
return undef unless defined $span;
- foreach my $xbus (Zaptel::Xpp::xbuses('SORT_CONNECTOR')) {
+ foreach my $xbus (Zaptel::Xpp::xbuses) {
foreach my $xpd ($xbus->xpds()) {
return $xpd if $xpd->fqn eq $span->name;
}
diff --git a/kernel/xpp/utils/zconf/Zaptel/Xpp/Mpp.pm b/kernel/xpp/utils/zconf/Zaptel/Xpp/Mpp.pm
new file mode 100644
index 0000000..44807bd
--- /dev/null
+++ b/kernel/xpp/utils/zconf/Zaptel/Xpp/Mpp.pm
@@ -0,0 +1,221 @@
+package Zaptel::Xpp::Mpp;
+#
+# Written by Oron Peled <oron@actcom.co.il>
+# Copyright (C) 2009, Xorcom
+# This program is free software; you can redistribute and/or
+# modify it under the same terms as Perl itself.
+#
+# $Id$
+#
+use strict;
+use File::Basename;
+use Getopt::Std;
+BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); }
+
+use Zaptel::Utils;
+
+=head1 NAME
+
+Zaptel::Xpp::Mpp - Perl interface to C<astribank_tool(8)>
+
+=head1 DESCRIPTION
+
+This package uses C<astribank_tool(8)> to collect information
+about Astribanks via MPP (Management Processor Protocol).
+
+The binary default location is F</usr/sbin/astribank_tool>. It may be
+overridden via module parameter C<astribank_tool=> and the
+C<ASTRIBANK_TOOL> environment variable (higher priority).
+
+It may also be set/unset from code via the set_astribank_tool() method.
+
+=head1 METHODS
+
+=head2 mpp_addinfo()
+
+Called with a list of C<Zaptel::Hardware> objects and augment their
+data with C<Zaptel::Xpp::Mpp> objects.
+
+This method is the normal external interface of this class.
+
+=head2 new()
+
+Constructor. Receive as parameter an instance of C<Zaptel::Hardware> class
+and return a C<Zaptel::Xpp:Mpp> object.
+
+Normally, used indirectly via the mpp_addinfo() method.
+
+=head2 set_astribank_tool()
+
+Override default location of astribank_tool(8). It is legal
+to set it to C<undef>.
+
+=head2 showinfo()
+
+Dump an C<Zaptel::Xpp::Mpp> object for debugging.
+
+=cut
+
+my $astribank_tool = '/usr/sbin/astribank_tool';
+
+sub set_astribank_tool($$) {
+ my $pack = shift || die;
+ $pack eq 'Zaptel::Xpp::Mpp' or die "$0: Called from wrong package? ($pack)";
+ my $arg = shift;
+ $astribank_tool = $arg;
+ #print STDERR "Setting astribank_tool='$astribank_tool'\n";
+}
+
+sub import {
+ my ($param) = grep(/^astribank_tool=/, @_);
+ if(defined $param) {
+ $param =~ s/^astribank_tool=//;
+ $astribank_tool = $param;
+ }
+ if(defined $ENV{ASTRIBANK_TOOL}) {
+ $astribank_tool = $ENV{ASTRIBANK_TOOL};
+ }
+}
+
+sub showinfo($$) {
+ my $self = shift || die;
+ my $prefix = shift || die;
+
+ return unless defined $self;
+ foreach my $k (sort keys %{$self}) {
+ my $v = $self->{$k};
+ if(ref($v) eq 'ARRAY') {
+ my @a = @{$v};
+ my $i;
+ my $ki;
+ for($i = 0; $i < @a; $i++) {
+ $ki = sprintf "%s[%d]", $k, $i;
+ printf "$prefix%-20s %s\n", $ki, $a[$i];
+ }
+ } else {
+ if($k eq 'DEV') {
+ printf "$prefix%-20s -> %s\n", $k, $v->hardware_name;
+ } else {
+ printf "$prefix%-20s %s\n", $k, $v;
+ }
+ }
+ }
+}
+
+sub astribank_tool_cmd($) {
+ my $dev = shift || die;
+ my $usb_top;
+
+ # Find USB bus toplevel
+ $usb_top = '/dev/bus/usb';
+ $usb_top = '/proc/bus/usb' unless -d $usb_top;
+ die "No USB toplevel found\n" unless -d $usb_top;
+ my $name = $dev->priv_device_name();
+ die "$0: Unkown private device name" unless defined $name;
+ my $path = "$usb_top/$name";
+ return ($astribank_tool, '-D', "$path");
+}
+
+sub new($$$) {
+ my $pack = shift || die;
+ my $dev = shift || die;
+ my $product = $dev->product;
+
+ return undef unless $dev->is_astribank;
+ return undef unless $dev->bus_type eq 'USB';
+ return undef unless $product =~ /116./;
+ my $mppinfo = {
+ DEV => $dev,
+ HAS_MPP => 1,
+ };
+ bless $mppinfo, $pack;
+ #print STDERR "$astribank_tool($path) -- '$product'\n";
+ if(! -x $astribank_tool) {
+ warn "Could not run '$astribank_tool'\n";
+ return $mppinfo;
+ }
+ return $mppinfo unless $product =~ /116[12]/;
+ $mppinfo->{'MPP_TALK'} = 1;
+ my @cmd = astribank_tool_cmd($dev);
+ my $name = $dev->priv_device_name();
+ my $dbg_file = "$name";
+ $dbg_file =~ s/\W/_/g;
+ #$dbg_file = "/tmp/twinstar-debug-$dbg_file";
+ $dbg_file = "/dev/null";
+ unless(open(F, "@cmd 2> '$dbg_file' |")) {
+ warn "Failed running '$astribank_tool': $!";
+ return undef;
+ }
+ local $/ = "\n";
+ local $_;
+ while(<F>) {
+ chomp;
+ #printf STDERR "'%s'\n", $_;
+ if(s/^INFO:\s*//) {
+ $mppinfo->{'PROTOCOL'} = $1 if /^protocol\s+version:\s*(\d+)/i;
+ } elsif(s/^EEPROM:\s*//) {
+ $mppinfo->{'EEPROM_RELEASE'} = $1 if /^release\s*:\s*([\d\.]+)/i;
+ $mppinfo->{'EEPROM_LABEL'} = $1 if /^label\s*:\s*([\w._'-]+)/i;
+ } elsif(s/^Extrainfo:\s+:\s*(.+?)$//) {
+ $mppinfo->{'EEPROM_EXTRAINFO'} = $1;
+ } elsif(s/^Capabilities:\s*TwinStar\s*:\s*(.+?)$//) {
+ my $cap = $1;
+ $mppinfo->{'TWINSTAR_CAPABLE'} = ($cap =~ /yes/i) ? 1 : 0;
+ } elsif(s/^TwinStar:\s*//) {
+ $mppinfo->{'TWINSTAR_PORT'} = $1 if /^connected\s+to\s*:\s*usb-(\d+)/i;
+ if(s/^USB-(\d+)\s*POWER\s*:\s*//) {
+ my $v = ($_ eq 'ON') ? 1 : 0;
+ $mppinfo->{'TWINSTAR_POWER'}->[$1] = $v;
+ }
+ if(s/^Watchdog[^:]+:\s*//) {
+ my $v = ($_ eq 'on-guard') ? 1 : 0;
+ $mppinfo->{'TWINSTAR_WATCHDOG'} = $v;
+ }
+ #printf STDERR "\t%s\n", $_;
+ } else {
+ #printf STDERR "\t%s\n", $_;
+ }
+ }
+ unless(close F) {
+ warn "Failed running '$astribank_tool': $!";
+ return undef;
+ }
+ #$mppinfo->showinfo;
+ return $mppinfo;
+}
+
+sub mpp_setwatchdog($$) {
+ my $mppinfo = shift || die;
+ my $on = shift;
+ die "$0: Bad value '$on'" unless defined($on) && $on =~ /^[0-1]$/;
+ my $dev = $mppinfo->dev || die;
+ return undef unless defined $mppinfo->mpp_talk;
+ my $old = $mppinfo->tws_watchdog;
+ my @cmd = astribank_tool_cmd($dev);
+ print STDERR "DEBUG($on): '@cmd'\n";
+ system(@cmd, '-w', $on);
+ die "Running $astribank_tool failed: $?" if $?;
+}
+
+sub mpp_jump($) {
+ my $mppinfo = shift || die;
+ my $dev = $mppinfo->dev || die;
+ return undef unless defined $mppinfo->mpp_talk;
+ my $port = $mppinfo->twinstar_port;
+ $port = ($port == 1) ? 0 : 1;
+ die "Unknown TwinStar port" unless defined $port;
+ my @cmd = astribank_tool_cmd($dev);
+ system(@cmd, '-p', $port);
+ die "Running $astribank_tool failed: $?" if $?;
+}
+
+sub mpp_addinfo($@) {
+ my $pack = shift || die;
+ my @devlist = @_;
+
+ foreach my $dev (@devlist) {
+ $dev->{MPPINFO} = $pack->new($dev);
+ }
+}
+
+1;
diff --git a/kernel/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm b/kernel/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm
index f87e2aa..9c73404 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm
@@ -9,6 +9,7 @@ package Zaptel::Xpp::Xbus;
#
use strict;
use Zaptel::Utils;
+use Zaptel::Hardware;
use Zaptel::Xpp::Xpd;
my $proc_base = "/proc/xpp";
@@ -87,6 +88,8 @@ sub read_attrs() {
if($attr eq 'STATUS') {
# Some values are in all caps as well
$val = uc($val);
+ } elsif($attr eq 'CONNECTOR') {
+ $val =~ s/^/@/; # Add prefix
} elsif($attr eq 'LABEL') {
# Fix badly burned labels.
$val =~ s/[[:^print:]]/_/g;
@@ -95,6 +98,19 @@ sub read_attrs() {
}
}
+sub transport_type($$) {
+ my $xbus = shift || die;
+ my $xbus_dir = shift;
+ my $transport = "$xbus_dir/transport";
+ if(-e "$transport/ep_00") { # It's USB
+ $xbus->{TRANSPORT_TYPE} = 'USB';
+ } else {
+ warn "Unkown transport in $xbus_dir\n";
+ undef $xbus->{TRANSPORT_TYPE};
+ }
+ return $xbus->{TRANSPORT_TYPE};
+}
+
sub read_xpdnames_old($) {
my $xbus_num = shift || die;
my $pat = sprintf "/proc/xpp/XBUS-%02d/XPD-[0-9][0-9]", $xbus_num;
@@ -142,16 +158,11 @@ sub new($$) {
$self->read_attrs;
# Get transport related info
my $transport = "$xbus_dir/transport";
- my ($usbdev) = glob("$transport/usb_device:*");
- if(defined $usbdev) { # It's USB
- if($usbdev =~ /.*usb_device:usbdev(\d+)\.(\d+)/) {
- my $busnum = $1;
- my $devnum = $2;
- #printf STDERR "DEBUG: %03d/%03d\n", $busnum, $devnum;
- $self->{USB_DEVNAME} = sprintf("%03d/%03d", $busnum, $devnum);
- } else {
- warn "Bad USB transport='$transport' usbdev='$usbdev'\n";
- }
+ my $transport_type = $self->transport_type($xbus_dir);
+ if(defined $transport_type) {
+ my $tt = "Zaptel::Hardware::$transport_type";
+ my $hw = $tt->set_transport($self, $xbus_dir);
+ #printf STDERR "Xbus::new transport($transport_type): %s\n", $hw->{HARDWARE_NAME};
}
my @xpdnames;
my @xpds;
diff --git a/kernel/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm b/kernel/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm
index 30a0bad..80478af 100644
--- a/kernel/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm
+++ b/kernel/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm
@@ -85,6 +85,25 @@ sub xpd_old_getoffhook($) {
my %attr_missing_warned; # Prevent duplicate warnings
+sub xpd_driver_getattr($$) {
+ my $xpd = shift || die;
+ my $attr = shift || die;
+ $attr = lc($attr);
+ my ($busnum, $unitnum, $subunitnum) = ($xpd->xbus->num, $xpd->unit, $xpd->subunit);
+ my $file = sprintf "$Zaptel::Xpp::sysfs_xpds/%02d:%1d:%1d/driver/$attr",
+ $busnum, $unitnum, $subunitnum;
+ if(!defined($file)) {
+ warn "$0: xpd_driver_getattr($attr) -- Missing attribute.\n" if
+ $attr_missing_warned{$attr};
+ return undef;
+ }
+ open(F, $file) || return undef;
+ my $val = <F>;
+ close F;
+ chomp $val;
+ return $val;
+}
+
sub xpd_getattr($$) {
my $xpd = shift || die;
my $attr = shift || die;
@@ -162,7 +181,7 @@ sub zt_registration($$) {
}
sub xpds_by_spanno() {
- my @xbuses = Zaptel::Xpp::xbuses("SORT_CONNECTOR");
+ my @xbuses = Zaptel::Xpp::xbuses();
my @xpds = map { $_->xpds } @xbuses;
@xpds = grep { $_->spanno } @xpds;
@xpds = sort { $a->spanno <=> $b->spanno } @xpds;
@@ -181,7 +200,7 @@ sub new($$$$$) {
my $sysfsdir = shift || die;
my $self = {
XBUS => $xbus,
- ID => "$unit$subunit",
+ ID => sprintf("%1d%1d", $unit, $subunit),
FQN => $xbus->name . "/" . "XPD-$unit$subunit",
UNIT => $unit,
SUBUNIT => $subunit,
@@ -198,6 +217,7 @@ sub new($$$$$) {
if($type =~ /BRI_(NT|TE)/) {
$self->{IS_BRI} = 1;
$self->{TERMTYPE} = $1;
+ $self->{DCHAN_HARDHDLC} = $self->xpd_driver_getattr('dchan_hardhdlc');
}
$self->{IS_PRI} = ($type =~ /[ETJ]1/);
$self->{IS_DIGITAL} = ( $self->{IS_BRI} || $self->{IS_PRI} );
diff --git a/kernel/xpp/utils/zt_registration b/kernel/xpp/utils/zt_registration
index 4ae5a66..90596b9 100755
--- a/kernel/xpp/utils/zt_registration
+++ b/kernel/xpp/utils/zt_registration
@@ -18,21 +18,24 @@ use Zaptel::Xpp::Xbus;
use Getopt::Std;
sub usage {
- die "Usage: $0 [on|off|1|0]\n";
+ die "Usage: $0 [-s sort_order] [on|off|1|0]\n";
}
my %opts;
-getopts('s:', \%opts);
-
-my $sort_order = $opts{s} || $ENV{XBUS_SORT} || 'SORT_CONNECTOR';
-my $sorter = Zaptel::Xpp::sorters($sort_order);
-
-if(!defined $sorter) {
- my @sorter_names = Zaptel::Xpp::sorters;
- print STDERR "Unknown sort order $sort_order. Select from:\n\t";
- print STDERR join("\n\t", @sorter_names);
- print STDERR "\n";
- exit 1;
+getopts('s:', \%opts) || usage;
+
+my $sorter;
+my $sort_order = $opts{'s'};
+if(defined $sort_order) {
+ my $sorter = Zaptel::Xpp::sorters($sort_order);
+
+ if(!defined $sorter) {
+ my @sorter_names = Zaptel::Xpp::sorters;
+ print STDERR "Unknown sort order $sort_order. Select from:\n\t";
+ print STDERR join("\n\t", @sorter_names);
+ print STDERR "\n";
+ exit 1;
+ }
}
@ARGV == 0 or @ARGV == 1 or usage;
@@ -58,7 +61,8 @@ sub myprintf {
my @spans = Zaptel::spans;
foreach my $xbus (Zaptel::Xpp::xbuses($sorter)) {
- myprintf "%-10s\t%s\t%s\n", $xbus->name, $xbus->label, $xbus->connector;
+ myprintf "%-10s\t%3s-%s\t%s\n",
+ $xbus->name, $xbus->xpporder, $xbus->label, $xbus->connector;
next unless $xbus->status eq 'CONNECTED';
foreach my $xpd ($xbus->xpds()) {
my $prev = $xpd->zt_registration($on);
@@ -76,7 +80,7 @@ foreach my $xbus (Zaptel::Xpp::xbuses($sorter)) {
myprintf "%3s ==> %3s\n", state2str($prev), state2str($on);
}
}
-myprintf "# Sorted: $sort_order\n";
+myprintf "# Sorted: $sort_order\n" if defined $sort_order;
__END__
@@ -118,7 +122,7 @@ The sort order to use.
If the option is not used, the sort order is taken from the environment
variable XBUS_SORT and failing that: the hard-coded default of
-SORT_CONNECTOR.
+SORT_XPPORDER.
The available sorting orders are documented in Zaptel::Xpp manual.
diff --git a/kernel/xpp/xbus-core.c b/kernel/xpp/xbus-core.c
index 9a62f94..68fc617 100644
--- a/kernel/xpp/xbus-core.c
+++ b/kernel/xpp/xbus-core.c
@@ -90,7 +90,6 @@ const char *xbus_statename(enum xbus_state st)
case XBUS_STATE_READY: return "READY";
case XBUS_STATE_DEACTIVATING: return "DEACTIVATING";
case XBUS_STATE_DEACTIVATED: return "DEACTIVATED";
- case XBUS_STATE_DISCONNECTED: return "DISCONNECTED";
case XBUS_STATE_FAIL: return "FAIL";
}
return NULL;
@@ -481,7 +480,7 @@ static int really_send_cmd_frame(xbus_t *xbus, xframe_t *xframe)
BUG_ON(!xbus);
BUG_ON(!xframe);
BUG_ON(xframe->xframe_magic != XFRAME_MAGIC);
- if(XBUS_IS(xbus, DISCONNECTED)) {
+ if(!XBUS_FLAGS(xbus, CONNECTED)) {
XBUS_ERR(xbus, "Dropped command before sending -- hardware deactivated.\n");
dump_xframe("Dropped", xbus, xframe, DBG_ANY);
FREE_SEND_XFRAME(xbus, xframe);
@@ -521,8 +520,8 @@ int xbus_command_queue_tick(xbus_t *xbus)
ret = really_send_cmd_frame(xbus, frm);
if(ret < 0) {
XBUS_ERR(xbus,
- "Failed to send from command_queue (ret=%d)\n",
- ret);
+ "Failed to send from command_queue (ret=%d)\n",
+ ret);
xbus_setstate(xbus, XBUS_STATE_FAIL);
}
}
@@ -562,7 +561,7 @@ int send_cmd_frame(xbus_t *xbus, xframe_t *xframe)
BUG_ON(xframe->xframe_magic != XFRAME_MAGIC);
- if(XBUS_IS(xbus, DISCONNECTED)) {
+ if(!XBUS_FLAGS(xbus, CONNECTED)) {
XBUS_ERR(xbus, "Dropped command before queueing -- hardware deactivated.\n");
ret = -ENODEV;
goto err;
@@ -627,7 +626,7 @@ void xbus_receive_xframe(xbus_t *xbus, xframe_t *xframe)
if(rx_tasklet) {
xframe_enqueue_recv(xbus, xframe);
} else {
- if(likely(!XBUS_IS(xbus, DISCONNECTED)))
+ if(likely(XBUS_FLAGS(xbus, CONNECTED)))
xframe_receive(xbus, xframe);
else
FREE_RECV_XFRAME(xbus, xframe); /* return to receive_pool */
@@ -728,6 +727,7 @@ static int new_card(xbus_t *xbus,
int i;
int subunits;
int ret = 0;
+ int remaining_ports;
proto_table = xproto_get(type);
if(!proto_table) {
@@ -736,6 +736,7 @@ static int new_card(xbus_t *xbus,
unit, type);
return -EINVAL;
}
+ remaining_ports = ports;
subunits = (ports + proto_table->ports_per_subunit - 1) /
proto_table->ports_per_subunit;
XBUS_DBG(DEVICES, xbus, "CARD %d type=%d.%d ports=%d (%dx%d), %d subunits, port-dir=0x%02X\n",
@@ -752,6 +753,21 @@ static int new_card(xbus_t *xbus,
BUG_ON(!xops);
xbus->worker->num_units += subunits - 1;
for(i = 0; i < subunits; i++) {
+ int subunit_ports = proto_table->ports_per_subunit;
+
+ if(subunit_ports > remaining_ports)
+ subunit_ports = remaining_ports;
+ remaining_ports -= proto_table->ports_per_subunit;
+ if(subunit_ports <= 0) {
+ XBUS_NOTICE(xbus,
+ "Subunit XPD=%d%d without ports (%d of %d)\n",
+ unit,
+ i,
+ subunit_ports,
+ ports);
+ ret = -ENODEV;
+ goto out;
+ }
if(!XBUS_IS(xbus, RECVD_DESC)) {
XBUS_NOTICE(xbus,
"Cannot create XPD=%d%d in state %s\n",
@@ -761,18 +777,18 @@ static int new_card(xbus_t *xbus,
ret = -ENODEV;
goto out;
}
- XBUS_DBG(DEVICES, xbus, "Creating XPD=%d%d type=%d.%d\n",
+ XBUS_DBG(DEVICES, xbus, "Creating XPD=%d%d type=%d.%d (%d ports)\n",
unit,
i,
type,
- subtype);
+ subtype, subunit_ports);
if(!XBUS_IS(xbus, RECVD_DESC)) {
XBUS_ERR(xbus, "Aborting creation -- In bad state %s\n",
xbus_statename(XBUS_STATE(xbus)));
ret = -ENODEV;
goto out;
}
- ret = create_xpd(xbus, proto_table, unit, i, type, subtype, subunits, port_dir);
+ ret = create_xpd(xbus, proto_table, unit, i, type, subtype, subunits, subunit_ports, port_dir);
if(ret < 0) {
XBUS_ERR(xbus, "Creation of XPD=%d%d failed %d\n",
unit, i, ret);
@@ -1086,6 +1102,22 @@ err:
return NULL;
}
+bool xbus_setflags(xbus_t *xbus, int flagbit, bool on)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&xbus->transport.state_lock, flags);
+ XBUS_DBG(DEVICES, xbus, "%s flag %d\n",
+ (on) ? "Set" : "Clear",
+ flagbit);
+ if(on)
+ set_bit(flagbit, &(xbus->transport.transport_flags));
+ else
+ clear_bit(flagbit, &(xbus->transport.transport_flags));
+ spin_unlock_irqrestore(&xbus->transport.state_lock, flags);
+ return 1;
+}
+
bool xbus_setstate(xbus_t *xbus, enum xbus_state newstate)
{
unsigned long flags;
@@ -1122,19 +1154,19 @@ bool xbus_setstate(xbus_t *xbus, enum xbus_state newstate)
state_flip = 1; /* We are good */
break;
case XBUS_STATE_DEACTIVATING:
-#if 0
- if(XBUS_IS(xbus, DEACTIVATED) || XBUS_IS(xbus, DISCONNECTED))
+ if(XBUS_IS(xbus, DEACTIVATING))
+ goto bad_state;
+ if(XBUS_IS(xbus, DEACTIVATED))
goto bad_state;
-#endif
break;
case XBUS_STATE_DEACTIVATED:
if(!XBUS_IS(xbus, DEACTIVATING))
goto bad_state;
break;
- case XBUS_STATE_DISCONNECTED:
- break;
case XBUS_STATE_FAIL:
- if(XBUS_IS(xbus, DEACTIVATING) || XBUS_IS(xbus, DEACTIVATED) || XBUS_IS(xbus, DISCONNECTED))
+ if(XBUS_IS(xbus, DEACTIVATING))
+ goto bad_state;
+ if(XBUS_IS(xbus, DEACTIVATED))
goto bad_state;
break;
default:
@@ -1195,11 +1227,12 @@ int xbus_connect(xbus_t *xbus)
BUG_ON(!ops->xframe_send_cmd);
BUG_ON(!ops->alloc_xframe);
BUG_ON(!ops->free_xframe);
+ xbus_setflags(xbus, XBUS_FLAG_CONNECTED, 1);
xbus_activate(xbus);
return 0;
}
-void xbus_deactivate(xbus_t *xbus, bool is_disconnected)
+void xbus_deactivate(xbus_t *xbus)
{
BUG_ON(!xbus);
XBUS_INFO(xbus, "[%s] Deactivating\n", xbus->label);
@@ -1213,16 +1246,15 @@ void xbus_deactivate(xbus_t *xbus, bool is_disconnected)
xbus_setstate(xbus, XBUS_STATE_DEACTIVATED);
worker_reset(xbus->worker);
xbus_release_xpds(xbus);
- if(!is_disconnected)
- xbus_setstate(xbus, XBUS_STATE_IDLE);
elect_syncer("deactivate");
}
void xbus_disconnect(xbus_t *xbus)
{
- XBUS_INFO(xbus, "[%s] Disconnecting\n", xbus->label);
BUG_ON(!xbus);
- xbus_deactivate(xbus, 1);
+ XBUS_INFO(xbus, "[%s] Disconnecting\n", xbus->label);
+ xbus_setflags(xbus, XBUS_FLAG_CONNECTED, 0);
+ xbus_deactivate(xbus);
xbus_command_queue_clean(xbus);
xbus_command_queue_waitempty(xbus);
tasklet_kill(&xbus->receive_tasklet);
@@ -1230,7 +1262,6 @@ void xbus_disconnect(xbus_t *xbus)
xframe_queue_clear(&xbus->send_pool);
xframe_queue_clear(&xbus->receive_pool);
xframe_queue_clear(&xbus->pcm_tospan);
- xbus_setstate(xbus, XBUS_STATE_DISCONNECTED);
del_timer_sync(&xbus->command_timer);
transportops_put(xbus);
transport_destroy(xbus);
@@ -1464,7 +1495,7 @@ static int xbus_read_proc(char *page, char **start, off_t off, int count, int *e
xbus->busname,
xbus->connector,
xbus->label,
- (!XBUS_IS(xbus, DISCONNECTED)) ? "connected" : "missing"
+ (XBUS_FLAGS(xbus, CONNECTED)) ? "connected" : "missing"
);
len += xbus_fill_proc_queue(page + len, &xbus->send_pool);
len += xbus_fill_proc_queue(page + len, &xbus->receive_pool);
@@ -1709,7 +1740,7 @@ static int read_proc_xbuses(char *page, char **start, off_t off, int count, int
xbus->busname,
xbus->connector,
xbus->label,
- (!XBUS_IS(xbus, DISCONNECTED)) ? "connected" : "missing"
+ (XBUS_FLAGS(xbus, CONNECTED)) ? "connected" : "missing"
);
}
}
@@ -1746,6 +1777,7 @@ static void transport_init(xbus_t *xbus, struct xbus_ops *ops, ushort max_send_s
spin_lock_init(&xbus->transport.state_lock);
spin_lock_init(&xbus->transport.lock);
atomic_set(&xbus->transport.transport_refcount, 0);
+ xbus_setflags(xbus, XBUS_FLAG_CONNECTED, 0);
init_waitqueue_head(&xbus->transport.transport_unused);
}
diff --git a/kernel/xpp/xbus-core.h b/kernel/xpp/xbus-core.h
index a24d76b..773d703 100644
--- a/kernel/xpp/xbus-core.h
+++ b/kernel/xpp/xbus-core.h
@@ -94,7 +94,6 @@ enum xbus_state {
XBUS_STATE_READY,
XBUS_STATE_DEACTIVATING,
XBUS_STATE_DEACTIVATED,
- XBUS_STATE_DISCONNECTED,
XBUS_STATE_FAIL,
};
@@ -106,6 +105,7 @@ struct xbus_transport {
struct device *transport_device;
ushort max_send_size;
enum xbus_state xbus_state;
+ unsigned long transport_flags;
spinlock_t state_lock;
atomic_t transport_refcount;
wait_queue_head_t transport_unused;
@@ -117,6 +117,9 @@ struct xbus_transport {
#define XBUS_IS(xbus, st) (XBUS_STATE(xbus) == XBUS_STATE_ ## st)
#define TRANSPORT_EXIST(xbus) ((xbus)->transport.ops != NULL)
+#define XBUS_FLAG_CONNECTED 0
+#define XBUS_FLAGS(xbus, flg) test_bit(XBUS_FLAG_ ## flg, &((xbus)->transport.transport_flags))
+
struct xbus_ops *transportops_get(xbus_t *xbus);
void transportops_put(xbus_t *xbus);
@@ -300,11 +303,12 @@ xpacket_t *xframe_next_packet(xframe_t *xframe, int len);
xpd_t *xpd_of(const xbus_t *xbus, int xpd_num);
xpd_t *xpd_byaddr(const xbus_t *xbus, uint unit, uint subunit);
bool xbus_setstate(xbus_t *xbus, enum xbus_state newstate);
+bool xbus_setflags(xbus_t *xbus, int flagbit, bool on);
xbus_t *xbus_new(struct xbus_ops *ops, ushort max_send_size, struct device *transport_device, void *priv);
void xbus_free(xbus_t *xbus);
int xbus_connect(xbus_t *xbus);
int xbus_activate(xbus_t *xbus);
-void xbus_deactivate(xbus_t *xbus, bool is_disconnected);
+void xbus_deactivate(xbus_t *xbus);
void xbus_disconnect(xbus_t *xbus);
void xbus_receive_xframe(xbus_t *xbus, xframe_t *xframe);
int xbus_process_worker(xbus_t *xbus);
diff --git a/kernel/xpp/xbus-pcm.c b/kernel/xpp/xbus-pcm.c
index 4d75a43..bcb380d 100644
--- a/kernel/xpp/xbus-pcm.c
+++ b/kernel/xpp/xbus-pcm.c
@@ -414,7 +414,7 @@ static void reset_sync_counters(void)
(e.g: wrong firmware version, etc).
*/
if(xbus->self_ticking) {
- if(XBUS_IS(xbus, DISCONNECTED)) {
+ if(!XBUS_FLAGS(xbus, CONNECTED)) {
XBUS_DBG(GENERAL, xbus,
"Dropped packet. Is shutting down.\n");
} else {
@@ -472,7 +472,7 @@ int zaptel_sync_tick(struct zt_span *span, int is_master)
if(is_master) {
static int rate_limit;
- if((rate_limit++ % 1003) == 0)
+ if((rate_limit++ % 10003) == 0)
XPD_NOTICE(xpd, "Is a ZAPTEL sync master: ignore sync from ZAPTEL\n");
goto noop;
}
@@ -554,7 +554,7 @@ static void update_sync_master(xbus_t *new_syncer, bool force_zaptel)
xbus_t *xbus = xbus_num(i);
if(!xbus)
continue;
- if(!XBUS_IS(xbus, DISCONNECTED) && xbus != new_syncer) {
+ if(XBUS_FLAGS(xbus, CONNECTED) && xbus != new_syncer) {
if(xbus->self_ticking)
xbus_request_sync(xbus, SYNC_MODE_PLL);
else
diff --git a/kernel/xpp/xbus-sysfs.c b/kernel/xpp/xbus-sysfs.c
index ca24648..2c8c6f1 100644
--- a/kernel/xpp/xbus-sysfs.c
+++ b/kernel/xpp/xbus-sysfs.c
@@ -86,7 +86,7 @@ static DEVICE_ATTR_WRITER(xbus_state_store, dev, buf, count)
xbus = dev_to_xbus(dev);
XBUS_DBG(GENERAL, xbus, "%s\n", buf);
if(strncmp(buf, "stop", 4) == 0)
- xbus_deactivate(xbus, 0);
+ xbus_deactivate(xbus);
else if(XBUS_IS(xbus, IDLE) && strncmp(buf, "start", 5) == 0)
xbus_activate(xbus);
else {
@@ -104,7 +104,7 @@ static DEVICE_ATTR_READER(status_show, dev, buf)
int ret;
xbus = dev_to_xbus(dev);
- ret = snprintf(buf, PAGE_SIZE, "%s\n", (!XBUS_IS(xbus, DISCONNECTED))?"connected":"missing");
+ ret = snprintf(buf, PAGE_SIZE, "%s\n", (XBUS_FLAGS(xbus, CONNECTED))?"connected":"missing");
return ret;
}
@@ -392,7 +392,11 @@ static void astribank_release(struct device *dev)
BUG_ON(!dev);
xbus = dev_to_xbus(dev);
- if(!XBUS_IS(xbus, DISCONNECTED)) {
+ if(XBUS_FLAGS(xbus, CONNECTED)) {
+ XBUS_ERR(xbus, "Try to release CONNECTED device.\n");
+ BUG();
+ }
+ if(!XBUS_IS(xbus, IDLE) && !XBUS_IS(xbus, FAIL) && !XBUS_IS(xbus, DEACTIVATED)) {
XBUS_ERR(xbus, "Try to release in state %s\n",
xbus_statename(XBUS_STATE(xbus)));
BUG();
diff --git a/kernel/xpp/xdefs.h b/kernel/xpp/xdefs.h
index ca6e964..9fe821d 100644
--- a/kernel/xpp/xdefs.h
+++ b/kernel/xpp/xdefs.h
@@ -135,6 +135,8 @@ typedef unsigned char byte;
#define DEVICE_ATTR_WRITER(name,dev,buf, count) \
ssize_t name(struct device *dev, const char *buf, size_t count)
#endif
+#define DRIVER_ATTR_READER(name,drv,buf) \
+ ssize_t name(struct device_driver *drv, char * buf)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
/* Also don't define this for later RHEL >= 5.2 . hex_asc is from the
diff --git a/kernel/xpp/xpd.h b/kernel/xpp/xpd.h
index 717e68d..743ff1e 100644
--- a/kernel/xpp/xpd.h
+++ b/kernel/xpp/xpd.h
@@ -31,7 +31,7 @@
#include <linux/device.h>
#include <linux/version.h>
#include <asm/atomic.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#include <linux/semaphore.h>
#else
#include <asm/semaphore.h>
diff --git a/kernel/xpp/xpp.conf b/kernel/xpp/xpp.conf
index e5aeb7c..d039468 100644
--- a/kernel/xpp/xpp.conf
+++ b/kernel/xpp/xpp.conf
@@ -1,14 +1,13 @@
-# /etc/dahdi/xpp.conf
+# /etc/xpp.conf
#
# This file is used to configure the operation
# of init_card_* initialization scripts.
#
# pri_protocol: is an XPP PRI device E1 (default) or T1?
-# This parameter is REQUIRED for the PRI module
-pri_protocol E1
+#pri_protocol E1
#
-# Alternatively you can set this on a port basis is you have a strange
+# Alternatively you can set this on a port by port basis if you have a strange
# setup where some of the ports are E1 and some are T1. These specific
# settings will override the default set above.
#pri_protocol/xbus-00/xpd-02 T1
diff --git a/kernel/xpp/xpp_usb.c b/kernel/xpp/xpp_usb.c
index 0340768..0d6d16a 100644
--- a/kernel/xpp/xpp_usb.c
+++ b/kernel/xpp/xpp_usb.c
@@ -975,7 +975,11 @@ static int __init xpp_usb_init(void)
INFO("revision %s\n", XPP_VERSION);
xusb_cache = kmem_cache_create("xusb_cache",
sizeof(xframe_t) + XFRAME_DATASIZE,
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,22)
+ 0, SLAB_STORE_USER,
+#else
0, 0,
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
NULL,
#endif
diff --git a/kernel/xpp/xpp_zap.c b/kernel/xpp/xpp_zap.c
index 9e39b01..b324cfa 100644
--- a/kernel/xpp/xpp_zap.c
+++ b/kernel/xpp/xpp_zap.c
@@ -252,6 +252,7 @@ int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table,
byte type,
byte subtype,
int subunits,
+ int subunit_ports,
byte port_dir)
{
xpd_t *xpd = NULL;
@@ -266,7 +267,12 @@ int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table,
unit, subunit);
return 0;
}
- xpd = proto_table->xops.card_new(xbus, unit, subunit, proto_table, subtype, subunits, to_phone);
+ if(subunit_ports <= 0 || subunit_ports > CHANNELS_PERXPD) {
+ XBUS_NOTICE(xbus, "Illegal number of ports %d for XPD %d%d\n",
+ subunit_ports, unit, subunit);
+ return 0;
+ }
+ xpd = proto_table->xops.card_new(xbus, unit, subunit, proto_table, subtype, subunits, subunit_ports, to_phone);
if(!xpd) {
XBUS_NOTICE(xbus, "card_new(%d,%d,%d,%d,%d) failed. Ignored.\n",
unit, subunit, proto_table->type, subtype, to_phone);
diff --git a/kernel/xpp/xpp_zap.h b/kernel/xpp/xpp_zap.h
index 6eece7b..101d7d6 100644
--- a/kernel/xpp/xpp_zap.h
+++ b/kernel/xpp/xpp_zap.h
@@ -29,7 +29,7 @@ int zaptel_register_xpd(xpd_t *xpd);
int zaptel_unregister_xpd(xpd_t *xpd);
void xbus_request_removal(xbus_t *xbus);
int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table,
- int unit, int subunit, byte type, byte subtype, int subunits, byte port_dir);
+ int unit, int subunit, byte type, byte subtype, int subunits, int subunit_ports, byte port_dir);
void xpd_post_init(xpd_t *xpd);
xpd_t *xpd_alloc(xbus_t *xbus, int unit, int subunit, int subtype, int subunits, size_t privsize, const xproto_table_t *proto_table, int channels);
void xpd_free(xpd_t *xpd);
diff --git a/kernel/xpp/xproto.c b/kernel/xpp/xproto.c
index 348b4b6..77465c9 100644
--- a/kernel/xpp/xproto.c
+++ b/kernel/xpp/xproto.c
@@ -93,7 +93,9 @@ const xproto_table_t *xproto_get(xpd_type_t cardtype)
}
if(xtable) {
BUG_ON(!xtable->owner);
+#ifdef CONFIG_MODULE_UNLOAD
DBG(GENERAL, "%s refcount was %d\n", xtable->name, module_refcount(xtable->owner));
+#endif
if(!try_module_get(xtable->owner)) {
ERR("%s: try_module_get for %s failed.\n", __FUNCTION__, xtable->name);
return NULL;
@@ -105,8 +107,10 @@ const xproto_table_t *xproto_get(xpd_type_t cardtype)
void xproto_put(const xproto_table_t *xtable)
{
BUG_ON(!xtable);
+#ifdef CONFIG_MODULE_UNLOAD
DBG(GENERAL, "%s refcount was %d\n", xtable->name, module_refcount(xtable->owner));
BUG_ON(module_refcount(xtable->owner) <= 0);
+#endif
module_put(xtable->owner);
}
@@ -262,7 +266,7 @@ int xframe_receive(xbus_t *xbus, xframe_t *xframe)
FREE_RECV_XFRAME(xbus, xframe);
return -EPROTO;
}
- if(XBUS_IS(xbus, DISCONNECTED)) {
+ if(!XBUS_FLAGS(xbus, CONNECTED)) {
XBUS_DBG(GENERAL, xbus, "Dropped xframe. Is shutting down.\n");
return -ENODEV;
}
diff --git a/kernel/xpp/xproto.h b/kernel/xpp/xproto.h
index f889b3a..5b5bf83 100644
--- a/kernel/xpp/xproto.h
+++ b/kernel/xpp/xproto.h
@@ -147,9 +147,9 @@ bool valid_xpd_addr(const struct xpd_addr *addr);
do { \
int pack_len = RPACKET_SIZE(card,op); \
\
- if(XBUS_IS(xbus, DISCONNECTED)) \
+ if(!XBUS_FLAGS(xbus, CONNECTED)) \
return -ENODEV; \
- (frm) = ALLOC_SEND_XFRAME(xbus); \
+ (frm) = ALLOC_SEND_XFRAME(xbus); \
if(!(frm)) \
return -ENOMEM; \
(p) = xframe_next_packet(frm, pack_len); \
@@ -218,7 +218,8 @@ xproto_handler_t xproto_global_handler(byte opcode);
struct xops {
xpd_t *(*card_new)(xbus_t *xbus, int unit, int subunit,
- const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone);
+ const xproto_table_t *proto_table, byte subtype,
+ int subunits, int subunit_ports, bool to_phone);
int (*card_init)(xbus_t *xbus, xpd_t *xpd);
int (*card_remove)(xbus_t *xbus, xpd_t *xpd);
int (*card_tick)(xbus_t *xbus, xpd_t *xpd);
diff --git a/zaptel.init b/zaptel.init
index aee83f7..2014a31 100644
--- a/zaptel.init
+++ b/zaptel.init
@@ -23,6 +23,9 @@ FXOTUNE=/sbin/fxotune
# explicit Astribank (e.g: 01).
XPP_SYNC=auto
+# A command to wait until Astribanks settle down.
+WAITFOR_XPDS=/usr/share/zaptel/waitfor_xpds
+
# The maximal timeout (seconds) to wait for udevd to finish generating
# device nodes after the modules have loaded and before running ztcfg.
ZAP_DEV_TIMEOUT=20
@@ -81,7 +84,7 @@ xpp_startup() {
if ! grep -q connected /proc/xpp/xbuses 2>/dev/null; then return 0; fi
echo "Waiting for Astribank devices to initialize:"
- cat /proc/xpp/XBUS-[0-9]*/waitfor_xpds 2>/dev/null || true
+ $WAITFOR_XPDS || true
# overriding locales for the above two, as perl can be noisy
# when locales are missing.