Automated formatting with YAPF.

PEP8 settings are used except the low 80 column limit has be increased
to a more reasonable 100 columns.
This commit is contained in:
Arvid Norlander 2020-08-05 18:17:31 +02:00
parent e003dbeb1a
commit 9dc0c14aed
No known key found for this signature in database
GPG key ID: E824A8E5D8D29AA0
27 changed files with 1890 additions and 697 deletions

394
.style.yapf Normal file
View file

@ -0,0 +1,394 @@
[style]
# Align closing bracket with visual indentation.
align_closing_bracket_with_visual_indent=True
# Allow dictionary keys to exist on multiple lines. For example:
#
# x = {
# ('this is the first element of a tuple',
# 'this is the second element of a tuple'):
# value,
# }
allow_multiline_dictionary_keys=False
# Allow lambdas to be formatted on more than one line.
allow_multiline_lambdas=False
# Allow splitting before a default / named assignment in an argument list.
allow_split_before_default_or_named_assigns=True
# Allow splits before the dictionary value.
allow_split_before_dict_value=True
# Let spacing indicate operator precedence. For example:
#
# a = 1 * 2 + 3 / 4
# b = 1 / 2 - 3 * 4
# c = (1 + 2) * (3 - 4)
# d = (1 - 2) / (3 + 4)
# e = 1 * 2 - 3
# f = 1 + 2 + 3 + 4
#
# will be formatted as follows to indicate precedence:
#
# a = 1*2 + 3/4
# b = 1/2 - 3*4
# c = (1+2) * (3-4)
# d = (1-2) / (3+4)
# e = 1*2 - 3
# f = 1 + 2 + 3 + 4
#
arithmetic_precedence_indication=False
# Number of blank lines surrounding top-level function and class
# definitions.
blank_lines_around_top_level_definition=2
# Insert a blank line before a class-level docstring.
blank_line_before_class_docstring=False
# Insert a blank line before a module docstring.
blank_line_before_module_docstring=False
# Insert a blank line before a 'def' or 'class' immediately nested
# within another 'def' or 'class'. For example:
#
# class Foo:
# # <------ this blank line
# def method():
# ...
blank_line_before_nested_class_or_def=False
# Do not split consecutive brackets. Only relevant when
# dedent_closing_brackets is set. For example:
#
# call_func_that_takes_a_dict(
# {
# 'key1': 'value1',
# 'key2': 'value2',
# }
# )
#
# would reformat to:
#
# call_func_that_takes_a_dict({
# 'key1': 'value1',
# 'key2': 'value2',
# })
coalesce_brackets=False
# The column limit.
column_limit=100
# The style for continuation alignment. Possible values are:
#
# - SPACE: Use spaces for continuation alignment. This is default behavior.
# - FIXED: Use fixed number (CONTINUATION_INDENT_WIDTH) of columns
# (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs or
# CONTINUATION_INDENT_WIDTH spaces) for continuation alignment.
# - VALIGN-RIGHT: Vertically align continuation lines to multiple of
# INDENT_WIDTH columns. Slightly right (one tab or a few spaces) if
# cannot vertically align continuation lines with indent characters.
continuation_align_style=SPACE
# Indent width used for line continuations.
continuation_indent_width=4
# Put closing brackets on a separate line, dedented, if the bracketed
# expression can't fit in a single line. Applies to all kinds of brackets,
# including function definitions and calls. For example:
#
# config = {
# 'key1': 'value1',
# 'key2': 'value2',
# } # <--- this bracket is dedented and on a separate line
#
# time_series = self.remote_client.query_entity_counters(
# entity='dev3246.region1',
# key='dns.query_latency_tcp',
# transform=Transformation.AVERAGE(window=timedelta(seconds=60)),
# start_ts=now()-timedelta(days=3),
# end_ts=now(),
# ) # <--- this bracket is dedented and on a separate line
dedent_closing_brackets=False
# Disable the heuristic which places each list element on a separate line
# if the list is comma-terminated.
disable_ending_comma_heuristic=False
# Place each dictionary entry onto its own line.
each_dict_entry_on_separate_line=True
# Require multiline dictionary even if it would normally fit on one line.
# For example:
#
# config = {
# 'key1': 'value1'
# }
force_multiline_dict=False
# The regex for an i18n comment. The presence of this comment stops
# reformatting of that line, because the comments are required to be
# next to the string they translate.
i18n_comment=
# The i18n function call names. The presence of this function stops
# reformattting on that line, because the string it has cannot be moved
# away from the i18n comment.
i18n_function_call=
# Indent blank lines.
indent_blank_lines=False
# Put closing brackets on a separate line, indented, if the bracketed
# expression can't fit in a single line. Applies to all kinds of brackets,
# including function definitions and calls. For example:
#
# config = {
# 'key1': 'value1',
# 'key2': 'value2',
# } # <--- this bracket is indented and on a separate line
#
# time_series = self.remote_client.query_entity_counters(
# entity='dev3246.region1',
# key='dns.query_latency_tcp',
# transform=Transformation.AVERAGE(window=timedelta(seconds=60)),
# start_ts=now()-timedelta(days=3),
# end_ts=now(),
# ) # <--- this bracket is indented and on a separate line
indent_closing_brackets=False
# Indent the dictionary value if it cannot fit on the same line as the
# dictionary key. For example:
#
# config = {
# 'key1':
# 'value1',
# 'key2': value1 +
# value2,
# }
indent_dictionary_value=False
# The number of columns to use for indentation.
indent_width=4
# Join short lines into one line. E.g., single line 'if' statements.
join_multiple_lines=True
# Do not include spaces around selected binary operators. For example:
#
# 1 + 2 * 3 - 4 / 5
#
# will be formatted as follows when configured with "*,/":
#
# 1 + 2*3 - 4/5
no_spaces_around_selected_binary_operators=
# Use spaces around default or named assigns.
spaces_around_default_or_named_assign=False
# Adds a space after the opening '{' and before the ending '}' dict delimiters.
#
# {1: 2}
#
# will be formatted as:
#
# { 1: 2 }
spaces_around_dict_delimiters=False
# Adds a space after the opening '[' and before the ending ']' list delimiters.
#
# [1, 2]
#
# will be formatted as:
#
# [ 1, 2 ]
spaces_around_list_delimiters=False
# Use spaces around the power operator.
spaces_around_power_operator=False
# Use spaces around the subscript / slice operator. For example:
#
# my_list[1 : 10 : 2]
spaces_around_subscript_colon=False
# Adds a space after the opening '(' and before the ending ')' tuple delimiters.
#
# (1, 2, 3)
#
# will be formatted as:
#
# ( 1, 2, 3 )
spaces_around_tuple_delimiters=False
# The number of spaces required before a trailing comment.
# This can be a single value (representing the number of spaces
# before each trailing comment) or list of values (representing
# alignment column values; trailing comments within a block will
# be aligned to the first column value that is greater than the maximum
# line length within the block). For example:
#
# With spaces_before_comment=5:
#
# 1 + 1 # Adding values
#
# will be formatted as:
#
# 1 + 1 # Adding values <-- 5 spaces between the end of the statement and comment
#
# With spaces_before_comment=15, 20:
#
# 1 + 1 # Adding values
# two + two # More adding
#
# longer_statement # This is a longer statement
# short # This is a shorter statement
#
# a_very_long_statement_that_extends_beyond_the_final_column # Comment
# short # This is a shorter statement
#
# will be formatted as:
#
# 1 + 1 # Adding values <-- end of line comments in block aligned to col 15
# two + two # More adding
#
# longer_statement # This is a longer statement <-- end of line comments in block aligned to col 20
# short # This is a shorter statement
#
# a_very_long_statement_that_extends_beyond_the_final_column # Comment <-- the end of line comments are aligned based on the line length
# short # This is a shorter statement
#
spaces_before_comment=2
# Insert a space between the ending comma and closing bracket of a list,
# etc.
space_between_ending_comma_and_closing_bracket=True
# Use spaces inside brackets, braces, and parentheses. For example:
#
# method_call( 1 )
# my_dict[ 3 ][ 1 ][ get_index( *args, **kwargs ) ]
# my_set = { 1, 2, 3 }
space_inside_brackets=False
# Split before arguments
split_all_comma_separated_values=False
# Split before arguments, but do not split all subexpressions recursively
# (unless needed).
split_all_top_level_comma_separated_values=False
# Split before arguments if the argument list is terminated by a
# comma.
split_arguments_when_comma_terminated=False
# Set to True to prefer splitting before '+', '-', '*', '/', '//', or '@'
# rather than after.
split_before_arithmetic_operator=False
# Set to True to prefer splitting before '&', '|' or '^' rather than
# after.
split_before_bitwise_operator=True
# Split before the closing bracket if a list or dict literal doesn't fit on
# a single line.
split_before_closing_bracket=True
# Split before a dictionary or set generator (comp_for). For example, note
# the split before the 'for':
#
# foo = {
# variable: 'Hello world, have a nice day!'
# for variable in bar if variable != 42
# }
split_before_dict_set_generator=True
# Split before the '.' if we need to split a longer expression:
#
# foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d))
#
# would reformat to something like:
#
# foo = ('This is a really long string: {}, {}, {}, {}'
# .format(a, b, c, d))
split_before_dot=False
# Split after the opening paren which surrounds an expression if it doesn't
# fit on a single line.
split_before_expression_after_opening_paren=False
# If an argument / parameter list is going to be split, then split before
# the first argument.
split_before_first_argument=False
# Set to True to prefer splitting before 'and' or 'or' rather than
# after.
split_before_logical_operator=True
# Split named assignments onto individual lines.
split_before_named_assigns=True
# Set to True to split list comprehensions and generators that have
# non-trivial expressions and multiple clauses before each of these
# clauses. For example:
#
# result = [
# a_long_var + 100 for a_long_var in xrange(1000)
# if a_long_var % 10]
#
# would reformat to something like:
#
# result = [
# a_long_var + 100
# for a_long_var in xrange(1000)
# if a_long_var % 10]
split_complex_comprehension=False
# The penalty for splitting right after the opening bracket.
split_penalty_after_opening_bracket=300
# The penalty for splitting the line after a unary operator.
split_penalty_after_unary_operator=10000
# The penalty of splitting the line around the '+', '-', '*', '/', '//',
# ``%``, and '@' operators.
split_penalty_arithmetic_operator=300
# The penalty for splitting right before an if expression.
split_penalty_before_if_expr=0
# The penalty of splitting the line around the '&', '|', and '^'
# operators.
split_penalty_bitwise_operator=300
# The penalty for splitting a list comprehension or generator
# expression.
split_penalty_comprehension=80
# The penalty for characters over the column limit.
split_penalty_excess_character=7000
# The penalty incurred by adding a line split to the unwrapped line. The
# more line splits added the higher the penalty.
split_penalty_for_added_line_split=30
# The penalty of splitting a list of "import as" names. For example:
#
# from a_very_long_or_indented_module_name_yada_yad import (long_argument_1,
# long_argument_2,
# long_argument_3)
#
# would reformat to something like:
#
# from a_very_long_or_indented_module_name_yada_yad import (
# long_argument_1, long_argument_2, long_argument_3)
split_penalty_import_names=0
# The penalty of splitting the line around the 'and' and 'or'
# operators.
split_penalty_logical_operator=300
# Use the Tab character for indentation.
use_tabs=False

View file

@ -10,7 +10,6 @@ from validitysensor import init
from time import sleep
from usb import core as usb_core
if __name__ == "__main__":
if os.geteuid() != 0:
raise Exception('This script needs to be executed as root')

View file

@ -30,7 +30,8 @@ from enum import Enum, auto
from time import sleep
from usb import core as usb_core
python_validity_data='/usr/share/python-validity/'
python_validity_data = '/usr/share/python-validity/'
# FIXME: supported usb ids are duplicated in usb.py
class VFS(Enum):
@ -38,6 +39,7 @@ class VFS(Enum):
DEV_97 = (0x138a, 0x0097)
DEV_9a = (0x06cb, 0x009a)
DEFAULT_URIS = {
VFS.DEV_90: {
'driver': 'https://download.lenovo.com/pccbbs/mobiles/n1cgn08w.exe',
@ -76,15 +78,12 @@ def download_and_extract_fw(dev_type, fwdir, fwuri=None):
with open(fwarchive, 'wb') as out_file:
out_file.write(response.read())
subprocess.check_call(['innoextract',
'--output-dir', fwdir,
'--include', fwname,
'--collisions', 'overwrite',
subprocess.check_call([
'innoextract', '--output-dir', fwdir, '--include', fwname, '--collisions', 'overwrite',
fwarchive
])
fwpath = subprocess.check_output([
'find', fwdir, '-name', fwname]).decode('utf-8').strip()
fwpath = subprocess.check_output(['find', fwdir, '-name', fwname]).decode('utf-8').strip()
print('Found firmware at {}'.format(fwpath))
if not fwpath:
@ -92,6 +91,7 @@ def download_and_extract_fw(dev_type, fwdir, fwuri=None):
return fwpath
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--driver-uri')
@ -111,8 +111,7 @@ if __name__ == "__main__":
raise Exception('No supported validity device found')
try:
subprocess.check_call(['innoextract', '--version'],
stdout=subprocess.DEVNULL)
subprocess.check_call(['innoextract', '--version'], stdout=subprocess.DEVNULL)
except Exception as e:
print('Impossible to run innoextract: {}'.format(e))
sys.exit(1)

View file

@ -64,9 +64,7 @@ class Device(dbus.service.Object):
"""Resolve user name to database object"""
return db.lookup_user(self.user2identity(user))
@dbus.service.method(dbus_interface=INTERFACE_NAME,
in_signature="s",
out_signature="as")
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature="s", out_signature="as")
def ListEnrolledFingers(self, user):
try:
logging.debug('In ListEnrolledFingers %s' % user)
@ -82,9 +80,7 @@ class Device(dbus.service.Object):
except Exception as e:
raise e
@dbus.service.method(dbus_interface=INTERFACE_NAME,
in_signature='s',
out_signature='')
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature='s', out_signature='')
def DeleteEnrolledFingers(self, user):
logging.debug('In DeleteEnrolledFingers %s' % user)
usr = self.user2record(user)
@ -94,9 +90,7 @@ class Device(dbus.service.Object):
db.del_record(usr.dbid)
@dbus.service.method(dbus_interface=INTERFACE_NAME,
in_signature='ss',
out_signature='')
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature='ss', out_signature='')
def VerifyStart(self, user, finger):
logging.debug('In VerifyStart for %s, %s' % (user, finger))
@ -130,15 +124,11 @@ class Device(dbus.service.Object):
thread.daemon = True
thread.start()
@dbus.service.method(dbus_interface=INTERFACE_NAME,
in_signature='',
out_signature='')
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature='', out_signature='')
def Cancel(self):
sensor.cancel()
@dbus.service.method(dbus_interface=INTERFACE_NAME,
in_signature='ss',
out_signature='')
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature='ss', out_signature='')
def EnrollStart(self, user, finger_name):
logging.debug('In EnrollStart %s for %s' % (finger_name, user))
@ -192,9 +182,7 @@ class Device(dbus.service.Object):
def EnrollStatus(self, result, done):
logging.debug('EnrollStatus')
@dbus.service.method(dbus_interface=INTERFACE_NAME,
in_signature='s',
out_signature='s')
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature='s', out_signature='s')
def RunCmd(self, cmd):
logging.debug('RunCmd')
return hexlify(tls.app(unhexlify(cmd))).decode()
@ -228,7 +216,10 @@ def main():
parser = argparse.ArgumentParser('Open fprintd DBus service')
parser.add_argument('--debug', help='Enable tracing', action='store_true')
parser.add_argument('--devpath', help='USB device path: usb-<busnum>-<address>')
parser.add_argument('--configpath', default='/etc/python-validity', type=Path, help='Path to config files')
parser.add_argument('--configpath',
default='/etc/python-validity',
type=Path,
help='Path to config files')
args = parser.parse_args()
if args.debug:

View file

@ -1,4 +1,3 @@
from validitysensor.usb import usb
from validitysensor.sensor import factory_reset, RebootException

View file

@ -20,6 +20,6 @@ for n in ls:
pid = o.GetConnectionUnixProcessID(n)
with open('/proc/%d/cmdline' % pid) as f:
s=f.read()
s=s.split('\0')
s = f.read()
s = s.split('\0')
print('%-10s %-5d %s' % (n, pid, ' '.join(s)))

View file

@ -13,6 +13,7 @@ import code
#usb.trace_enabled = True
#tls.trace_enabled = True
def identify():
def update_cb(e):
print('Capture error: %s, try again' % repr(e))
@ -21,6 +22,7 @@ def identify():
print('Got finger %x for user recordid %d. Hash: %s' % (subtype, usrid, hexlify(hsh).decode()))
def enroll(sid, finger):
def update_cb(x, e):
if e is not None:
@ -31,4 +33,3 @@ def enroll(sid, finger):
recid = sensor.enroll(sid, finger, update_cb)
print('Created a finger record with dbid %d' % recid)

View file

@ -3,26 +3,19 @@
from setuptools import setup
setup(name='python-validity',
version='0.9',
py_modules = [],
packages=['validitysensor'],
scripts=[
'bin/validity-led-dance',
'bin/validity-sensors-firmware',
],
install_requires=[
'cryptography >= 2.1.4',
'pyusb >= 1.0.0',
'pyyaml >= 3.12'
],
data_files=[
('share/dbus-1/system.d/', ['dbus_service/io.github.uunicorn.Fprint.conf']),
('lib/python-validity/', ['dbus_service/dbus-service']),
('share/python-validity/playground/', [
'scripts/dbus-cmd.py',
'scripts/lsdbus.py',
'scripts/factory-reset.py',
'scripts/prototype.py'
]),
]
)
version='0.9',
py_modules=[],
packages=['validitysensor'],
scripts=[
'bin/validity-led-dance',
'bin/validity-sensors-firmware',
],
install_requires=['cryptography >= 2.1.4', 'pyusb >= 1.0.0', 'pyyaml >= 3.12'],
data_files=[
('share/dbus-1/system.d/', ['dbus_service/io.github.uunicorn.Fprint.conf']),
('lib/python-validity/', ['dbus_service/dbus-service']),
('share/python-validity/playground/', [
'scripts/dbus-cmd.py', 'scripts/lsdbus.py', 'scripts/factory-reset.py',
'scripts/prototype.py'
]),
])

View file

@ -1,5 +1,6 @@
from enum import Enum, auto
class Blobs(Enum):
init_hardcoded = auto()
init_hardcoded_clean_slate = auto()
@ -22,6 +23,7 @@ def __load_blob(blob):
globals()[blob] = getattr(blobs, blob)
return globals()[blob]
for p in dir(Blobs):
if isinstance(getattr(Blobs, p), Blobs):
globals()[p] = lambda bname=p: __load_blob(bname)

View file

@ -1,7 +1,6 @@
from .util import unhex
init_hardcoded=unhex('''
init_hardcoded = unhex('''
06020000013917b3dda91383b5bcac64fa4ad35dce96570a9d2d974b80926a431f9cd46248980a263c6fcef6a82839a90b59ac590848859
afac817b7d53bf51cd3205c1b8f43048be8253c3bd247937c837aca8b18d3cc8ee8c8971ac4f688813cf3d8550d71496985b7ec07ff2dc7
896d330fdab263a0ee433a5c4bc910439d1c6161853feb03f5502209502e7308beb7919473cfe69f422c30502d226a4d0a34d96c8c77956
@ -13,9 +12,9 @@ e024ca6b9a48332c1a69a5a3fdd24b964cf7e7c55229bb0b48a6e339eb2c42d07ec850a4ee780660
b3d5cad8d5bd7cea37e58a31307a6d50e6ae379a53f1366678c0741a3d872b8dcfefa7f63128dc8245
''')
init_hardcoded_clean_slate=unhex('')
init_hardcoded_clean_slate = unhex('')
reset_blob=unhex('''
reset_blob = unhex('''
0602000001d6123241376f110935a7ae38b614ced9952eaa38e2984842d0552d984b69ab5c1a70175513319970225d9ca25be063a7d70a2
9dff803240c099ba5386910b69c3b7ca8d0b26ec9a5684fe92af9c6d8068ace0954eb8582adc6208aa6c116b1778ff531dd2b6817a10d66
7e0385d18ac7ccb47eb67f1f54b5b94c84d65529c6e9fe9039218ae9cde123f38ffa52a953ed589d0d8bb48680aeea6544b7ceedbea3216
@ -226,7 +225,7 @@ f72aea07e183577f591a081845ea340797b79c6c8742e8826a6d7df773ec8564025fbb570bfbc001
a5d4483f1
''')
db_write_enable=unhex('''
db_write_enable = unhex('''
06020000015ddf5d76a8e3bab8b10d9f82f0b31652d5b208dff1d20745b7c5442e09db880c80ca103d5b2071d8bdcaab452b900d1785be2
de478669e72a9d082273f0f6176b700ffb65a026af052e76de5f9e247e994bed7c79e34815b465a8070a76da7d365525d7285dfb152d24c
732a471f031d22ebb67d6e27bfff74b3ab1c4780461a460c0ea5710fbd32ab59a6ca9ca3e3e24264640b15245a6c48b6bd20c6848c2307e
@ -262,7 +261,7 @@ a2da95eb8445a6381f3941917bed7fcf01ab199228eadd1968847e4b9a40022d2b0ec68318abf97c
''')
# FIXME this must be very specific to a particular device and constructed on the fly from multiple hardcoded tables:
identify_prg=unhex('''
identify_prg = unhex('''
02980000002300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210
000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a020
0b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc2
@ -295,7 +294,7 @@ c1e1e1c221f201d21201e1c1f34242221201f20221f201e241e241d2020221e2420231d221e211e1
''')
# The following blob has only 1 byte difference from the above
enroll_prg=unhex('''
enroll_prg = unhex('''
02980000002300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210
000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a020
0b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc2
@ -327,7 +326,7 @@ c1e1e1c221f201d21201e1c1f34242221201f20221f201e241e241d2020221e2420231d221e211e1
81808180818081808180818081808180818081808080808080808080807f807f807f807f7f7e7e
''')
calibrate_prg=unhex('''
calibrate_prg = unhex('''
0298006103230000002000080000200080000001003200700000000080202005002420000050207736282
0010030200100082170000c210000482102004c210000582000005c20000060200000682005006c200129
70200121742001887820018084202000942001809c200902a0200b19b4200000b8203b04bc201400c0200
@ -365,4 +364,3 @@ c2d182e1e30182e1c321d341d341e321c301e1e241e201f201d1c321a301e1c211e21341f1e20202
8080808180818081808080818081808180818081808180808081808180818081808180818081808180818
0818081808180818081808080808080808080807f807f807f807f7f7e7e
''')

View file

@ -1,7 +1,6 @@
from .util import unhex
init_hardcoded=unhex('''
init_hardcoded = unhex('''
06020000014a231406e5542fc6dc3b1aedebe68f55596ad3ca13f6e019994c6f71672fff756fbde0511d09d45978b12ba415b3694a0e763
48c8cfe9dbb9abf86813fc0c67c1005519a6f87360c2fb3e12bd0a9e012b06d9f5c9b44ccc6645b0fbd47afe45c8c874fcb88fbfd18fb7a
9b3241351f256acce689f9586a52b01f8fdcb66cdf3b340b1f9f386d58ca24fdfcdfbcebefb5f3a3c2a08357721040235a20ce1ee2f4f78
@ -15,7 +14,7 @@ f3135c5e78820e36653fa3db535f57c71897242939d7da50f81070ce9ab81c61af6ac29a6c6c4a5d
2999d1c0e7acf67e598696cd58cc4bdb1b7c037ee9a085f784c4
''')
init_hardcoded_clean_slate=unhex('''
init_hardcoded_clean_slate = unhex('''
06020000012c40c9d271378bc0912ef5dced69bd81b7fc16972c7b46e621af54a00e2cc6baca6eb83ea30222dfc6c925262006ae93412ea
cf482f2034ee7b13297474b7e1e91f279cac2ccb7195443e4dd3328cfd292ade073fcc2eaa8f07b77231130ba997f921b9be7b4fb6cc691
0d2976b3e050913b27dbe73afd6e964260b9435ebab5117e71f7cb68464d4b6f8afc7e1a421f671f5854a1d0c8ab93ed3b88b2bc1a42875
@ -32,7 +31,7 @@ b4c74c39900830abc6906a1004bef1b5b7dbbbeb5ec1b22604ac86429b9f56511b746a7124c449b8
aa41249faeef4d838e280cb5d6fc19cfe86c75f
''')
reset_blob=unhex('''
reset_blob = unhex('''
06020000018772bd56dd58d64023e1745f7c253a49b32dd6a02bc32347195b6763bfcc23c9e0beb0c5809e06a5628629f28c4048530a5cd
df6f48391ea0c2cb5a7ffe93ef04c8b4dad584117e65aac085c25062a0f12a8ee432c7ecbb6613c28b743e4a75e382afc6b8037e342d466
7b66a73691edc6b25698c15e78d9d67f7cc56274e99e6b7bb5fba32dd42d74dfa672f414c4a29302b30a202d00a2571d2a884169e82106c
@ -252,7 +251,7 @@ f20332657d2ca6728b9865a6bfdc9a9055a6ab86cb782307c2c0255525884bf8060f8aed7ec034f3
20f8bb8d94784228934870046f60ac937af4957c9414bcc33895fcc183062be4e4bff56f9c89838ead8e433dc604536938
''')
db_write_enable=unhex('''
db_write_enable = unhex('''
0602000001f48001074892b6c57deb7889b5ebf86bc3040f6d91ff1f68765f046591184be08cf36c154b7ec5368139d0f9532382214379a
ff3ffbfe4659e2f274e864bd0ad660f99e21da2bab677dbfa907a66ce110c180d2ddc5dfe40b8ed975cbedffc11631f12f8bd646a0ee82d
44d2a6c1ec9cfbd40f485cb3d9124376b97b4a3349b0a730adda626d8ac28ec20e886aab1b8851deee3431c4d89c8bb3e787eaa9c0323df

View file

@ -1,7 +1,6 @@
from .util import unhex
init_hardcoded=unhex('''
init_hardcoded = unhex('''
06020000014a231406e5542fc6dc3b1aedebe68f55596ad3ca13f6e019994c6f71672fff756fbde0511d09d45978b12ba415b3694a0e763
48c8cfe9dbb9abf86813fc0c67c1005519a6f87360c2fb3e12bd0a9e012b06d9f5c9b44ccc6645b0fbd47afe45c8c874fcb88fbfd18fb7a
9b3241351f256acce689f9586a52b01f8fdcb66cdf3b340b1f9f386d58ca24fdfcdfbcebefb5f3a3c2a08357721040235a20ce1ee2f4f78
@ -15,7 +14,7 @@ f3135c5e78820e36653fa3db535f57c71897242939d7da50f81070ce9ab81c61af6ac29a6c6c4a5d
2999d1c0e7acf67e598696cd58cc4bdb1b7c037ee9a085f784c4
''')
init_hardcoded_clean_slate=unhex('''
init_hardcoded_clean_slate = unhex('''
06020000012c40c9d271378bc0912ef5dced69bd81b7fc16972c7b46e621af54a00e2cc6baca6eb83ea30222dfc6c925262006ae93412ea
cf482f2034ee7b13297474b7e1e91f279cac2ccb7195443e4dd3328cfd292ade073fcc2eaa8f07b77231130ba997f921b9be7b4fb6cc691
0d2976b3e050913b27dbe73afd6e964260b9435ebab5117e71f7cb68464d4b6f8afc7e1a421f671f5854a1d0c8ab93ed3b88b2bc1a42875
@ -32,7 +31,7 @@ b4c74c39900830abc6906a1004bef1b5b7dbbbeb5ec1b22604ac86429b9f56511b746a7124c449b8
aa41249faeef4d838e280cb5d6fc19cfe86c75f
''')
reset_blob=unhex('''
reset_blob = unhex('''
06020000018772bd56dd58d64023e1745f7c253a49b32dd6a02bc32347195b6763bfcc23c9e0beb0c5809e06a5628629f28c4048530a5cd
df6f48391ea0c2cb5a7ffe93ef04c8b4dad584117e65aac085c25062a0f12a8ee432c7ecbb6613c28b743e4a75e382afc6b8037e342d466
7b66a73691edc6b25698c15e78d9d67f7cc56274e99e6b7bb5fba32dd42d74dfa672f414c4a29302b30a202d00a2571d2a884169e82106c
@ -252,7 +251,7 @@ f20332657d2ca6728b9865a6bfdc9a9055a6ab86cb782307c2c0255525884bf8060f8aed7ec034f3
20f8bb8d94784228934870046f60ac937af4957c9414bcc33895fcc183062be4e4bff56f9c89838ead8e433dc604536938
''')
db_write_enable=unhex('''
db_write_enable = unhex('''
0602000001f48001074892b6c57deb7889b5ebf86bc3040f6d91ff1f68765f046591184be08cf36c154b7ec5368139d0f9532382214379a
ff3ffbfe4659e2f274e864bd0ad660f99e21da2bab677dbfa907a66ce110c180d2ddc5dfe40b8ed975cbedffc11631f12f8bd646a0ee82d
44d2a6c1ec9cfbd40f485cb3d9124376b97b4a3349b0a730adda626d8ac28ec20e886aab1b8851deee3431c4d89c8bb3e787eaa9c0323df

View file

@ -8,28 +8,34 @@ from .flash import call_cleanups
from .sid import *
from .winbio_constants import finger_names
class UserStorage():
def __init__(self, dbid, name):
self.dbid=dbid
self.name=name
self.users=[]
self.dbid = dbid
self.name = name
self.users = []
def __repr__(self):
return '<UserStorage: dbid=%04x name=%s users=%s>' % (self.dbid, repr(self.name), repr(self.users))
return '<UserStorage: dbid=%04x name=%s users=%s>' % (self.dbid, repr(
self.name), repr(self.users))
class User():
def __init__(self, dbid, identity):
self.dbid=dbid
self.identity=identity
self.fingers=[]
self.dbid = dbid
self.identity = identity
self.fingers = []
def __repr__(self):
return '<User: dbid=%04x identity=%s fingers=%s>' % (self.dbid, repr(self.identity), repr(self.fingers))
return '<User: dbid=%04x identity=%s fingers=%s>' % (self.dbid, repr(
self.identity), repr(self.fingers))
def subtype_to_string(s: int):
finger_name = finger_names.get(s, None)
return finger_name or 'Unknown'
def parse_user_storage(rsp):
rc, = unpack('<H', rsp[:2])
@ -37,25 +43,26 @@ def parse_user_storage(rsp):
return None
assert_status(rsp[:2])
rsp=rsp[2:]
rsp = rsp[2:]
hdr, rsp = rsp[:8], rsp[8:]
recid, usercnt, namesz, unknwn = unpack('<HHHH', hdr)
usrtab, rsp = rsp[:4*usercnt], rsp[4*usercnt:]
usrtab, rsp = rsp[:4 * usercnt], rsp[4 * usercnt:]
name, rsp = rsp[:namesz], rsp[namesz:]
if len(rsp) > 0:
raise Exception('Junk at the end of the storage info response: %s' % rsp.hex())
storage=UserStorage(recid, name)
storage = UserStorage(recid, name)
while len(usrtab) > 0:
rec, usrtab = usrtab[:4], usrtab[4:]
urid, valsz = unpack('<HH', rec)
storage.users += [ { 'dbid': urid, 'valueSize': valsz } ]
storage.users += [{'dbid': urid, 'valueSize': valsz}]
return storage
def parse_identity(b):
t, b = b[:4], b[4:]
t, = unpack('<L', t)
@ -65,33 +72,35 @@ def parse_identity(b):
l, = unpack('<L', l)
return sid_from_bytes(b[:l])
raise Exception('Don''t know how to handle identity type %d' % t)
raise Exception('Don' 't know how to handle identity type %d' % t)
def parse_user(rsp: bytes):
assert_status(rsp[:2])
rsp=rsp[2:]
rsp = rsp[2:]
hdr, rsp = rsp[:8], rsp[8:]
recid, fingercnt, unknwn, identitysz = unpack('<HHHH', hdr)
fingertab, rsp = rsp[:8*fingercnt], rsp[8*fingercnt:]
fingertab, rsp = rsp[:8 * fingercnt], rsp[8 * fingercnt:]
identity, rsp = rsp[:identitysz], rsp[identitysz:]
if len(rsp) > 0:
raise Exception('Junk at the end of the user info response: %s' % rsp.hex())
identity = parse_identity(identity)
user=User(recid, identity)
user = User(recid, identity)
while len(fingertab) > 0:
rec, fingertab = fingertab[:8], fingertab[8:]
frid, subtype, stgid, valsz = unpack('<HHHH', rec)
user.fingers += [ { 'dbid': frid, 'subtype': subtype, 'storage': stgid, 'valueSize': valsz } ]
user.fingers += [{'dbid': frid, 'subtype': subtype, 'storage': stgid, 'valueSize': valsz}]
return user
def identity_to_bytes(identity: str):
if isinstance(identity, SidIdentity):
b=identity.to_bytes()
b = identity.to_bytes()
b = pack('<LL', 3, len(b)) + b
# May not be neccessary, but windows union has a minimum size of 0x4c bytes
@ -101,7 +110,8 @@ def identity_to_bytes(identity: str):
return b
else:
raise Exception('Don''t know how to handle identity %s' % repr(identity))
raise Exception('Don' 't know how to handle identity %s' % repr(identity))
class DbRecord():
def __init__(self):
@ -113,29 +123,24 @@ class DbRecord():
def __repr__(self):
return '<DbRecord: dbid=%d type=%d storage=%d value=%s children=%s>' % (
self.dbid,
self.type,
self.storage,
repr(self.value),
repr(self.children)
)
self.dbid, self.type, self.storage, repr(self.value), repr(self.children))
class Db():
class Info():
def __init__(self, total, used, free, records, roots):
self.total = total # partition size
self.used = used # used (not deleted)
self.free = free # unallocated space
self.records = records # total number, including deleted
self.total = total # partition size
self.used = used # used (not deleted)
self.free = free # unallocated space
self.records = records # total number, including deleted
self.roots = roots
def __repr__(self):
return 'Db.Info(total=%d, used=%d, free=%d, records=%d, roots=%s)' % (
self.total, self.used, self.free, self.records, repr(self.roots))
self.total, self.used, self.free, self.records, repr(self.roots))
def get_user_storage(self, dbid=0, name=''):
name=name.encode()
name = name.encode()
if len(name) > 0:
name += b'\0'
@ -148,7 +153,7 @@ class Db():
def get_storage_data(self):
stg = self.get_user_storage(name='StgWindsor')
rc = self.get_record_children(stg.dbid).children
return [i['dbid'] for i in rc if i['type'] == 8] # 8 == "data" type
return [i['dbid'] for i in rc if i['type'] == 8] # 8 == "data" type
def get_user(self, dbid):
return parse_user(tls.cmd(pack('<BHHH', 0x4a, dbid, 0, 0)))
@ -171,7 +176,7 @@ class Db():
rec = DbRecord()
rec.dbid, rec.type, rec.storage, sz = unpack('<xxHHHHxx', rsp[:12])
rec.value = rsp[12:12+sz]
rec.value = rsp[12:12 + sz]
return rec
@ -182,10 +187,10 @@ class Db():
rec = DbRecord()
rec.dbid, rec.type, rec.storage, sz, cnt = unpack('<xxHHHHHxx', rsp[:14])
rsp = rsp[14:]
rec.children=[]
rec.children = []
for i in range(0, cnt):
dbid, typ = unpack('<HH', rsp[i*4:i*4+4])
rec.children += [{ 'dbid': dbid, 'type': typ }]
dbid, typ = unpack('<HH', rsp[i * 4:i * 4 + 4])
rec.children += [{'dbid': dbid, 'type': typ}]
return rec
@ -200,12 +205,12 @@ class Db():
unknown1, unknown0, total, used, free, records, nroots = unpack('<LLLLLHH', rsp[:0x18])
# Seems to always be unknown1 == 1, unknown0 == 0
rsp = rsp[0x18:]
roots = [unpack('<H', rsp[i*2:i*2+2])[0] for i in range(0, nroots)]
roots = [unpack('<H', rsp[i * 2:i * 2 + 2])[0] for i in range(0, nroots)]
return Db.Info(total, used, free, records, roots)
def new_record(self, parent, typ, storage, data):
self.db_info() # TODO check free space, compact the partition when out of storage
self.db_info() # TODO check free space, compact the partition when out of storage
assert_status(tls.cmd(db_write_enable))
try:
rsp = tls.cmd(pack('<BHHHH', 0x47, parent, typ, storage, len(data)) + data)
@ -240,11 +245,11 @@ class Db():
val = hexlify(rec.value).decode()
if len(val) > 80:
val = val[:80] + '...'
print('%s%d (type %d) %s' % (' '*depth, rec.dbid, rec.type, val))
print('%s%d (type %d) %s' % (' ' * depth, rec.dbid, rec.type, val))
rec = self.get_record_children(root)
for c in rec.children:
self.dump_raw(c['dbid'], depth+1)
self.dump_raw(c['dbid'], depth + 1)
def dump_all(self):
stg = self.get_user_storage(name='StgWindsor')
@ -252,7 +257,8 @@ class Db():
for u in usrs:
print('%2d: User %s with %d fingers:' % (u.dbid, repr(u.identity), len(u.fingers)))
for f in u.fingers:
print(' %2d: %02x (%s)' % (f['dbid'], f['subtype'], subtype_to_string(f['subtype'])))
print(' %2d: %02x (%s)' %
(f['dbid'], f['subtype'], subtype_to_string(f['subtype'])))
db = Db()

View file

@ -4,12 +4,16 @@ from .util import assert_status, unhex
from .blobs import db_write_enable
from .hw_tables import flash_ic_table_lookup
class FlashInfo():
def __init__(self, ic, blocks, unknown0, blocksize, unknown1, partitions):
self.ic, self.blocks, self.unknown0, self.blocksize, self.unknown1, self.partitions = ic, blocks, unknown0, blocksize, unknown1, partitions
def __repr__(self):
return 'FlashInfo(%s, 0x%x, 0x%x, 0x%x, 0x%x, %s)' % (repr(self.ic), self.blocks, self.unknown0, self.blocksize, self.unknown1, repr(self.partitions))
return 'FlashInfo(%s, 0x%x, 0x%x, 0x%x, 0x%x, %s)' % (repr(
self.ic), self.blocks, self.unknown0, self.blocksize, self.unknown1,
repr(self.partitions))
# type 01 is for the firmware - written blocks are decrypted on the fly using fw key
# access lvl:
@ -20,27 +24,31 @@ class PartitionInfo():
self.id, self.type, self.access_lvl, self.offset, self.size = id, type, access_lvl, offset, size
def __repr__(self):
return 'PartitionInfo(0x%02x, 0x%02x, 0x%04x, 0x%08x, 0x%08x)' % (self.id, self.type, self.access_lvl, self.offset, self.size)
return 'PartitionInfo(0x%02x, 0x%02x, 0x%04x, 0x%08x, 0x%08x)' % (
self.id, self.type, self.access_lvl, self.offset, self.size)
def get_flash_info():
rsp=tls.cmd(unhex('3e'))
rsp = tls.cmd(unhex('3e'))
assert_status(rsp)
rsp=rsp[2:]
hdr=rsp[:0xe]
rsp=rsp[0xe:]
rsp = rsp[2:]
hdr = rsp[:0xe]
rsp = rsp[0xe:]
jid0, jid1, blocks, unknown0, blocksize, unknown1, pcnt = unpack('<HHHHHHH', hdr)
ic=flash_ic_table_lookup(jid0, jid1, blocks*blocksize)
ic = flash_ic_table_lookup(jid0, jid1, blocks * blocksize)
if ic == None:
raise Exception('Unknown flash IC. JEDEC id=%x:%x, size=%dx%d' % (jid0, jid1, blocks, blocksize))
raise Exception('Unknown flash IC. JEDEC id=%x:%x, size=%dx%d' %
(jid0, jid1, blocks, blocksize))
partitions=[rsp[i*0xc:(i+1)*0xc] for i in range(0, pcnt)]
partitions=[unpack('<BBHLL', i) for i in partitions]
partitions=[PartitionInfo(*i) for i in partitions]
partitions = [rsp[i * 0xc:(i + 1) * 0xc] for i in range(0, pcnt)]
partitions = [unpack('<BBHLL', i) for i in partitions]
partitions = [PartitionInfo(*i) for i in partitions]
return FlashInfo(ic, blocks, unknown0, blocksize, unknown1, partitions)
# >>> 4302 -- get partition header (get fwext info)
# b004 -- no fw detected
# 0000
@ -59,43 +67,50 @@ class ModuleInfo():
self.type, self.subtype, self.major, self.minor, self.size = type, subtype, major, minor, size
def __repr__(self):
return 'ModuleInfo(0x%04x, 0x%04x, %d, %d, %d)' % (self.type, self.subtype, self.major, self.minor, self.size)
return 'ModuleInfo(0x%04x, 0x%04x, %d, %d, %d)' % (self.type, self.subtype, self.major,
self.minor, self.size)
class FirmwareInfo():
def __init__(self, major, minor, buildtime, modules):
self.major, self.minor, self.buildtime, self.modules = major, minor, buildtime, modules
def __repr__(self):
return 'FirmwareInfo(%d, %d, %d, %s)' % (self.major, self.minor, self.buildtime, repr(self.modules))
return 'FirmwareInfo(%d, %d, %d, %s)' % (self.major, self.minor, self.buildtime,
repr(self.modules))
def get_fw_info(partition):
rsp=tls.cmd(pack('<BB', 0x43, partition))
rsp = tls.cmd(pack('<BB', 0x43, partition))
# don't want to throw exception here - it is normal not to have FW when we're about to upload it
if len(rsp) == 2 and rsp[1] == 4 and rsp[0] == 0xb0:
return None
assert_status(rsp)
rsp=rsp[2:]
hdr=rsp[:0xa]
rsp=rsp[0xa:]
rsp = rsp[2:]
hdr = rsp[:0xa]
rsp = rsp[0xa:]
major, minor, modcnt, buildtime = unpack('<HHHL', hdr)
modules=[rsp[i*0xc:(i+1)*0xc] for i in range(0, modcnt)]
modules=[unpack('<HHHHL', i) for i in modules]
modules=[ModuleInfo(*i) for i in modules]
modules = [rsp[i * 0xc:(i + 1) * 0xc] for i in range(0, modcnt)]
modules = [unpack('<HHHHL', i) for i in modules]
modules = [ModuleInfo(*i) for i in modules]
return FirmwareInfo(major, minor, buildtime, modules)
def write_enable():
assert_status(tls.cmd(db_write_enable))
def call_cleanups():
rsp = tls.cmd(b'\x1a')
err = unpack('<H', rsp[:2])[0]
if err == 0x0491: # Nothing to commit
return # don't throw an exception, just ignore
if err == 0x0491: # Nothing to commit
return # don't throw an exception, just ignore
assert_status(rsp)
def erase_flash(partition):
assert_status(tls.cmd(db_write_enable))
try:
@ -103,13 +118,15 @@ def erase_flash(partition):
finally:
call_cleanups()
def read_flash(partition, addr, size):
cmd = pack('<BBBHLL', 0x40, partition, 1, 0, addr, size)
rsp = tls.cmd(cmd)
assert_status(rsp)
sz, = unpack('<xxLxx', rsp[:8])
return rsp[8:8+sz]
return rsp[8:8 + sz]
def write_flash(partition, addr, buf):
tls.cmd(db_write_enable)
@ -120,21 +137,25 @@ def write_flash(partition, addr, buf):
finally:
call_cleanups()
def write_flash_all(partition, ptr, buf):
bs = 0x1000
while len(buf) > 0:
chunk, buf = buf[:bs], buf[bs:]
chunk, buf = buf[:bs], buf[bs:]
write_flash(partition, ptr, chunk)
ptr += len(chunk)
def read_flash_all(partition, start, size):
bs = 0x1000
blocks = [read_flash(partition, addr, bs) for addr in range(start, start+size, bs)]
blocks = [read_flash(partition, addr, bs) for addr in range(start, start + size, bs)]
return b''.join(blocks)[:size]
def write_fw_signature(partition, signature):
rsp=tls.cmd(pack('<BBxH', 0x42, partition, len(signature)) + signature)
rsp = tls.cmd(pack('<BBxH', 0x42, partition, len(signature)) + signature)
assert_status(rsp)
def read_tls_flash():
return read_flash(1, 0, 0x1000)

View file

@ -1,81 +1,775 @@
from .table_types import SensorTypeInfo, SensorCaptureProg
SensorTypeInfo.table=[
SensorTypeInfo(sensor_type=0x00db, bytes_per_line=0x98, repeat_multiplier=1, lines_per_calibration_data=144, line_width=144, calibration_blob='101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f'),
SensorTypeInfo(sensor_type=0x00e4, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=100, line_width=112, calibration_blob='9392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e'),
SensorTypeInfo(sensor_type=0x00ed, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
SensorTypeInfo(sensor_type=0x0199, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
SensorTypeInfo(sensor_type=0x00b5, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
SensorTypeInfo(sensor_type=0x0885, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
SensorTypeInfo(sensor_type=0x1055, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
SensorTypeInfo(sensor_type=0x1825, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
SensorTypeInfo(sensor_type=0x1ff5, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
SensorTypeInfo(sensor_type=0x00b3, bytes_per_line=0x60, repeat_multiplier=2, lines_per_calibration_data=84, line_width=85, calibration_blob='898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'),
SensorTypeInfo(sensor_type=0x143b, bytes_per_line=0x5c, repeat_multiplier=2, lines_per_calibration_data=84, line_width=84, calibration_blob='898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'),
SensorTypeInfo(sensor_type=0x08b1, bytes_per_line=0x58, repeat_multiplier=2, lines_per_calibration_data=78, line_width=78, calibration_blob='9b9a9996959392918f8e8d8b8a89878685837d7b7a7977767573716f6d6b6a695d5b5a595756555251504e4d4c4a41403e3d3c3a393432312c2a28261e1d1c1a19181615141211100d0c0a090806'),
SensorTypeInfo(sensor_type=0x00e1, bytes_per_line=0x58, repeat_multiplier=2, lines_per_calibration_data=78, line_width=78, calibration_blob='9b9a9996959392918f8e8d8b8a89878685837d7b7a7977767573716f6d6b6a695d5b5a595756555251504e4d4c4a41403e3d3c3a393432312c2a28261e1d1c1a19181615141211100d0c0a090806'),
SensorTypeInfo(sensor_type=0x00ea, bytes_per_line=0x5c, repeat_multiplier=1, lines_per_calibration_data=84, line_width=84, calibration_blob='898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'),
SensorTypeInfo(sensor_type=0x0194, bytes_per_line=0x7c, repeat_multiplier=3, lines_per_calibration_data=84, line_width=114, calibration_blob='000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253'),
SensorTypeInfo(sensor_type=0x0126, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
SensorTypeInfo(sensor_type=0x0117, bytes_per_line=0xa0, repeat_multiplier=4, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
SensorTypeInfo(sensor_type=0x08f3, bytes_per_line=0xa0, repeat_multiplier=1, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
SensorTypeInfo(sensor_type=0x08f6, bytes_per_line=0xa0, repeat_multiplier=1, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
SensorTypeInfo(sensor_type=0x0121, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
SensorTypeInfo(sensor_type=0x0b4b, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
SensorTypeInfo(sensor_type=0x0b4d, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
SensorTypeInfo(sensor_type=0x0130, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=40, line_width=144, calibration_blob='15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
SensorTypeInfo(sensor_type=0x0be2, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=40, line_width=144, calibration_blob='15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
SensorTypeInfo(sensor_type=0x0be1, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=40, line_width=144, calibration_blob='15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
SensorTypeInfo(sensor_type=0x0518, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=40, line_width=144, calibration_blob='15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
SensorTypeInfo(sensor_type=0x0179, bytes_per_line=0x98, repeat_multiplier=3, lines_per_calibration_data=56, line_width=144, calibration_blob='3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172'),
SensorTypeInfo.table = [
SensorTypeInfo(
sensor_type=0x00db,
bytes_per_line=0x98,
repeat_multiplier=1,
lines_per_calibration_data=144,
line_width=144,
calibration_blob=
'101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f'
),
SensorTypeInfo(
sensor_type=0x00e4,
bytes_per_line=0x78,
repeat_multiplier=2,
lines_per_calibration_data=100,
line_width=112,
calibration_blob=
'9392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e'
),
SensorTypeInfo(
sensor_type=0x00ed,
bytes_per_line=0x78,
repeat_multiplier=2,
lines_per_calibration_data=112,
line_width=112,
calibration_blob=
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
),
SensorTypeInfo(
sensor_type=0x0199,
bytes_per_line=0x78,
repeat_multiplier=2,
lines_per_calibration_data=112,
line_width=112,
calibration_blob=
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
),
SensorTypeInfo(
sensor_type=0x00b5,
bytes_per_line=0x78,
repeat_multiplier=2,
lines_per_calibration_data=112,
line_width=112,
calibration_blob=
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
),
SensorTypeInfo(
sensor_type=0x0885,
bytes_per_line=0x78,
repeat_multiplier=2,
lines_per_calibration_data=112,
line_width=112,
calibration_blob=
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
),
SensorTypeInfo(
sensor_type=0x1055,
bytes_per_line=0x78,
repeat_multiplier=2,
lines_per_calibration_data=112,
line_width=112,
calibration_blob=
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
),
SensorTypeInfo(
sensor_type=0x1825,
bytes_per_line=0x78,
repeat_multiplier=2,
lines_per_calibration_data=112,
line_width=112,
calibration_blob=
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
),
SensorTypeInfo(
sensor_type=0x1ff5,
bytes_per_line=0x78,
repeat_multiplier=2,
lines_per_calibration_data=112,
line_width=112,
calibration_blob=
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
),
SensorTypeInfo(
sensor_type=0x00b3,
bytes_per_line=0x60,
repeat_multiplier=2,
lines_per_calibration_data=84,
line_width=85,
calibration_blob=
'898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'
),
SensorTypeInfo(
sensor_type=0x143b,
bytes_per_line=0x5c,
repeat_multiplier=2,
lines_per_calibration_data=84,
line_width=84,
calibration_blob=
'898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'
),
SensorTypeInfo(
sensor_type=0x08b1,
bytes_per_line=0x58,
repeat_multiplier=2,
lines_per_calibration_data=78,
line_width=78,
calibration_blob=
'9b9a9996959392918f8e8d8b8a89878685837d7b7a7977767573716f6d6b6a695d5b5a595756555251504e4d4c4a41403e3d3c3a393432312c2a28261e1d1c1a19181615141211100d0c0a090806'
),
SensorTypeInfo(
sensor_type=0x00e1,
bytes_per_line=0x58,
repeat_multiplier=2,
lines_per_calibration_data=78,
line_width=78,
calibration_blob=
'9b9a9996959392918f8e8d8b8a89878685837d7b7a7977767573716f6d6b6a695d5b5a595756555251504e4d4c4a41403e3d3c3a393432312c2a28261e1d1c1a19181615141211100d0c0a090806'
),
SensorTypeInfo(
sensor_type=0x00ea,
bytes_per_line=0x5c,
repeat_multiplier=1,
lines_per_calibration_data=84,
line_width=84,
calibration_blob=
'898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'
),
SensorTypeInfo(
sensor_type=0x0194,
bytes_per_line=0x7c,
repeat_multiplier=3,
lines_per_calibration_data=84,
line_width=114,
calibration_blob=
'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253'
),
SensorTypeInfo(
sensor_type=0x0126,
bytes_per_line=0xa0,
repeat_multiplier=2,
lines_per_calibration_data=56,
line_width=144,
calibration_blob=
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
),
SensorTypeInfo(
sensor_type=0x0117,
bytes_per_line=0xa0,
repeat_multiplier=4,
lines_per_calibration_data=56,
line_width=144,
calibration_blob=
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
),
SensorTypeInfo(
sensor_type=0x08f3,
bytes_per_line=0xa0,
repeat_multiplier=1,
lines_per_calibration_data=56,
line_width=144,
calibration_blob=
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
),
SensorTypeInfo(
sensor_type=0x08f6,
bytes_per_line=0xa0,
repeat_multiplier=1,
lines_per_calibration_data=56,
line_width=144,
calibration_blob=
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
),
SensorTypeInfo(
sensor_type=0x0121,
bytes_per_line=0xa0,
repeat_multiplier=2,
lines_per_calibration_data=56,
line_width=144,
calibration_blob=
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
),
SensorTypeInfo(
sensor_type=0x0b4b,
bytes_per_line=0xa0,
repeat_multiplier=2,
lines_per_calibration_data=56,
line_width=144,
calibration_blob=
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
),
SensorTypeInfo(
sensor_type=0x0b4d,
bytes_per_line=0xa0,
repeat_multiplier=2,
lines_per_calibration_data=56,
line_width=144,
calibration_blob=
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
),
SensorTypeInfo(
sensor_type=0x0130,
bytes_per_line=0xa0,
repeat_multiplier=2,
lines_per_calibration_data=40,
line_width=144,
calibration_blob=
'15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
SensorTypeInfo(
sensor_type=0x0be2,
bytes_per_line=0xa0,
repeat_multiplier=2,
lines_per_calibration_data=40,
line_width=144,
calibration_blob=
'15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
SensorTypeInfo(
sensor_type=0x0be1,
bytes_per_line=0xa0,
repeat_multiplier=2,
lines_per_calibration_data=40,
line_width=144,
calibration_blob=
'15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
SensorTypeInfo(
sensor_type=0x0518,
bytes_per_line=0xa0,
repeat_multiplier=2,
lines_per_calibration_data=40,
line_width=144,
calibration_blob=
'15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
SensorTypeInfo(
sensor_type=0x0179,
bytes_per_line=0x98,
repeat_multiplier=3,
lines_per_calibration_data=56,
line_width=144,
calibration_blob=
'3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172'
),
]
SensorCaptureProg.table=[
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
SensorCaptureProg(major=0x6, minor=0x6, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
SensorCaptureProg(major=0x6, minor=0x7, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
SensorCaptureProg(major=0x6, minor=0x8, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
SensorCaptureProg(major=0x6, minor=0xa, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
SensorCaptureProg(major=0x6, minor=0xb, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
SensorCaptureProg(major=0x6, minor=0x6, build=0x0, u1=0x0, dev_type=0x885, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082150000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000']),
SensorCaptureProg(major=0x6, minor=0x7, build=0x0, u1=0x0, dev_type=0x885, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082150000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x1055, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482103004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x1825, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601062810250101000007c8078c06ff4f80006d0300200307030990098db00b90880991858e08c1810b9190910ac1b828928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f812089920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xb5, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e0034007801000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001023171023171023161023161023160106635205001025010100000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x1ff5, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601062810250101000007c8078c06ff4f80006d0300200307030990098db00b90880991858e08c1810b9190910ac1b828928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f812089920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
SensorCaptureProg(major=0x6, minor=0x7, build=0x0, u1=0x0, dev_type=0x1825, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010240101000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xe4, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221410221410221410221410221401066510250101000007c8078c06ff4f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c0703030720040200002f0004006400000029000400700000003500040080000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xed, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482104004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010240101000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
SensorCaptureProg(major=0x6, minor=0x7, build=0x0, u1=0x0, dev_type=0x143b, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000d600d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c1117003400340200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101c11101c11101c11101c11101c10010657101e0101000007c8078c06ff00004f80006d03002c03070308c608c709930703800ac60994800ac70995800b930996800b940997800b950998800b9608c8800b9708ca800b9808cb800ac808cc800aca08ce800acb08cf800acc099a800ace099b800acf099c800b9a099d800b9b099e800b9c099f800b9d08d0800b9e08d2800b9f08d3800ad008d4800ad208d6800ad308d7800ad40802800ad60803800ad7095a800a02095b800a03095c800b5a095d800b5b08d9800b5c08da800b5d08db800ad908dd800ada08de800adb08df800add095e800ade095f800adf0960800b5e0961800b5f0962800b600963800b6108e1800b6208e2800b6308e3800ae108e5800ae208e6800ae308e7800ae50964800ae60965800ae70966800b640967800b650968800b66096e800b6708e9800b6808ea800b6e08eb800ae908ed800aea08ef800aeb08ee800aed096f800aef0970800aee0971800b6f0972800b700974800b710975800b7208f0800b7408f1800b7508f2800af008f4800af108f5800af208f6800af40976800af50977800af60979800b760978800b77097a800b79097b800b7808f8800b7a08fa800b7b08fc800af808fd800afa08fe800afc0900800c2007030307200402002f0004005400000029000400580000003500040068000000']),
SensorCaptureProg(major=0x6, minor=0x7, build=0x0, u1=0x0, dev_type=0xb3, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082140000c210000482106004c210000582000005c2000006020000068200a006c20012970200121742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200100c4200100c82002003300100000000080cc2000002c01d0200000a1013200440000000080dc205302e0206401e420a901e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c11180034003c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101c11101c11101c11101c11101c10010657101e0101000007c8078c06ff00004f80006d03002c0308c608c70703800ac60993800ac70994800b930995800b940996800b950997800b960998800b9708c8800b9808ca800ac808cb800aca08cc800acb08ce800acc08cf800ace099a800acf099b800b9a099c800b9b099d800b9c099e800b9d099f800b9e08d0800b9f08d2800ad008d3800ad208d4800ad308d6800ad408d7800ad60802800ad70803800a02095a800a03095b800b5a095c800b5b095d800b5c08d9800b5d08da800ad908db800ada08dd800adb08de800add08df800ade095e800adf095f800b5e0960800b5f0961800b600962800b610963800b6208e1800b6308e2800ae108e3800ae208e5800ae308e6800ae508e7800ae60964800ae70965800b640966800b650967800b660968800b67096e800b6808e9800b6e08ea800ae908eb800aea08ed800aeb08ef800aed08ee800aef096f800aee0970800b6f0971800b700972800b710974800b720975800b7408f0800b7508f1800af008f2800af108f4800af208f5800af408f6800af50976800af60977800b760979800b770978800b79097a800b78097b800b7a08f8800b7b08fa800af808fc800afa08fd800afc08fe800afd090080808080240c0703030720040200000000002f0004005400000029000400580000003500040068000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xe1, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032006c000000008020200400242000005020773628200100302001003c208000082138000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084203000942001809c200902a0200b19bc201400c0200200c4200100c82002003300100000000080cc2000006401d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c11160034001402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b10101b10101b10101b0f101b0f010656101e0101000007c8078c06ff4f80006d03002c03070308c108bf098f0703800ac10990800abf098d800b8f0991800b900992800b8d08c5800b9108c3800b9208c6800ac508c4800ac308cb800ac608c7800ac40993800acb0994800ac70995800b930997800b940996800b950998800b9708ce800b9608cc800b9808cf800ace08d0800acc08d2800acf08dd800ad0099a800ad2099b800add099c800b9a0803800b9b095a800b9c095b800a0308de800b5a08df800b5b08e1800ade08eb800adf08ed800ae108f1800aeb095c800aed0962800af10963800b5c096f800b620970800b630971800b6f08f2800b7008f5800b7108f6800af208fa800af508f8800af608fc800afa0974800af80976800afc097b800b74097a800b76097f800b7b097e800b7a08fd800b7f08fe800b7e090b800afd090c800afe090d800b0b090f800b0c0980800b0d0982800b0f0983800b80097d800b820978800b83097c800b7d0914800b780908800b7c0909800b140907800b080905800b090904800b070979800b050977800b040975800b790972800b77096c800b750936800b7209348080800c20070303072004020000002f0004004e00000029000400540000003500040064000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x8b1, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032006c000000008020200400242000005020773628200100302001003c208000082138000c210000482107004c210000582000005c2000006020000068200a006c20014970200141742001887820018084203000942001809c200902a0200b19bc201400c0200200c4200100c82002003300100000000080cc2000002c00d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c11160034001402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b10101b10101b10101b0f101b0f010656101e0101000007c8078c06ff4f80006d03002c03070308c108bf098f0703800ac10990800abf098d800b8f0991800b900992800b8d08c5800b9108c3800b9208c6800ac508c4800ac308cb800ac608c7800ac40993800acb0994800ac70995800b930997800b940996800b950998800b9708ce800b9608cc800b9808cf800ace08d0800acc08d2800acf08dd800ad0099a800ad2099b800add099c800b9a0803800b9b095a800b9c095b800a0308de800b5a08df800b5b08e1800ade08eb800adf08ed800ae108f1800aeb095c800aed0962800af10963800b5c096f800b620970800b630971800b6f08f2800b7008f5800b7108f6800af208fa800af508f8800af608fc800afa0974800af80976800afc097b800b74097a800b76097f800b7b097e800b7a08fd800b7f08fe800b7e090b800afd090c800afe090d800b0b090f800b0c0980800b0d0982800b0f0983800b80097d800b820978800b83097c800b7d0914800b780908800b7c0909800b140907800b080905800b090904800b070979800b050977800b040975800b790972800b77096c800b750936800b7209348080800c20070303072004020000002f0004004e00000029000400540000003500040064000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xea, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000d600d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c11170034003002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b11101b11101b11101b11101b1001064d101d0101000007c8078c06ff00004f80006d03002c03070308c608c709930703800ac60994800ac70995800b930996800b940997800b950998800b9608c8800b9708ca800b9808cb800ac808cc800aca08ce800acb08cf800acc099a800ace099b800acf099c800b9a099d800b9b099e800b9c099f800b9d08d0800b9e08d2800b9f08d3800ad008d4800ad208d6800ad308d7800ad40802800ad60803800ad7095a800a02095b800a03095c800b5a095d800b5b08d9800b5c08da800b5d08db800ad908dd800ada08de800adb08df800add095e800ade095f800adf0960800b5e0961800b5f0962800b600963800b6108e1800b6208e2800b6308e3800ae108e5800ae208e6800ae308e7800ae50964800ae60965800ae70966800b640967800b650968800b66096e800b6708e9800b6808ea800b6e08eb800ae908ed800aea08ef800aeb08ee800aed096f800aef0970800aee0971800b6f0972800b700974800b710975800b7208f0800b7408f1800b7508f2800af008f4800af108f5800af208f6800af40976800af50977800af60979800b760978800b77097a800b79097b800b7808f8800b7a08fa800b7b08fc800af808fd800afa08fe800afc0900800c2007030307200402002f0004005400000029000400540000003500040064000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x199, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482107004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340078010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010250101000007c8078c06ff0000000000004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0x8f3, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032006000000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20700070207000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002a0030000330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c64200050630c642000606c0c64200070620c642000806b0c64200090610c642000a06a0c642000b0600c642000c0690c642000d05f0c642000e05e0c642000f04f0c642000005d0c642000104e0c642000205c0c642000304d0c642000405b0c642000504c0c642000605a0c642000704b0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d10c642000d02b0c642000e0d20c642000f02a0c64200000d30c64200010290c64200020d60c64200030280c64200040d70c642000501d0c64200060d80c642000701c0c64200080d90c642000901b0c642000a0da0c642000b01a0c642000c0de0c642000d0190c642000e0df0c642000f0150c64200000e00c64200010140c64200020e10c64200030130c64200040e20c64200050120c64200060e40c64200070110c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b070100002403089808a9089908a8089a08a7089b08a6089c08a4089d08a3089e08a2089f08a1c0102c03088808b9088908b8088a08b7088b08b3089208b2089308b1089408b0089508afc01003087108c6087208c5087d08c2087e08c1087f08c0088008bf088108bb088708bac0100628070103084f085e085f08690860086a0861086b0862086c086308c9086f08c8087008c7c010030847082e0848082f08490830084a0831084b085a084c085b084d085c084e085dc01003082a08d2082b08d1082c08ce083808cd083908cc083a08cb083b08ca0846082dc0100632070103081508df081908de081a08da081b08d9081c08d8081d08d7082808d6082908d3c01059940b03080a08e8080b08e7080c08e6080d08e5081108e4081208e2081308e1081408e0c0102403080008f1080108f0080208ef080308ee080408ed080508ec080608eb080708eac0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0x8f6, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20500070205000742000007820000084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c64200050630c642000606c0c64200070620c642000806b0c64200090610c642000a06a0c642000b0600c642000c0690c642000d05f0c642000e05e0c642000f04f0c642000005d0c642000104e0c642000205c0c642000304d0c642000405b0c642000504c0c642000605a0c642000704b0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c0000000080681101006411260034001c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b070100000720240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c90863086c0862086b0861086a08600869085f085e084fc01003085d084e085c084d085b084c085a084b0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c0100308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c010070320030c07030703072004020000004200080002089000000000002f00040038000000', '2f00040038000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0x121, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20720070207200742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a120100000620102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063007010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0x121, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20720070207200742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a120100000620102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063007010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0xb4b, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20660070206600742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0xb4b, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20660070206600742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0xb4b, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050201f015c200000602000004c2003006c20720070207200742004007820040084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d03005e03004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0xb4b, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050201f015c200000602000004c2003006c20720070207200742004007820040084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d03005e03004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0xb4d, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20600070206000742002007820020084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d01005e01004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0xb4d, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20600070206000742002007820020084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d01005e01004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0x130, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20400070204000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003', '330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c', '32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0x518, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20640070206400742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003', '330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c', '32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0xbe1, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20550070205500742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003', '330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c', '32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0xbe2, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20500070205000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003', '330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c', '32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000']),
SensorCaptureProg(major=0x6, minor=0xb, build=0x0, u1=0x0, dev_type=0x194, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c0000000080202004002820ff0b2c20f60b6c202f007020000074201000782000005c2000006020000064200000502000005420151d84202000942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc2000004900d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0201400f8200500fc200000b8203b00002804001428000008280000082810001428180008281100142819001c281a00', '32001400000000806811010064111f007c1700007017010033001c00000000809c1701000000ac1700900100b01754000000b417007200003400500010061110061110061110061110061001068010080101000007c80764060000002003070107010c07840a640863c91e2cc9159107010a9dc9110701030a3208330701c90f20c91e070304020000000000', '2f0004005400000029000400000000003500040010000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x179, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032007800000000802020040024200000382000002820df0b2c20df0b30200000342000003c20000040200000442000004820000050200a005c20000060200000642000004c200300002100006c2030007020300040210000742006007820060084202000b4200000b8203a00bc201400c0200200c4200100c820020033001c000000008054202f27030058202f270300cc200000ef03d0200000ef033200440000000080dc20e803e020e803e420d002e820d002f0200500f8200500fc200000b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '320014000000008068110100641126007c1700007017010033001c00000000809c1701000000ac1700900100b01738000000b417009000003400040310060b10060b10060b10060b10060c01064e10080101000007c80764060000002003070107010c2c078408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b800aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a720871800ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a800ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a060805800aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800a010800802007032003070307030402000000', '2f0004003800000029000400000000003500040010000000']),
SensorCaptureProg(major=0x6, minor=0xa, build=0x0, u1=0x0, dev_type=0x117, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032006400000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c20680070206800742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a80063207010ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a06080580240aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800c0a01080080070103040200000000002f00040038000000', '290004009400000035000400a4000000']),
SensorCaptureProg(major=0x6, minor=0xb, build=0x0, u1=0x0, dev_type=0x117, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032006400000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c20680070206800742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a80063207010ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a06080580240aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800c0a01080080070103040200000000002f00040038000000', '290004009400000035000400a4000000']),
SensorCaptureProg(major=0x6, minor=0xb, build=0x0, u1=0x0, dev_type=0x126, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032007000000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c2068007020680074200100782001006420000084202000b4200000b8203a00bc201400c0200200c4200100c820020074030000a0030f00330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d0800a2c082b800ad008d1800a2b082a80063207010ad108d2800a2a0829800ad208d3800a290828800ad308d6800a28081c800ad608d7800a1c081b800ad708d8800a1b081a800ad808d9800a1a0819800ad908da800a190815800ada08df800a150814800adf08e0800a140813800ae008e1800a130812800ae108e2800a120811800ae208e4800a11080e800ae408e5800a0e080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708e8800a0b080a800ae808ea800a0a0807800aea08eb800a070806800aeb08ec800a06080580240aec08ed800a050804800aed08ee800a040803800aee08ef800a030802800aef08f0800a020801800af008f1800c0a01080080070c03040200000000002f00040038000000290004009400000035000400a4000000']),
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xdb, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a0200b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c1126003400080310061d10061d10061d10061d10061c01065810080101000007c8078c06100000204f80007f000003070107010c07032c08fc80095a800afc08fb800b5a095b800afb08fa800b5b095c800afa08f9800b5c095d800af908f8800b5d095e800af808f7800b5e095f800af708f6800b5f0960800af608f5800b600961800af508f4800b610962800af408f3800b620963800af308f2800b630964800af208f1800b640965800af108f0800b650966800af008ef800b660967800aef08ee800b670968800aee08ed800b68096c800aed08ec800b6c096d800aec08eb800b6d096e800aeb08ea800b6e096f800aea08e9800b6f0970800ae908e8800b700971800ae808e7800b710972800ae708e6800b720973800ae608e5800b730974800ae508e4800b740975800ae408e3800b750976800ae308e2800b760977800ae208e1800b770978800ae108e0800b780979800ae008df800b79097a800adf08de800b7a097b800ade08dd800b7b097c800add08dc800b7c097d800adc08db800b7d097e800adb08da800b7e097f800ada08d9800b7f0980800ad908d8800b800981800ad808d7800b810982800ad708d6800b820983800ad608d5800b830984800ad508d4800b840985800ad408d3800b850986800ad308d2800b860987800ad208d1800b870988800ad108d0800b880989800ad008cf800b89098a800acf08ce800b8a098b800ace08cd800b8b098c800acd08cc800b8c098d800acc08cb800b8d098e800acb08ca800b8e098f800aca08c9800b8f0990800ac908c8800b900991800ac808c7800b910992800ac708c6800b920993800ac608c5800b930994800ac508c4800b940995800ac408c3800b950996800ac308c2800b960997800ac208c1800b970998800ac108c0800b980999800ac008bf800b99099a800abf08be800b9a099b800abe08bd800b9b099c800abd08bc800b9c099d800abc08bb800b9d099e800abb08ba800b9e099f800aba08b9800b9f09a0800ab908b8800ba00801800ab808b7800a010802800ab708b6800a020803800ab608b5800a030804802003070404020000000000002f0004009000000029000400000000003500040010000000']),
SensorCaptureProg.table = [
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0x0,
a0=0x0,
a1=0x0,
blobs=[
'23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000',
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
'29000400000000003500040000000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x6,
build=0x0,
u1=0x0,
dev_type=0x0,
a0=0x0,
a1=0x0,
blobs=[
'23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000',
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
'29000400000000003500040000000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x7,
build=0x0,
u1=0x0,
dev_type=0x0,
a0=0x0,
a1=0x0,
blobs=[
'23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000',
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
'29000400000000003500040000000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x8,
build=0x0,
u1=0x0,
dev_type=0x0,
a0=0x0,
a1=0x0,
blobs=[
'23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000',
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
'29000400000000003500040000000000'
]),
SensorCaptureProg(
major=0x6,
minor=0xa,
build=0x0,
u1=0x0,
dev_type=0x0,
a0=0x0,
a1=0x0,
blobs=[
'230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000',
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
'29000400000000003500040000000000'
]),
SensorCaptureProg(
major=0x6,
minor=0xb,
build=0x0,
u1=0x0,
dev_type=0x0,
a0=0x0,
a1=0x0,
blobs=[
'230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000',
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
'29000400000000003500040000000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x14,
build=0x0,
u1=0x0,
dev_type=0x0,
a0=0x0,
a1=0x0,
blobs=[
'230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000',
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
'29000400000000003500040000000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x6,
build=0x0,
u1=0x0,
dev_type=0x885,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082150000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x7,
build=0x0,
u1=0x0,
dev_type=0x885,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082150000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0x1055,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482103004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0x1825,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601062810250101000007c8078c06ff4f80006d0300200307030990098db00b90880991858e08c1810b9190910ac1b828928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f812089920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0xb5,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c111e0034007801000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001023171023171023161023161023160106635205001025010100000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0x1ff5,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601062810250101000007c8078c06ff4f80006d0300200307030990098db00b90880991858e08c1810b9190910ac1b828928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f812089920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x7,
build=0x0,
u1=0x0,
dev_type=0x1825,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010240101000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0xe4,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221410221410221410221410221401066510250101000007c8078c06ff4f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c0703030720040200002f0004006400000029000400700000003500040080000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0xed,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482104004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010240101000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x7,
build=0x0,
u1=0x0,
dev_type=0x143b,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000d600d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c1117003400340200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101c11101c11101c11101c11101c10010657101e0101000007c8078c06ff00004f80006d03002c03070308c608c709930703800ac60994800ac70995800b930996800b940997800b950998800b9608c8800b9708ca800b9808cb800ac808cc800aca08ce800acb08cf800acc099a800ace099b800acf099c800b9a099d800b9b099e800b9c099f800b9d08d0800b9e08d2800b9f08d3800ad008d4800ad208d6800ad308d7800ad40802800ad60803800ad7095a800a02095b800a03095c800b5a095d800b5b08d9800b5c08da800b5d08db800ad908dd800ada08de800adb08df800add095e800ade095f800adf0960800b5e0961800b5f0962800b600963800b6108e1800b6208e2800b6308e3800ae108e5800ae208e6800ae308e7800ae50964800ae60965800ae70966800b640967800b650968800b66096e800b6708e9800b6808ea800b6e08eb800ae908ed800aea08ef800aeb08ee800aed096f800aef0970800aee0971800b6f0972800b700974800b710975800b7208f0800b7408f1800b7508f2800af008f4800af108f5800af208f6800af40976800af50977800af60979800b760978800b77097a800b79097b800b7808f8800b7a08fa800b7b08fc800af808fd800afa08fe800afc0900800c2007030307200402002f0004005400000029000400580000003500040068000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x7,
build=0x0,
u1=0x0,
dev_type=0xb3,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082140000c210000482106004c210000582000005c2000006020000068200a006c20012970200121742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200100c4200100c82002003300100000000080cc2000002c01d0200000a1013200440000000080dc205302e0206401e420a901e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c11180034003c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101c11101c11101c11101c11101c10010657101e0101000007c8078c06ff00004f80006d03002c0308c608c70703800ac60993800ac70994800b930995800b940996800b950997800b960998800b9708c8800b9808ca800ac808cb800aca08cc800acb08ce800acc08cf800ace099a800acf099b800b9a099c800b9b099d800b9c099e800b9d099f800b9e08d0800b9f08d2800ad008d3800ad208d4800ad308d6800ad408d7800ad60802800ad70803800a02095a800a03095b800b5a095c800b5b095d800b5c08d9800b5d08da800ad908db800ada08dd800adb08de800add08df800ade095e800adf095f800b5e0960800b5f0961800b600962800b610963800b6208e1800b6308e2800ae108e3800ae208e5800ae308e6800ae508e7800ae60964800ae70965800b640966800b650967800b660968800b67096e800b6808e9800b6e08ea800ae908eb800aea08ed800aeb08ef800aed08ee800aef096f800aee0970800b6f0971800b700972800b710974800b720975800b7408f0800b7508f1800af008f2800af108f4800af208f5800af408f6800af50976800af60977800b760979800b770978800b79097a800b78097b800b7a08f8800b7b08fa800af808fc800afa08fd800afc08fe800afd090080808080240c0703030720040200000000002f0004005400000029000400580000003500040068000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0xe1,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032006c000000008020200400242000005020773628200100302001003c208000082138000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084203000942001809c200902a0200b19bc201400c0200200c4200100c82002003300100000000080cc2000006401d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c11160034001402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b10101b10101b10101b0f101b0f010656101e0101000007c8078c06ff4f80006d03002c03070308c108bf098f0703800ac10990800abf098d800b8f0991800b900992800b8d08c5800b9108c3800b9208c6800ac508c4800ac308cb800ac608c7800ac40993800acb0994800ac70995800b930997800b940996800b950998800b9708ce800b9608cc800b9808cf800ace08d0800acc08d2800acf08dd800ad0099a800ad2099b800add099c800b9a0803800b9b095a800b9c095b800a0308de800b5a08df800b5b08e1800ade08eb800adf08ed800ae108f1800aeb095c800aed0962800af10963800b5c096f800b620970800b630971800b6f08f2800b7008f5800b7108f6800af208fa800af508f8800af608fc800afa0974800af80976800afc097b800b74097a800b76097f800b7b097e800b7a08fd800b7f08fe800b7e090b800afd090c800afe090d800b0b090f800b0c0980800b0d0982800b0f0983800b80097d800b820978800b83097c800b7d0914800b780908800b7c0909800b140907800b080905800b090904800b070979800b050977800b040975800b790972800b77096c800b750936800b7209348080800c20070303072004020000002f0004004e00000029000400540000003500040064000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0x8b1,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032006c000000008020200400242000005020773628200100302001003c208000082138000c210000482107004c210000582000005c2000006020000068200a006c20014970200141742001887820018084203000942001809c200902a0200b19bc201400c0200200c4200100c82002003300100000000080cc2000002c00d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c11160034001402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b10101b10101b10101b0f101b0f010656101e0101000007c8078c06ff4f80006d03002c03070308c108bf098f0703800ac10990800abf098d800b8f0991800b900992800b8d08c5800b9108c3800b9208c6800ac508c4800ac308cb800ac608c7800ac40993800acb0994800ac70995800b930997800b940996800b950998800b9708ce800b9608cc800b9808cf800ace08d0800acc08d2800acf08dd800ad0099a800ad2099b800add099c800b9a0803800b9b095a800b9c095b800a0308de800b5a08df800b5b08e1800ade08eb800adf08ed800ae108f1800aeb095c800aed0962800af10963800b5c096f800b620970800b630971800b6f08f2800b7008f5800b7108f6800af208fa800af508f8800af608fc800afa0974800af80976800afc097b800b74097a800b76097f800b7b097e800b7a08fd800b7f08fe800b7e090b800afd090c800afe090d800b0b090f800b0c0980800b0d0982800b0f0983800b80097d800b820978800b83097c800b7d0914800b780908800b7c0909800b140907800b080905800b090904800b070979800b050977800b040975800b790972800b77096c800b750936800b7209348080800c20070303072004020000002f0004004e00000029000400540000003500040064000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0xea,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000d600d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c11170034003002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b11101b11101b11101b11101b1001064d101d0101000007c8078c06ff00004f80006d03002c03070308c608c709930703800ac60994800ac70995800b930996800b940997800b950998800b9608c8800b9708ca800b9808cb800ac808cc800aca08ce800acb08cf800acc099a800ace099b800acf099c800b9a099d800b9b099e800b9c099f800b9d08d0800b9e08d2800b9f08d3800ad008d4800ad208d6800ad308d7800ad40802800ad60803800ad7095a800a02095b800a03095c800b5a095d800b5b08d9800b5c08da800b5d08db800ad908dd800ada08de800adb08df800add095e800ade095f800adf0960800b5e0961800b5f0962800b600963800b6108e1800b6208e2800b6308e3800ae108e5800ae208e6800ae308e7800ae50964800ae60965800ae70966800b640967800b650968800b66096e800b6708e9800b6808ea800b6e08eb800ae908ed800aea08ef800aeb08ee800aed096f800aef0970800aee0971800b6f0972800b700974800b710975800b7208f0800b7408f1800b7508f2800af008f4800af108f5800af208f6800af40976800af50977800af60979800b760978800b77097a800b79097b800b7808f8800b7a08fa800b7b08fc800af808fd800afa08fe800afc0900800c2007030307200402002f0004005400000029000400540000003500040064000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0x199,
a0=0x18,
a1=0x19,
blobs=[
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482107004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c111e00340078010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010250101000007c8078c06ff0000000000004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x14,
build=0x0,
u1=0x0,
dev_type=0x8f3,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032006000000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20700070207000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002a0030000330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c64200050630c642000606c0c64200070620c642000806b0c64200090610c642000a06a0c642000b0600c642000c0690c642000d05f0c642000e05e0c642000f04f0c642000005d0c642000104e0c642000205c0c642000304d0c642000405b0c642000504c0c642000605a0c642000704b0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d10c642000d02b0c642000e0d20c642000f02a0c64200000d30c64200010290c64200020d60c64200030280c64200040d70c642000501d0c64200060d80c642000701c0c64200080d90c642000901b0c642000a0da0c642000b01a0c642000c0de0c642000d0190c642000e0df0c642000f0150c64200000e00c64200010140c64200020e10c64200030130c64200040e20c64200050120c64200060e40c64200070110c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b070100002403089808a9089908a8089a08a7089b08a6089c08a4089d08a3089e08a2089f08a1c0102c03088808b9088908b8088a08b7088b08b3089208b2089308b1089408b0089508afc01003087108c6087208c5087d08c2087e08c1087f08c0088008bf088108bb088708bac0100628070103084f085e085f08690860086a0861086b0862086c086308c9086f08c8087008c7c010030847082e0848082f08490830084a0831084b085a084c085b084d085c084e085dc01003082a08d2082b08d1082c08ce083808cd083908cc083a08cb083b08ca0846082dc0100632070103081508df081908de081a08da081b08d9081c08d8081d08d7082808d6082908d3c01059940b03080a08e8080b08e7080c08e6080d08e5081108e4081208e2081308e1081408e0c0102403080008f1080108f0080208ef080308ee080408ed080508ec080608eb080708eac0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x14,
build=0x0,
u1=0x0,
dev_type=0x8f6,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20500070205000742000007820000084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c64200050630c642000606c0c64200070620c642000806b0c64200090610c642000a06a0c642000b0600c642000c0690c642000d05f0c642000e05e0c642000f04f0c642000005d0c642000104e0c642000205c0c642000304d0c642000405b0c642000504c0c642000605a0c642000704b0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
'32000c0000000080681101006411260034001c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b070100000720240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c90863086c0862086b0861086a08600869085f085e084fc01003085d084e085c084d085b084c085a084b0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c0100308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c010070320030c07030703072004020000004200080002089000000000002f00040038000000',
'2f00040038000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x14,
build=0x0,
u1=0x0,
dev_type=0x121,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20720070207200742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a120100000620102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063007010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x15,
build=0x0,
u1=0x0,
dev_type=0x121,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20720070207200742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a120100000620102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063007010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x14,
build=0x0,
u1=0x0,
dev_type=0xb4b,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20660070206600742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x15,
build=0x0,
u1=0x0,
dev_type=0xb4b,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20660070206600742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x14,
build=0x0,
u1=0x0,
dev_type=0xb4b,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050201f015c200000602000004c2003006c20720070207200742004007820040084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d03005e03004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x15,
build=0x0,
u1=0x0,
dev_type=0xb4b,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050201f015c200000602000004c2003006c20720070207200742004007820040084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d03005e03004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x14,
build=0x0,
u1=0x0,
dev_type=0xb4d,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20600070206000742002007820020084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d01005e01004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x15,
build=0x0,
u1=0x0,
dev_type=0xb4d,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20600070206000742002007820020084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d01005e01004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x15,
build=0x0,
u1=0x0,
dev_type=0x130,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20400070204000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003',
'330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c',
'32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x15,
build=0x0,
u1=0x0,
dev_type=0x518,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20640070206400742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003',
'330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c',
'32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x15,
build=0x0,
u1=0x0,
dev_type=0xbe1,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20550070205500742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003',
'330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c',
'32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x15,
build=0x0,
u1=0x0,
dev_type=0xbe2,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20500070205000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003',
'330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c',
'32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000'
]),
SensorCaptureProg(
major=0x6,
minor=0xb,
build=0x0,
u1=0x0,
dev_type=0x194,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032005c0000000080202004002820ff0b2c20f60b6c202f007020000074201000782000005c2000006020000064200000502000005420151d84202000942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc2000004900d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0201400f8200500fc200000b8203b00002804001428000008280000082810001428180008281100142819001c281a00',
'32001400000000806811010064111f007c1700007017010033001c00000000809c1701000000ac1700900100b01754000000b417007200003400500010061110061110061110061110061001068010080101000007c80764060000002003070107010c07840a640863c91e2cc9159107010a9dc9110701030a3208330701c90f20c91e070304020000000000',
'2f0004005400000029000400000000003500040010000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0x179,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032007800000000802020040024200000382000002820df0b2c20df0b30200000342000003c20000040200000442000004820000050200a005c20000060200000642000004c200300002100006c2030007020300040210000742006007820060084202000b4200000b8203a00bc201400c0200200c4200100c820020033001c000000008054202f27030058202f270300cc200000ef03d0200000ef033200440000000080dc20e803e020e803e420d002e820d002f0200500f8200500fc200000b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'320014000000008068110100641126007c1700007017010033001c00000000809c1701000000ac1700900100b01738000000b417009000003400040310060b10060b10060b10060b10060c01064e10080101000007c80764060000002003070107010c2c078408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b800aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a720871800ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a800ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a060805800aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800a010800802007032003070307030402000000',
'2f0004003800000029000400000000003500040010000000'
]),
SensorCaptureProg(
major=0x6,
minor=0xa,
build=0x0,
u1=0x0,
dev_type=0x117,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032006400000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c20680070206800742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a80063207010ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a06080580240aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800c0a01080080070103040200000000002f00040038000000',
'290004009400000035000400a4000000'
]),
SensorCaptureProg(
major=0x6,
minor=0xb,
build=0x0,
u1=0x0,
dev_type=0x117,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032006400000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c20680070206800742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a80063207010ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a06080580240aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800c0a01080080070103040200000000002f00040038000000',
'290004009400000035000400a4000000'
]),
SensorCaptureProg(
major=0x6,
minor=0xb,
build=0x0,
u1=0x0,
dev_type=0x126,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032007000000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c2068007020680074200100782001006420000084202000b4200000b8203a00bc201400c0200200c4200100c820020074030000a0030f00330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
'32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d0800a2c082b800ad008d1800a2b082a80063207010ad108d2800a2a0829800ad208d3800a290828800ad308d6800a28081c800ad608d7800a1c081b800ad708d8800a1b081a800ad808d9800a1a0819800ad908da800a190815800ada08df800a150814800adf08e0800a140813800ae008e1800a130812800ae108e2800a120811800ae208e4800a11080e800ae408e5800a0e080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708e8800a0b080a800ae808ea800a0a0807800aea08eb800a070806800aeb08ec800a06080580240aec08ed800a050804800aed08ee800a040803800aee08ef800a030802800aef08f0800a020801800af008f1800c0a01080080070c03040200000000002f00040038000000290004009400000035000400a4000000'
]),
SensorCaptureProg(
major=0x6,
minor=0x0,
build=0x0,
u1=0x0,
dev_type=0xdb,
a0=0x18,
a1=0x19,
blobs=[
'2300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a0200b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00',
'32000c0000000080501101004c1126003400080310061d10061d10061d10061d10061c01065810080101000007c8078c06100000204f80007f000003070107010c07032c08fc80095a800afc08fb800b5a095b800afb08fa800b5b095c800afa08f9800b5c095d800af908f8800b5d095e800af808f7800b5e095f800af708f6800b5f0960800af608f5800b600961800af508f4800b610962800af408f3800b620963800af308f2800b630964800af208f1800b640965800af108f0800b650966800af008ef800b660967800aef08ee800b670968800aee08ed800b68096c800aed08ec800b6c096d800aec08eb800b6d096e800aeb08ea800b6e096f800aea08e9800b6f0970800ae908e8800b700971800ae808e7800b710972800ae708e6800b720973800ae608e5800b730974800ae508e4800b740975800ae408e3800b750976800ae308e2800b760977800ae208e1800b770978800ae108e0800b780979800ae008df800b79097a800adf08de800b7a097b800ade08dd800b7b097c800add08dc800b7c097d800adc08db800b7d097e800adb08da800b7e097f800ada08d9800b7f0980800ad908d8800b800981800ad808d7800b810982800ad708d6800b820983800ad608d5800b830984800ad508d4800b840985800ad408d3800b850986800ad308d2800b860987800ad208d1800b870988800ad108d0800b880989800ad008cf800b89098a800acf08ce800b8a098b800ace08cd800b8b098c800acd08cc800b8c098d800acc08cb800b8d098e800acb08ca800b8e098f800aca08c9800b8f0990800ac908c8800b900991800ac808c7800b910992800ac708c6800b920993800ac608c5800b930994800ac508c4800b940995800ac408c3800b950996800ac308c2800b960997800ac208c1800b970998800ac108c0800b980999800ac008bf800b99099a800abf08be800b9a099b800abe08bd800b9b099c800abd08bc800b9c099d800abc08bb800b9d099e800abb08ba800b9e099f800aba08b9800b9f09a0800ab908b8800ba00801800ab808b7800a010802800ab708b6800a020803800ab608b5800a030804802003070404020000000000002f0004009000000029000400000000003500040010000000'
]),
]

View file

@ -1,14 +1,13 @@
class DeviceInfo():
def __init__(self, major, type, version, version_mask, name):
self.major, self.type, self.version, self.version_mask, self.name = major, type, version, version_mask, name
def __repr__(self):
return "DeviceInfo(0x%04x, 0x%04x, 0x%02x, 0x%02x, '%s')" % (
self.major, self.type, self.version, self.version_mask, self.name
)
self.major, self.type, self.version, self.version_mask, self.name)
dev_info_table=[
dev_info_table = [
DeviceInfo(0x0000, 0x0080, 0x00, 0x00, 'VSI 15A '),
DeviceInfo(0x0000, 0x0080, 0x00, 0x00, 'VSI 15A '),
DeviceInfo(0x0000, 0x0080, 0x00, 0x00, 'VSI 15A '),
@ -428,6 +427,7 @@ dev_info_table=[
DeviceInfo(0x0190, 0x2449, 0xa3, 0xff, '86C TM-P3569-001 '),
]
def dev_info_lookup(major, ver):
fuzzy_match = None
@ -444,16 +444,19 @@ def dev_info_lookup(major, ver):
return fuzzy_match
class FlashIcInfo():
def __init__(self, name, size, f18, jid0, jid1, f1b, f1c, f1e, secror_size, sector_erase_cmd, f25, f26):
def __init__(self, name, size, f18, jid0, jid1, f1b, f1c, f1e, secror_size, sector_erase_cmd,
f25, f26):
self.name, self.size, self.f18, self.jid0, self.jid1, self.f1b, self.f1c, self.f1e, self.secror_size, self.sector_erase_cmd, self.f25, self.f26 = name, size, f18, jid0, jid1, f1b, f1c, f1e, secror_size, sector_erase_cmd, f25, f26
def __repr__(self):
return "FlashIcInfo('%s', %d, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % (
self.name, self.size, self.f18, self.jid0, self.jid1, self.f1b, self.f1c, self.f1e, self.secror_size, self.sector_erase_cmd, self.f25, self.f26)
self.name, self.size, self.f18, self.jid0, self.jid1, self.f1b, self.f1c, self.f1e,
self.secror_size, self.sector_erase_cmd, self.f25, self.f26)
flash_ic_table=[
flash_ic_table = [
FlashIcInfo('M25P05-A', 65536, 0x5, 0x20, 0x20, 0x10, 0x8000, 0x0, 0x8000, 0xd8, 0x0, 0x4),
FlashIcInfo('M25P10-A', 131072, 0x10, 0x20, 0x20, 0x11, 0x8000, 0x0, 0x8000, 0xd8, 0x0, 0x4),
FlashIcInfo('M25P20', 262144, 0x11, 0x20, 0x20, 0x12, 0x0, 0x1, 0x10000, 0xd8, 0x0, 0x4),
@ -476,10 +479,10 @@ flash_ic_table=[
FlashIcInfo('GD25Q80C', 1048576, 0x13, 0xc8, 0x40, 0x14, 0x0, 0x1, 0x1000, 0x20, 0x0, 0x4),
]
def flash_ic_table_lookup(jedec_id0, jedec_id1, size):
for i in flash_ic_table:
if i.jid0 == jedec_id0 and i.jid1 == jedec_id1 and i.size == size:
return i
return None

View file

@ -1,4 +1,3 @@
import atexit
import logging
@ -10,6 +9,7 @@ from validitysensor.init_flash import init_flash
from validitysensor.upload_fwext import upload_fwext
from validitysensor.init_db import init_db
def close():
logging.debug('In atexit handler')
if usb.dev is not None:
@ -24,6 +24,7 @@ def close():
finally:
usb.close()
def open_common():
init_flash()
usb.send_init()
@ -41,10 +42,12 @@ def open_common():
atexit.register(close)
logging.debug('atexit registered')
def open():
usb.open()
open_common()
def open_devpath(busnum, address):
usb.open_devpath(busnum, address)
open_common()

View file

@ -1,13 +1,14 @@
from struct import pack, unpack
import logging
from .db import db
def machine_id_rec_value(b):
b = b.encode('utf-16le')
b = b + b'\0' * (0x94 - len(b))
return pack('<HH', 0x102, len(b)) + b # 0x102 = Machine ID/GUID?
return pack('<HH', 0x102, len(b)) + b # 0x102 = Machine ID/GUID?
# This function is unused. It simply describes the Windows driver behavior.
# TODO: make this GUID unique!
@ -24,10 +25,11 @@ def init_machine_guid(machine_guid='e7260876-58db-4d27-8c40-8d13110d6a71'):
if rc != machine_id_rec_value(machine_guid):
u0, l = unpack('<HH', rc[:4])
b=rc[4:4+l]
b=b.decode('utf-16le')
b = rc[4:4 + l]
b = b.decode('utf-16le')
raise Exception('Machine GUID does not match the DB flash ownership record (%s).' % b)
def init_db():
stg = db.get_user_storage(name='StgWindsor')
if stg == None:
@ -35,4 +37,3 @@ def init_db():
db.new_user_storate()
#init_machine_guid()

View file

@ -1,4 +1,3 @@
import os
from struct import pack, unpack
from binascii import unhexlify
@ -18,24 +17,25 @@ from .sensor import reboot, RomInfo
from .util import assert_status, unhex
from .blobs import reset_blob
flash_layout_hardcoded=[
flash_layout_hardcoded = [
# id type access offset size
# lvl
PartitionInfo(1, 4, 7, 0x00001000, 0x00001000), # cert store
PartitionInfo(2, 1, 2, 0x00002000, 0x0003e000), # xpfwext
PartitionInfo(5, 5, 3, 0x00040000, 0x00008000), # ???
PartitionInfo(6, 6, 3, 0x00048000, 0x00008000), # calibration data
PartitionInfo(4, 3, 5, 0x00050000, 0x00080000), # template database
PartitionInfo(1, 4, 7, 0x00001000, 0x00001000), # cert store
PartitionInfo(2, 1, 2, 0x00002000, 0x0003e000), # xpfwext
PartitionInfo(5, 5, 3, 0x00040000, 0x00008000), # ???
PartitionInfo(6, 6, 3, 0x00048000, 0x00008000), # calibration data
PartitionInfo(4, 3, 5, 0x00050000, 0x00080000), # template database
]
partition_signature=unhex('''
partition_signature = unhex('''
1db02a886b007e2b47263bb8fe30bd64a1f58bea7b25f1e1ba9ae09add7ecff36333f8198339cdd713f043633710a17bc7b3f418f1d8ff435a1bf47f065dffca
727109152217fce73bf2bf8e01a1641f6a24b0c492a6a3f10114057275846842b1c8b66bd6700738524d4471bca3315ba23bb832743220ad195b60558aa79a3e
deb2604834e2bb62e890b0ce405b3b8ef2fec2aab3e22bff23f89a58ff0dc015fece5d3ed3f5496ace879a92980aec9d85eb7e9df245eae03a41acfd4e7d1cb1
dbd0df42d534904de00b6389f68867646e9d7c3d0b1dffd74070b2d0f2049b9f1dc7b0c9651c59be3ea891674725e1f2f7a484a941615b80211105978369cf71
''')
crypto_backend=default_backend()
crypto_backend = default_backend()
def get_partition_signature():
if usb.usb_dev().idVendor == 0x138a:
@ -48,14 +48,15 @@ def get_partition_signature():
def with_hdr(id, buf):
return pack('<HH', id, len(buf)) + buf
def encrypt_key(client_private, client_public):
x = unhexlify('%064x' % client_public.x)[::-1]
y = unhexlify('%064x' % client_public.y)[::-1]
d = unhexlify('%064x' % client_private)[::-1]
m = x+y+d
m = x + y + d
l = 16 - (len(m) % 16)
m = m + bytes([l])*l
m = m + bytes([l]) * l
iv = os.urandom(0x10)
cipher = Cipher(algorithms.AES(tls.psk_encryption_key), modes.CBC(iv), backend=crypto_backend)
@ -65,44 +66,47 @@ def encrypt_key(client_private, client_public):
sig = hmac.new(tls.psk_validation_key, c, sha256).digest()
return b'\x02' + c + sig
def make_cert(client_public):
msg=(pack('<LL', 0x17, 0x20) +
unhexlify('%064x' % client_public.x)[::-1] +
(b'\0'*0x24) +
unhexlify('%064x' % client_public.y)[::-1] +
(b'\0'*0x4c))
msg = (pack('<LL', 0x17, 0x20) + unhexlify('%064x' % client_public.x)[::-1] + (b'\0' * 0x24) +
unhexlify('%064x' % client_public.y)[::-1] + (b'\0' * 0x4c))
pk = ec.derive_private_key(hs_key(), ec.SECP256R1(), backend=crypto_backend)
s=pk.sign(msg, ec.ECDSA(hashes.SHA256()))
s=pack('<L', len(s)) + s
s = pk.sign(msg, ec.ECDSA(hashes.SHA256()))
s = pack('<L', len(s)) + s
msg = msg + s
msg += b'\0'*(444 - len(msg)) # FIXME not sure this math is right
msg += b'\0' * (444 - len(msg)) # FIXME not sure this math is right
return msg
def serialize_flash_params(ic):
return pack('<LLxxBx', ic.size, ic.secror_size, ic.sector_erase_cmd)
def serialize_partition(p):
b = pack('<BBHLL', p.id, p.type, p.access_lvl, p.offset, p.size)
b = b + b'\0'*4 + sha256(b).digest()
b = b + b'\0' * 4 + sha256(b).digest()
return b
def partition_flash(info, layout, client_public):
logging.info('Detected Flash IC: %s, %d bytes' % (info.ic.name, info.ic.size))
cmd = unhex('4f 0000 0000')
cmd += with_hdr(0, serialize_flash_params(info.ic))
cmd += with_hdr(1, b''.join([serialize_partition(p) for p in layout]) + get_partition_signature())
cmd += with_hdr(1,
b''.join([serialize_partition(p) for p in layout]) + get_partition_signature())
cmd += with_hdr(5, make_cert(client_public))
cmd += with_hdr(3, crt_hardcoded)
rsp = tls.cmd(cmd)
assert_status(rsp)
rsp = rsp[2:]
crt_len, rsp=rsp[:4], rsp[4:]
crt_len, rsp = rsp[:4], rsp[4:]
crt_len, = unpack('<L', crt_len)
tls.handle_cert(rsp[:crt_len])
rsp = rsp[crt_len:]
# ^ TODO - figure out what the rest of rsp means
def init_flash():
info = get_flash_info()
@ -125,13 +129,13 @@ def init_flash():
# ^ TODO: use the firmware version which to lookup pubkey for server cert validation
try:
rsp=usb.cmd(unhex('50'))
rsp = usb.cmd(unhex('50'))
assert_status(rsp)
finally:
call_cleanups()
rsp=rsp[2:]
l,=unpack('<L', rsp[:4])
rsp = rsp[2:]
l, = unpack('<L', rsp[:4])
if len(rsp) != l:
raise Exception('Length mismatch')

View file

@ -18,22 +18,32 @@ from .blobs import reset_blob
from . import timeslot as prg
# TODO: this should be specific to an individual device (system may have more than one sensor)
calib_data_path='/usr/share/python-validity/calib-data.bin'
calib_data_path = '/usr/share/python-validity/calib-data.bin'
line_update_type1_devices = [
0xB5, 0x885, 0xB3, 0x143B, 0x1055, 0xE1, 0x8B1, 0xEA, 0xE4, 0xED, 0x1825, 0x1FF5, 0x199
]
line_update_type1_devices = [ 0xB5, 0x885, 0xB3, 0x143B, 0x1055, 0xE1, 0x8B1, 0xEA, 0xE4, 0xED, 0x1825, 0x1FF5, 0x199 ]
# TODO use more sophisticated glow patters in different cases
def glow_start_scan():
cmd=unhexlify('3920bf0200ffff0000019900200000000099990000000000000000000000000020000000000000000000000000ffff000000990020000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
cmd = unhexlify(
'3920bf0200ffff0000019900200000000099990000000000000000000000000020000000000000000000000000ffff000000990020000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
)
assert_status(tls.app(cmd))
def glow_end_scan():
cmd=unhexlify('39f4010000f401000001ff002000000000ffff0000000000000000000000000020000000000000000000000000f401000000ff0020000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
cmd = unhexlify(
'39f4010000f401000001ff002000000000ffff0000000000000000000000000020000000000000000000000000f401000000ff0020000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
)
assert_status(tls.app(cmd))
def get_prg_status():
return tls.app(unhexlify('5100000000'))
def wait_till_finished():
while True:
status = get_prg_status()
@ -43,38 +53,44 @@ def wait_till_finished():
sleep(0.2)
def get_prg_status2():
return tls.app(unhexlify('5100200000'))
def read_hw_reg32(addr):
rsp=tls.cmd(pack('<BLB', 7, addr, 4))
rsp = tls.cmd(pack('<BLB', 7, addr, 4))
assert_status(rsp)
rsp, = unpack('<L', rsp[2:])
return rsp
def write_hw_reg32(addr, val):
rsp=tls.cmd(pack('<BLLB', 8, addr, val, 4))
rsp = tls.cmd(pack('<BLLB', 8, addr, val, 4))
assert_status(rsp)
class RebootException(Exception):
pass
def reboot():
assert_status(tls.cmd(unhex('050200')))
raise RebootException()
def factory_reset():
assert_status(usb.cmd(reset_blob))
assert_status(usb.cmd(b'\x10' + b'\0'*0x61))
assert_status(usb.cmd(b'\x10' + b'\0' * 0x61))
reboot()
class RomInfo():
@classmethod
def get(cls):
rsp=tls.cmd(b'\x01')
rsp = tls.cmd(b'\x01')
assert_status(rsp)
rsp=rsp[2:]
rsp = rsp[2:]
return cls(*unpack('<LLBBxBxxxB', rsp[0:0x10]))
def __init__(self, timestamp, build, major, minor, product, u1):
@ -86,9 +102,9 @@ class RomInfo():
def identify_sensor():
rsp=tls.cmd(b'\x75')
rsp = tls.cmd(b'\x75')
assert_status(rsp)
rsp=rsp[2:]
rsp = rsp[2:]
zeroes, minor, major = unpack('<LHH', rsp)
@ -97,6 +113,7 @@ def identify_sensor():
return dev_info_lookup(major, minor)
# <<< 0000 880d 0000 07000000
# 08000000 9400 0e00 0300 0080 07000000 7e7f807f808080808080808080808080808080808080818081808180818080808080818081808080818081808180
# a4000000 0800 0e00 0200 0000 00000000 0d007100
@ -106,14 +123,14 @@ def identify_sensor():
# 6c010000 1400 0e00 0f00 0080 05550007 7701002805720000080100020811e107
# 88010000 0c00 0e00 1200 0080 07000000 7002 7800 7002 7800
def get_factory_bits(tag):
rsp=tls.cmd(pack('<B H HL', 0x6f, tag, 0, 0))
rsp = tls.cmd(pack('<B H HL', 0x6f, tag, 0, 0))
assert_status(rsp)
rsp=rsp[2:]
rsp = rsp[2:]
wtf, entries = unpack('<LL', rsp[:8])
rsp = rsp[8:]
rc={}
rc = {}
for x in range(0, entries):
hdr, rsp = rsp[:12], rsp[12:]
ptr, l, tag, subtag, flags = unpack('<LHHHH', hdr)
@ -132,68 +149,74 @@ def get_factory_bits(tag):
def bitpack(b):
l=len(b)
m=min(b)
x=max(b)
l = len(b)
m = min(b)
x = max(b)
# maximum delta which we must encode
x-=m
x -= m
# count useful bits
u=0
u = 0
while x > 0:
x>>=1
u+=1
x >>= 1
u += 1
# convert to array of binary strings with each element exactly u characters long
b=[bin(i-m+0x100)[-u:] for i in b]
b = [bin(i - m + 0x100)[-u:] for i in b]
# combine chunks into one long text number with u*l binary digits and parse it as integer
b=int(''.join(b[::-1]), 2)
b = int(''.join(b[::-1]), 2)
# convert back to bytes
b=b.to_bytes((u*l+7)//8, 'little')
b = b.to_bytes((u * l + 7) // 8, 'little')
return (u, m, b)
class Line():
mask=None
flags=None
data=None
v0=0
v1=0
v2=0
mask = None
flags = None
data = None
v0 = 0
v1 = 0
v2 = 0
def clip(x):
if x < -128:
x=-128
x = -128
if x > 127:
x=127
x = 127
return x & 0xff
def scale(x):
x -= 0x80
x = int(x*10/0x22) # TODO: scaling factor depends on a device
x = int(x * 10 / 0x22) # TODO: scaling factor depends on a device
return clip(x)
def add(l, r):
# Make signed
l, r = unpack('bb', pack('BB', l, r))
return clip(l+r)
return clip(l + r)
def chunks(b, l):
return [b[i:i+l] for i in range(0, len(b), l)]
return [b[i:i + l] for i in range(0, len(b), l)]
class CaptureMode(Enum):
CALIBRATE=1
IDENTIFY=2
ENROLL=3
CALIBRATE = 1
IDENTIFY = 2
ENROLL = 3
class Sensor():
calib_data=b''
calib_data = b''
def open(self):
self.device_info = identify_sensor()
@ -202,25 +225,29 @@ class Sensor():
self.type_info = SensorTypeInfo.get_by_type(self.device_info.type)
if self.device_info.type == 0x199:
self.key_calibration_line = 0x38 # (lines_per_calibration_data/2), but hardcoded for sensor type 0x199
self.calibration_frames = 3 # TODO: workout where it's really comming from
self.calibration_iterations = 3 # hardcoded for type
self.key_calibration_line = 0x38 # (lines_per_calibration_data/2), but hardcoded for sensor type 0x199
self.calibration_frames = 3 # TODO: workout where it's really comming from
self.calibration_iterations = 3 # hardcoded for type
elif self.device_info.type == 0xdb:
self.key_calibration_line = 0x48 # TODO 48 is just a guess -- find it
self.calibration_frames = 6 # TODO: workout where it's really comming from
self.key_calibration_line = 0x48 # TODO 48 is just a guess -- find it
self.calibration_frames = 6 # TODO: workout where it's really comming from
self.calibration_iterations = 0
else:
raise Exception('Device %s is not supported (sensor type 0x%x)' % (self.device_info.name, self.device_info.type))
raise Exception('Device %s is not supported (sensor type 0x%x)' %
(self.device_info.name, self.device_info.type))
self.rom_info = RomInfo.get()
self.hardcoded_prog = SensorCaptureProg.get(self.rom_info, self.device_info.type, 0x18, 0x19) # TODO: find where 0x18, 0x19 coming from
self.hardcoded_prog = SensorCaptureProg.get(self.rom_info, self.device_info.type, 0x18,
0x19) # TODO: find where 0x18, 0x19 coming from
if self.hardcoded_prog is None:
raise Exception('Can\'t find initial capture program for rom %s and sensor type %x' % (repr(self.rom_info), self.device_info.type))
raise Exception('Can\'t find initial capture program for rom %s and sensor type %x' %
(repr(self.rom_info), self.device_info.type))
# Look for a "2D" chunk. It must have a 32 bit integer which represent the number of lines per frame
lines_2d = [unpack('<L', v)[0] for [k, v] in prg.split_chunks(self.hardcoded_prog) if k == 0x2f][0]
self.lines_per_frame = lines_2d*self.type_info.repeat_multiplier
lines_2d = [
unpack('<L', v)[0] for [k, v] in prg.split_chunks(self.hardcoded_prog) if k == 0x2f
][0]
self.lines_per_frame = lines_2d * self.type_info.repeat_multiplier
self.bytes_per_line = self.type_info.bytes_per_line
factory_bits = get_factory_bits(0x0e00)
@ -238,23 +265,23 @@ class Sensor():
# This is the exact logic from the DLL.
# If it looks broken that was probably intended.
def patch_timeslot_table(self, b, inc_address, mult):
b=bytearray(b)
i=0
while i+3 < len(b):
b = bytearray(b)
i = 0
while i + 3 < len(b):
if b[i] & 0xf8 == 0x10:
if b[i+2] > 1:
b[i+2] *= mult
if b[i + 2] > 1:
b[i + 2] *= mult
if inc_address:
b[i+1] += 1
i+=3
b[i + 1] += 1
i += 3
continue
if b[i] == 0:
i+=1
i += 1
continue
if b[i] == 7:
i+=2
i += 2
continue
break
@ -262,10 +289,10 @@ class Sensor():
return bytes(b)
def patch_timeslot_again(self, b):
b=bytearray(b)
b = bytearray(b)
pc = 0
match=None
match = None
# Look for the last Call in the script
while pc < len(b):
opcode, l, *operands = prg.decode_insn(b[pc:])
@ -276,7 +303,7 @@ class Sensor():
# Call
if opcode == 11:
match = operands[1] # destination address
match = operands[1] # destination address
pc += l
@ -303,13 +330,13 @@ class Sensor():
return bytes(b)
# Hack the value to be taken from the factory calibration table right in the middle of a sensor
b[match+1] = self.factory_calibration_values[self.key_calibration_line]
b[match + 1] = self.factory_calibration_values[self.key_calibration_line]
return bytes(b)
def average(self, raw_calib_data):
frame_size = self.lines_per_frame * self.bytes_per_line
interleave_lines = self.lines_per_frame // self.type_info.lines_per_calibration_data # 2, TODO: algo is quite different when it is 1
interleave_lines = self.lines_per_frame // self.type_info.lines_per_calibration_data # 2, TODO: algo is quite different when it is 1
input_frames = self.calibration_frames
if interleave_lines > 1:
@ -318,59 +345,63 @@ class Sensor():
input_frames -= 1
base_address = frame_size
frame=raw_calib_data[base_address:base_address+frame_size]
frame = raw_calib_data[base_address:base_address + frame_size]
# split into groups of lines
frame=chunks(frame, interleave_lines*self.bytes_per_line)
frame = chunks(frame, interleave_lines * self.bytes_per_line)
# split group of lines into lines
frame=[chunks(f, self.bytes_per_line) for f in frame]
frame = [chunks(f, self.bytes_per_line) for f in frame]
# calculate averages across interleaved lines
frame=[bytes([sum(i)//len(f) for i in zip(*f)]) for f in frame]
frame=b''.join(frame)
frame = [bytes([sum(i) // len(f) for i in zip(*f)]) for f in frame]
frame = b''.join(frame)
else:
if input_frames > 1:
# skip the first frame
input_frames -= 2
base_address = frame_size*2
base_address = frame_size * 2
frames=raw_calib_data[base_address:base_address+frame_size*input_frames]
frames=chunks(frames, frame_size)
frame=[int(sum(i)/input_frames) for i in zip(*frames)]
frame=bytes(frame)
frames = raw_calib_data[base_address:base_address + frame_size * input_frames]
frames = chunks(frames, frame_size)
frame = [int(sum(i) / input_frames) for i in zip(*frames)]
frame = bytes(frame)
return frame
def process_calibration_results(self, cooked_data):
frame=chunks(cooked_data, self.bytes_per_line)
frame = chunks(cooked_data, self.bytes_per_line)
# apply scaling factors
frame=[f[:8] + bytes(map(scale, f[8:])) for f in frame]
frame=b''.join(frame)
frame = [f[:8] + bytes(map(scale, f[8:])) for f in frame]
frame = b''.join(frame)
if len(self.calib_data) > 0:
# Not the first calibration run. Combine results
# split previous calibration info into lines
lll=chunks(self.calib_data, self.bytes_per_line)
lll = chunks(self.calib_data, self.bytes_per_line)
# split next calibration info into lines
rrr=chunks(frame, self.bytes_per_line)
rrr = chunks(frame, self.bytes_per_line)
# Don't touch the first 8 bytes of each line, add everything else as signed characters, clipping the values
combined=[ll[:8] + bytes([add(l, r) for l, r in zip(ll[8:],rr[8:])]) for ll, rr in zip(lll, rrr)]
combined = [
ll[:8] + bytes([add(l, r) for l, r in zip(ll[8:], rr[8:])])
for ll, rr in zip(lll, rrr)
]
self.calib_data = bytes(b''.join(combined))
else:
self.calib_data = frame
def get_key_line(self):
if len(self.calib_data) > 0:
bytes_per_calibration_line=len(self.calib_data) // self.type_info.lines_per_calibration_data
key_line_offset=8+bytes_per_calibration_line*self.key_calibration_line
key_line=self.calib_data[key_line_offset:key_line_offset+self.type_info.line_width]
key_line=bytes([i-1 if i == 5 else i for i in key_line])
bytes_per_calibration_line = len(
self.calib_data) // self.type_info.lines_per_calibration_data
key_line_offset = 8 + bytes_per_calibration_line * self.key_calibration_line
key_line = self.calib_data[key_line_offset:key_line_offset + self.type_info.line_width]
key_line = bytes([i - 1 if i == 5 else i for i in key_line])
else:
key_line=b'\0'*self.type_info.line_width
key_line = b'\0' * self.type_info.line_width
return key_line
@ -381,7 +412,7 @@ class Sensor():
# TODO: figure out when to use address increment
tst = self.patch_timeslot_table(c[1], True, self.type_info.repeat_multiplier)
if mode != CaptureMode.CALIBRATE:
tst=self.patch_timeslot_again(tst)
tst = self.patch_timeslot_again(tst)
c[1] = self.get_key_line() + tst[self.type_info.line_width:]
#---------------- Reply Configuration ---------------
@ -392,22 +423,36 @@ class Sensor():
# It seems to be only used for identification and it looks almost identical to Finger Detect (0x26)
# Seems to be the same all the time for a given sensor and mostly hardcoded
# TODO: analyse construct_wtf_4e @0000000180090BF0
chunks += [[0x4e, unhexlify('fbb20f0000000f00300000008700020067000a00018000000a0200000b1900008813b80b01091000')]]
chunks += [[
0x4e,
unhexlify(
'fbb20f0000000f00300000008700020067000a00018000000a0200000b1900008813b80b01091000'
)
]]
# Image Reconstruction.
# TODO: analyse add_image_reconstruction_cmd_02_buff_list_item @000000018008EA70
chunks += [[0x2e, unhexlify('0200180002000000700070004d010000a0008c003c32321e3c0a0202')]]
chunks += [[
0x2e, unhexlify('0200180002000000700070004d010000a0008c003c32321e3c0a0202')
]]
elif mode == CaptureMode.ENROLL:
chunks += [[0x26, unhexlify('fbb20f0000000f00300000008700020067000a00018000000a0200000b19000050c360ea01091000')]]
chunks += [[
0x26,
unhexlify(
'fbb20f0000000f00300000008700020067000a00018000000a0200000b19000050c360ea01091000'
)
]]
# Image Reconstruction. There is only one byte difference with the "identify" version. (same is true for 0097)
chunks += [[0x2e, unhexlify('0200180023000000700070004d010000a0008c003c32321e3c0a0202')]]
chunks += [[
0x2e, unhexlify('0200180023000000700070004d010000a0008c003c32321e3c0a0202')
]]
#---------------- Interleave ---------------
chunks += [[0x44, pack('<L', 1)]]
lines=[]
cnt=2 # TODO figure out why 2
lines = []
cnt = 2 # TODO figure out why 2
l=Line()
l = Line()
lines += [l]
l.mask = 0xff
# Find 2nd "Enable Rx" instruction
@ -417,28 +462,29 @@ class Sensor():
l.v0 = 0xf
cnt += 1
l=Line()
l = Line()
lines += [l]
l.mask = 0xff
# Find 1st "Write Register" instruction to the 0x8000203C port
pc, _ = prg.find_nth_regwrite(tst, 0x8000203C, 1)
l.flags = (pc + 1) | (cnt << 0x14) | 0x7000000
l.v0, l.v1, l.data = bitpack(self.factory_calibration_values)
l.v0 = (l.v0-1) | 8
l.v0 = (l.v0 - 1) | 8
cnt += 1
if len(self.calib_data) > 0:
bytes_per_calibration_line=len(self.calib_data) // self.type_info.lines_per_calibration_data
bytes_per_calibration_line = len(
self.calib_data) // self.type_info.lines_per_calibration_data
for i in range(0, 112, 4):
l=Line()
l = Line()
lines += [l]
l.mask=0xffffffff
l.flags=i | (0x85 << 24)
l.data=b''
l.mask = 0xffffffff
l.flags = i | (0x85 << 24)
l.data = b''
for j in range(0, 112):
p=8+j*bytes_per_calibration_line+i
l.data += self.calib_data[p:p+4]
p = 8 + j * bytes_per_calibration_line + i
l.data += self.calib_data[p:p + 4]
# Align to dwords, as the sensor demands it
for l in lines:
@ -446,7 +492,6 @@ class Sensor():
if pad > 0:
l.data += b'\0' * (4 - pad)
#---------------- Line Update ---------------
line_update = pack('<L', len(lines))
line_update += b''.join([pack('<LL', l.mask, l.flags) for l in lines])
@ -455,7 +500,10 @@ class Sensor():
chunks += [[0x30, line_update]]
#---------------- Line Update Transform ---------------
update_transform = b''.join([pack('<BBH', l.v0, l.v1, l.v2) + l.data for l in lines if ((l.flags & 0x00f00000) >> 0x14) > 1])
update_transform = b''.join([
pack('<BBH', l.v0, l.v1, l.v2) + l.data for l in lines
if ((l.flags & 0x00f00000) >> 0x14) > 1
])
chunks += [[0x43, update_transform]]
return chunks
@ -472,7 +520,7 @@ class Sensor():
# TODO: figure out when to use address increment
tst = self.patch_timeslot_table(c[1], True, self.type_info.repeat_multiplier)
if mode != CaptureMode.CALIBRATE:
tst=self.patch_timeslot_again(tst)
tst = self.patch_timeslot_again(tst)
c[1] = tst
#---------------- Reply Configuration ---------------
@ -483,18 +531,32 @@ class Sensor():
# It seems to be only used for identification and it looks almost identical to Finger Detect (0x26)
# Seems to be the same all the time for a given sensor and mostly hardcoded
# TODO: analyse construct_wtf_4e @0000000180090BF0
chunks += [[0x4e, unhexlify('fbb20f0000000f00300000006001020040010a00018000000a0200000b1900008813b80b01091000')]]
chunks += [[
0x4e,
unhexlify(
'fbb20f0000000f00300000006001020040010a00018000000a0200000b1900008813b80b01091000'
)
]]
# Image Reconstruction.
# TODO: analyse add_image_reconstruction_cmd_02_buff_list_item @000000018008EA70
chunks += [[0x2e, unhexlify('0200180002000000900090004d01000090017c013c323232640a0201')]]
chunks += [[
0x2e, unhexlify('0200180002000000900090004d01000090017c013c323232640a0201')
]]
elif mode == CaptureMode.ENROLL:
chunks += [[0x26, unhexlify('fbb20f0000000f00300000006001020040010a00018000000a0200000b19000050c360ea01091000')]]
chunks += [[
0x26,
unhexlify(
'fbb20f0000000f00300000006001020040010a00018000000a0200000b19000050c360ea01091000'
)
]]
# Image Reconstruction. There is only one byte difference with the "identify" version. (same is true for 0097)
chunks += [[0x2e, unhexlify('0200180023000000900090004d01000090017c013c323232640a0201')]]
chunks += [[
0x2e, unhexlify('0200180023000000900090004d01000090017c013c323232640a0201')
]]
lines = []
l=Line()
l = Line()
lines += [l]
l.mask = 0xff
# Find 2nd "Enable Rx" instruction
@ -502,7 +564,7 @@ class Sensor():
l.flags = (pc + 1) | 0x3000000
l.data = self.type_info.calibration_blob
l=Line()
l = Line()
lines += [l]
l.mask = 0xff
# Find 1st "Write Register" instruction to the 0x8000203C port
@ -510,7 +572,7 @@ class Sensor():
l.flags = (pc + 1) | 0x3000000
l.data = self.factory_calib_data
l=Line()
l = Line()
lines += [l]
l.mask = 0xff
# Find 1st "Write Register" instruction to the 0x8000203C port
@ -524,7 +586,6 @@ class Sensor():
if pad > 0:
l.data += b'\0' * (4 - pad)
#---------------- Line Update ---------------
line_update = pack('<L', len(lines))
line_update += b''.join([pack('<LL', l.mask, l.flags) for l in lines])
@ -535,18 +596,18 @@ class Sensor():
return chunks
def build_cmd_02(self, mode):
chunks=list(prg.split_chunks(self.hardcoded_prog))
chunks = list(prg.split_chunks(self.hardcoded_prog))
if self.rom_info.product != 0x30:
raise Exception('Not implemented')
if self.device_info.type in line_update_type1_devices:
chunks=self.line_update_type_1(mode, chunks)
chunks = self.line_update_type_1(mode, chunks)
else:
chunks=self.line_update_type_2(mode, chunks)
chunks = self.line_update_type_2(mode, chunks)
if mode == CaptureMode.CALIBRATE:
req_lines = self.calibration_frames*self.lines_per_frame+1 # TODO: figure out how this is actually calculated
req_lines = self.calibration_frames * self.lines_per_frame + 1 # TODO: figure out how this is actually calculated
else:
req_lines = 0
@ -575,7 +636,7 @@ class Sensor():
hs, zeroes = start[0:0x20], start[0x20:0x40]
if zeroes != b'\0'*0x20:
if zeroes != b'\0' * 0x20:
logging.warning('Unexpected contents in calibration flash partition')
return False
@ -586,7 +647,6 @@ class Sensor():
return True
def calibrate(self):
if os.path.isfile(calib_data_path):
with open(calib_data_path, 'rb') as f:
@ -615,8 +675,9 @@ class Sensor():
clean_slate = self.average(usb.read_82())
clean_slate = pack('<H', len(clean_slate)) + clean_slate
clean_slate = clean_slate + pack('<H', 0) # TODO: still don't know what this zero is for
clean_slate = pack('<H', len(clean_slate)) + sha256(clean_slate).digest() + b'\0'*0x20 + clean_slate
clean_slate = clean_slate + pack('<H', 0) # TODO: still don't know what this zero is for
clean_slate = pack(
'<H', len(clean_slate)) + sha256(clean_slate).digest() + b'\0' * 0x20 + clean_slate
clean_slate = pack('<H', 0x5002) + clean_slate
self.persist_clean_slate(clean_slate)
@ -638,7 +699,7 @@ class Sensor():
while True:
b = usb.wait_int()
if b[0] == 2:
break;
break
# wait capture complete
while True:
@ -668,11 +729,10 @@ class Sensor():
return (x, y, w1, w2)
finally:
tls.app(unhexlify('04')) # capture stop if still running, cleanup
tls.app(unhexlify('04')) # capture stop if still running, cleanup
def enrollment_update_start(self, key):
rsp=tls.app(pack('<BLL', 0x68, key, 0))
rsp = tls.app(pack('<BLL', 0x68, key, 0))
assert_status(rsp)
new_key, = unpack('<L', rsp[2:])
@ -690,7 +750,7 @@ class Sensor():
def enrollment_update(self, prev):
write_enable()
try:
rsp=tls.app(b'\x6b' + prev)
rsp = tls.app(b'\x6b' + prev)
assert_status(rsp)
finally:
call_cleanups()
@ -709,26 +769,25 @@ class Sensor():
if l != len(res):
raise Exception('Response size does not match %d != %d', l, len(res))
magic_len = 0x38 # hardcoded in the DLL
magic_len = 0x38 # hardcoded in the DLL
template = header = tid = None
while len(res) > 0:
tag, l = unpack('<HH', res[:4])
if tag == 0:
template = res[:magic_len+l]
template = res[:magic_len + l]
elif tag == 1:
header = res[magic_len:magic_len+l]
header = res[magic_len:magic_len + l]
elif tag == 3:
tid = res[magic_len:magic_len+l]
tid = res[magic_len:magic_len + l]
else:
logging.warning('Ignoring unknown tag %x' % tag)
res=res[magic_len+l:]
res = res[magic_len + l:]
return (header, template, tid)
def make_finger_data(self, subtype, template, tid):
template = pack('<HH', 1, len(template)) + template
tid = pack('<HH', 2, len(tid)) + tid
@ -746,7 +805,7 @@ class Sensor():
def do_create_finger(final_template, tid):
tinfo = self.make_finger_data(subtype, final_template, tid)
usr=db.lookup_user(identity)
usr = db.lookup_user(identity)
if usr == None:
usr = db.new_user(identity)
else:
@ -759,8 +818,8 @@ class Sensor():
return recid
key=0
template=b''
key = 0
template = b''
self.create_enrollment()
while True:
try:
@ -785,11 +844,11 @@ class Sensor():
finally:
self.enrollment_update_end()
self.enrollment_update_end() # done twice for some reason
self.enrollment_update_end() # done twice for some reason
return do_create_finger(template, tid)
def parse_dict(self, x):
rc={}
rc = {}
while len(x) > 0:
(t, l), x = unpack('<HH', x[:4]), x[4:]
@ -799,10 +858,10 @@ class Sensor():
def match_finger(self) -> typing.Tuple[int, int, bytes]:
try:
stg_id=0 # match against any storage
usr_id=0 # match against any user
cmd=pack('<BBBHHHHH', 0x5e, 2, 0xff, stg_id, usr_id, 1, 0,0)
rsp=tls.app(cmd)
stg_id = 0 # match against any storage
usr_id = 0 # match against any user
cmd = pack('<BBBHHHHH', 0x5e, 2, 0xff, stg_id, usr_id, 1, 0, 0)
rsp = tls.app(cmd)
assert_status(rsp)
b = usb.wait_int()
@ -814,11 +873,11 @@ class Sensor():
assert_status(rsp)
rsp = rsp[2:]
(l,), rsp = unpack('<H', rsp[:2]), rsp[2:]
(l, ), rsp = unpack('<H', rsp[:2]), rsp[2:]
if l != len(rsp):
raise Exception('Response size does not match')
rsp=self.parse_dict(rsp)
rsp = self.parse_dict(rsp)
usrid, subtype, hsh = rsp[1], rsp[3], rsp[4]
usrid, = unpack('<L', usrid)
@ -829,7 +888,6 @@ class Sensor():
# cleanup, ignore any errors
tls.app(unhexlify('6200000000'))
def identify(self, update_cb):
while True:
try:
@ -857,8 +915,8 @@ class Sensor():
finger_record = db.get_record_children(fingerids[0])
ids=[r['dbid'] for r in finger_record.children if r['type'] == 8]
ids = [r['dbid'] for r in finger_record.children if r['type'] == 8]
return [db.get_record_value(id).value for id in ids]
sensor = Sensor()
sensor = Sensor()

View file

@ -1,7 +1,7 @@
from struct import unpack, pack
import typing
class SidIdentity():
def __init__(self, revision: int, auth: int, subauth: typing.Sequence[int]):
self.revision = revision
@ -9,7 +9,7 @@ class SidIdentity():
self.subauth = subauth
def to_bytes(self):
b=pack('>BBHL', self.revision, len(self.subauth), self.auth >> 32, self.auth & 0xffffffff)
b = pack('>BBHL', self.revision, len(self.subauth), self.auth >> 32, self.auth & 0xffffffff)
for i in self.subauth:
b += pack('<L', i)
@ -18,6 +18,7 @@ class SidIdentity():
def __repr__(self):
return 'S-%d-%d-%s' % (self.revision, self.auth, '-'.join(map(str, self.subauth)))
def sid_from_bytes(b: bytes):
revision = b[0]
subcnt = b[1]
@ -27,10 +28,11 @@ def sid_from_bytes(b: bytes):
auth <<= 8
auth |= i
subauth=unpack('<%dL' % subcnt, b[8:])
subauth = unpack('<%dL' % subcnt, b[8:])
return SidIdentity(revision, auth, subauth)
def sid_from_string(s: str):
parts = s.split('-')

View file

@ -1,8 +1,8 @@
from binascii import hexlify, unhexlify
class SensorTypeInfo:
table=[]
table = []
@classmethod
def get_by_type(cls, sensor_type):
@ -11,18 +11,21 @@ class SensorTypeInfo:
if i.sensor_type == sensor_type:
return i
def __init__(self, sensor_type, bytes_per_line, repeat_multiplier, lines_per_calibration_data, line_width, calibration_blob):
self.sensor_type=sensor_type
self.repeat_multiplier=repeat_multiplier
self.lines_per_calibration_data=lines_per_calibration_data
self.line_width=line_width
self.bytes_per_line=bytes_per_line
self.calibration_blob=unhexlify(calibration_blob)
def __init__(self, sensor_type, bytes_per_line, repeat_multiplier, lines_per_calibration_data,
line_width, calibration_blob):
self.sensor_type = sensor_type
self.repeat_multiplier = repeat_multiplier
self.lines_per_calibration_data = lines_per_calibration_data
self.line_width = line_width
self.bytes_per_line = bytes_per_line
self.calibration_blob = unhexlify(calibration_blob)
def __repr__(self):
calibration_blob=hexlify(self.calibration_blob).decode()
calibration_blob = hexlify(self.calibration_blob).decode()
return 'SensorTypeInfo(sensor_type=0x%04x, bytes_per_line=0x%x, repeat_multiplier=%d, lines_per_calibration_data=%d, line_width=%d, calibration_blob=%s)' % (
self.sensor_type, self.bytes_per_line, self.repeat_multiplier, self.lines_per_calibration_data, self.line_width, repr(calibration_blob))
self.sensor_type, self.bytes_per_line, self.repeat_multiplier,
self.lines_per_calibration_data, self.line_width, repr(calibration_blob))
def fuzzy(expected, actual):
if expected == actual:
@ -32,6 +35,7 @@ def fuzzy(expected, actual):
else:
return 0
def metric(i, rominfo):
metric = 0
metric |= fuzzy(i.major, rominfo.major)
@ -44,8 +48,9 @@ def metric(i, rominfo):
return metric
class SensorCaptureProg:
table=[]
table = []
@classmethod
def get(cls, rominfo, sensor_type, a0, a1):
@ -76,18 +81,18 @@ class SensorCaptureProg:
return b''.join(found.blobs)
def __init__(self, major, minor, build, u1, dev_type, a0, a1, blobs):
self.major=major
self.minor=minor
self.build=build
self.u1=u1
self.dev_type=dev_type
self.a0=a0
self.a1=a1
blobs=[unhexlify(b) for b in blobs]
self.blobs=blobs
self.major = major
self.minor = minor
self.build = build
self.u1 = u1
self.dev_type = dev_type
self.a0 = a0
self.a1 = a1
blobs = [unhexlify(b) for b in blobs]
self.blobs = blobs
def __repr__(self):
blobs=[hexlify(b).decode() for b in self.blobs]
blobs = [hexlify(b).decode() for b in self.blobs]
return 'SensorCaptureProg(major=0x%x, minor=0x%x, build=0x%x, u1=0x%x, dev_type=0x%x, a0=0x%x, a1=0x%x, blobs=%s)' % (
self.major, self.minor, self.build, self.u1, self.dev_type, self.a0, self.a1,

View file

@ -1,103 +1,103 @@
from binascii import hexlify
from struct import unpack, pack
codes={}
codes[0x0] = "No Operation"
codes[0x1] = "Swipe"
codes[0x2] = "Timeslot Configuration"
codes[0x3] = "Register"
codes[0x4] = "Register Set 32"
codes[0x5] = "Register Operation 32"
codes[0x6] = "Security"
codes[0x7] = "WOE"
codes[0x8] = "Motion 1"
codes[0xa] = "CPUCLK"
codes[0xb] = "Motion 2"
codes[0xc] = "Calibration Block"
codes[0xd] = "Sweep"
codes[0xe] = "Zone Configuration"
codes[0xf] = "Zones Per Sweep"
codes[0x10] = "Lines Per Sweep Iteration"
codes[0x11] = "Lines Per Sweep"
codes[0x12] = "Total Zones"
codes[0x13] = "CAL WOE Ctrl"
codes[0x14] = "Cal WOE Mask"
codes[0x15] = "BW Reduciton"
codes[0x16] = "AGC"
codes[0x17] = "Reply Configuration"
codes[0x18] = "Motion 3"
codes[0x19] = "WOVAR"
codes[0x1a] = "Block MOde"
codes[0x1b] = "Bit Reduction"
codes[0x1c] = "Motion 4"
codes[0x1d] = "Calibration WOENF"
codes[0x1e] = "Calibration"
codes[0x1f] = "Zone Configuration A"
codes[0x20] = "Set Register 32"
codes[0x21] = "Register Operation 32A"
codes[0x22] = "Fingerprint Buffering"
codes[0x23] = "Reply Config + Timeslot Table"
codes[0x24] = "Baseline"
codes[0x25] = "SO Alternate"
codes[0x26] = "Finger Detect"
codes[0x27] = "Finger Detect Sample Register"
codes[0x28] = "Finger Detect Scan Registers"
codes[0x29] = "Timeslot Table Offset"
codes[0x2a] = "ACM Config"
codes[0x2b] = "ACM Control"
codes[0x2c] = "CEM Config"
codes[0x2d] = "CEM Control"
codes[0x2e] = "Image Reconstruction"
codes[0x2f] = "2D"
codes[0x30] = "Line Update"
codes[0x31] = "FDetect Timeslot Table"
codes[0x32] = "Register List 16"
codes[0x33] = "Register list 32"
codes[0x34] = "Timeslot Table 2D"
codes[0x35] = "Timeslot Table Offset for Finger Detect"
codes[0x36] = "Security Aligned"
codes[0x37] = "WOF2"
codes[0x38] = "WOE WOF"
codes[0x39] = "Navigation"
codes[0x3a] = "WOE WOF2 Version2"
codes[0x3b] = "Cal WOE WOF2"
codes[0x3c] = "Event Signal"
codes[0x3d] = "IFS Frame Stats"
codes[0x3e] = "SNR Method 4"
codes[0x3f] = "WOE WOF2 Version 3"
codes[0x40] = "Calibrate WOE WOF2 Version 3"
codes[0x41] = "Finger Detect Ratchet"
codes[0x42] = "Data Encoder"
codes[0x43] = "Line Update Transform"
codes[0x44] = "Line Update InterLeave"
codes[0x45] = "SO Table Values for Macros"
codes[0x46] = "Timeslot Macro Definitions"
codes[0x47] = "Enable ASP Feature"
codes[0x48] = "Baseline Frame"
codes[0x49] = "Rx Select"
codes[0x4e] = "WTF"
codes[0xffff] = "Unknown"
codes = {}
codes[0x0] = "No Operation"
codes[0x1] = "Swipe"
codes[0x2] = "Timeslot Configuration"
codes[0x3] = "Register"
codes[0x4] = "Register Set 32"
codes[0x5] = "Register Operation 32"
codes[0x6] = "Security"
codes[0x7] = "WOE"
codes[0x8] = "Motion 1"
codes[0xa] = "CPUCLK"
codes[0xb] = "Motion 2"
codes[0xc] = "Calibration Block"
codes[0xd] = "Sweep"
codes[0xe] = "Zone Configuration"
codes[0xf] = "Zones Per Sweep"
codes[0x10] = "Lines Per Sweep Iteration"
codes[0x11] = "Lines Per Sweep"
codes[0x12] = "Total Zones"
codes[0x13] = "CAL WOE Ctrl"
codes[0x14] = "Cal WOE Mask"
codes[0x15] = "BW Reduciton"
codes[0x16] = "AGC"
codes[0x17] = "Reply Configuration"
codes[0x18] = "Motion 3"
codes[0x19] = "WOVAR"
codes[0x1a] = "Block MOde"
codes[0x1b] = "Bit Reduction"
codes[0x1c] = "Motion 4"
codes[0x1d] = "Calibration WOENF"
codes[0x1e] = "Calibration"
codes[0x1f] = "Zone Configuration A"
codes[0x20] = "Set Register 32"
codes[0x21] = "Register Operation 32A"
codes[0x22] = "Fingerprint Buffering"
codes[0x23] = "Reply Config + Timeslot Table"
codes[0x24] = "Baseline"
codes[0x25] = "SO Alternate"
codes[0x26] = "Finger Detect"
codes[0x27] = "Finger Detect Sample Register"
codes[0x28] = "Finger Detect Scan Registers"
codes[0x29] = "Timeslot Table Offset"
codes[0x2a] = "ACM Config"
codes[0x2b] = "ACM Control"
codes[0x2c] = "CEM Config"
codes[0x2d] = "CEM Control"
codes[0x2e] = "Image Reconstruction"
codes[0x2f] = "2D"
codes[0x30] = "Line Update"
codes[0x31] = "FDetect Timeslot Table"
codes[0x32] = "Register List 16"
codes[0x33] = "Register list 32"
codes[0x34] = "Timeslot Table 2D"
codes[0x35] = "Timeslot Table Offset for Finger Detect"
codes[0x36] = "Security Aligned"
codes[0x37] = "WOF2"
codes[0x38] = "WOE WOF"
codes[0x39] = "Navigation"
codes[0x3a] = "WOE WOF2 Version2"
codes[0x3b] = "Cal WOE WOF2"
codes[0x3c] = "Event Signal"
codes[0x3d] = "IFS Frame Stats"
codes[0x3e] = "SNR Method 4"
codes[0x3f] = "WOE WOF2 Version 3"
codes[0x40] = "Calibrate WOE WOF2 Version 3"
codes[0x41] = "Finger Detect Ratchet"
codes[0x42] = "Data Encoder"
codes[0x43] = "Line Update Transform"
codes[0x44] = "Line Update InterLeave"
codes[0x45] = "SO Table Values for Macros"
codes[0x46] = "Timeslot Macro Definitions"
codes[0x47] = "Enable ASP Feature"
codes[0x48] = "Baseline Frame"
codes[0x49] = "Rx Select"
codes[0x4e] = "WTF"
codes[0xffff] = "Unknown"
insn_to_string=[
'NOOP', # 0
'End of Table', # 1
'Return', # 2
'Clear SO', # 3
'End of Data', # 4
'Marco %02x', # 5
'Enable Rx 0x%02x', # 6
'Idle Rx 0x%03x', # 7
'Enable SO 0x%03x', # 8
'Disable SO 0x%03x', # 9
'Interrupt %x', # 10
'Call rx_inc=%d, addr=%x, repeat=%d', # 11
'Features %02x', # 12
'Register Write *0x%08x = 0x%04x', # 13
'Sample %x, %x', # 14
'Sample Repeat %x, %x, repeat=%x', # 15
insn_to_string = [
'NOOP', # 0
'End of Table', # 1
'Return', # 2
'Clear SO', # 3
'End of Data', # 4
'Marco %02x', # 5
'Enable Rx 0x%02x', # 6
'Idle Rx 0x%03x', # 7
'Enable SO 0x%03x', # 8
'Disable SO 0x%03x', # 9
'Interrupt %x', # 10
'Call rx_inc=%d, addr=%x, repeat=%d', # 11
'Features %02x', # 12
'Register Write *0x%08x = 0x%04x', # 13
'Sample %x, %x', # 14
'Sample Repeat %x, %x, repeat=%x', # 15
]
def decode_insn(b):
if b[0] == 0:
return (0, 1)
@ -124,9 +124,9 @@ def decode_insn(b):
elif b[0] & 0xf8 == 0x10:
return (11, 3, b[0] & 7, b[1] << 2, 0x100 if b[2] == 0 else b[2])
elif b[0] & 0xe0 == 0x20:
return (12, 1, b[0] & 0x1f) # TODO check how features are converted to op args
return (12, 1, b[0] & 0x1f) # TODO check how features are converted to op args
elif b[0] & 0xc0 == 0x40:
return (13, 3, (b[0] & 0x3f)*4+0x80002000, b[1] | (b[2] << 8))
return (13, 3, (b[0] & 0x3f) * 4 + 0x80002000, b[1] | (b[2] << 8))
elif b[0] & 0xc0 == 0x80:
return (14, 1, (b[0] & 0x38) >> 3, b[0] & 7)
elif b[0] & 0xc0 == 0xc0:
@ -134,18 +134,21 @@ def decode_insn(b):
else:
raise Exception('Unhandled instruction %02x' % b)
def disassm_timeslot_table(b, off):
pc=off
pc = off
while len(b) > 0:
op, sz, *operands = decode_insn(b)
if sz > len(b):
raise Exception('Truncated instruction')
print(' %04x: %-6s %s' % (pc, hexlify(b[:sz]).decode(), insn_to_string[op] % tuple(operands)))
print(' %04x: %-6s %s' %
(pc, hexlify(b[:sz]).decode(), insn_to_string[op] % tuple(operands)))
b = b[sz:]
pc += sz
def find_nth_insn(b, opcode, n):
pc=0
pc = 0
while len(b) > 0:
op, sz, *_ = decode_insn(b)
@ -153,15 +156,16 @@ def find_nth_insn(b, opcode, n):
raise Exception('Truncated instruction')
if op == opcode:
n-=1
n -= 1
if n == 0:
return (pc, b[:sz])
b = b[sz:]
pc += sz
def find_nth_regwrite(b, reg_addr, n):
pc=0
pc = 0
while len(b) > 0:
op, sz, *operands = decode_insn(b)
@ -171,7 +175,7 @@ def find_nth_regwrite(b, reg_addr, n):
if op == 13:
addr, value = operands
if addr == reg_addr:
n-=1
n -= 1
if n == 0:
return (pc, b[:sz])
@ -185,9 +189,11 @@ def split_chunks(b):
p, b = b[:sz], b[sz:]
yield [typ, p]
def merge_chunks(cs):
return b''.join([pack('<HH', key, len(val)) + val for key, val in cs])
def dump_all(b):
while len(b) > 0:
(typ, sz), b = unpack('<HH', b[:4]), b[4:]
@ -198,19 +204,19 @@ def dump_all(b):
print(' *0x%08x = 0x%08x' % (addr, val))
elif typ == 0x32:
print('Set Registers 16:')
(base,), p = unpack('<L', p[:4]), p[4:]
(base, ), p = unpack('<L', p[:4]), p[4:]
while len(p) > 0:
(off, val), p = unpack('<HH', p[:4]), p[4:]
print(' *0x%08x = 0x%04x' % (off + base, val))
elif typ == 0x33:
print('Set Registers 32:')
(base,), p = unpack('<L', p[:4]), p[4:]
(base, ), p = unpack('<L', p[:4]), p[4:]
while len(p) > 0:
(off, val), p = unpack('<HL', p[:6]), p[6:]
print(' *0x%08x = 0x%08x' % (off + base, val))
elif typ == 0x34:
print('%04x (%20s): (0x%x bytes) %s' % (typ, codes[typ], len(p), hexlify(p).decode()))
ts=p
ts = p
elif typ == 0x29:
ts_off, = unpack('<L', p)
print('%04x (%20s): 0x%x' % (typ, codes[typ], ts_off))
@ -220,4 +226,3 @@ def dump_all(b):
if ts is not None:
print('Timeslot table, starting at 0x%x:' % ts_off)
disassm_timeslot_table(ts[ts_off:], ts_off)

View file

@ -15,11 +15,10 @@ from hashlib import sha256
from .util import unhex
from .usb import usb
password_hardcoded = unhexlify('717cd72d0962bc4a2846138dbb2c24192512a76407065f383846139d4bec2033')
gwk_sign_hardcoded = unhexlify('3a4c76b76a97981d1274247e166610e77f4d9c9d07d3c728e532916bdd28b454')
password_hardcoded=unhexlify('717cd72d0962bc4a2846138dbb2c24192512a76407065f383846139d4bec2033')
gwk_sign_hardcoded=unhexlify('3a4c76b76a97981d1274247e166610e77f4d9c9d07d3c728e532916bdd28b454')
crt_hardcoded=unhex('''
crt_hardcoded = unhex('''
170000000001000001000000fcffffffffffffffffffffff00000000000000000000000001000000fffff
fff0000000000000000000000000000000000000000000000000000000000000000000000004b60d2273e
3cce3bf6b053ccb0061d65bc86987655bdebb3e7933aaad835c65a0000000000000000000000000000000
@ -32,7 +31,8 @@ ae6bcffffffffffffffff00000000ffffffff0000000000000000000000000000000000000000000
fff000000000000000000000000000000000000000000000000000000000000000000000000
''')
crypto_backend=default_backend()
crypto_backend = default_backend()
def prf(secret, seed, length):
n = (length + 0x20 - 1) // 0x20
@ -41,46 +41,52 @@ def prf(secret, seed, length):
a = hmac.new(secret, seed, sha256).digest()
while n > 0:
res += hmac.new(secret, a+seed, sha256).digest()
res += hmac.new(secret, a + seed, sha256).digest()
a = hmac.new(secret, a, sha256).digest()
n -= 1
return res[:length]
def hs_key():
key=password_hardcoded[:0x10]
seed=password_hardcoded[0x10:] + b'\xaa'*2
hs_key=prf(key, b'HS_KEY_PAIR_GEN' + seed, 0x20)
key = password_hardcoded[:0x10]
seed = password_hardcoded[0x10:] + b'\xaa' * 2
hs_key = prf(key, b'HS_KEY_PAIR_GEN' + seed, 0x20)
return int(hs_key[::-1].hex(), 16)
def with_2bytes_size(chunk):
return pack('>H', len(chunk)) + chunk
def with_3bytes_size(chunk):
return pack('>BH', len(chunk) >> 16, len(chunk)) + chunk
def with_1byte_size(chunk):
return pack('>B', len(chunk)) + chunk
def to_bytes(n):
b=b''
b = b''
while n:
b += (n & 0xff).to_bytes(1, 'big')
n >>= 8
return b
def pad(b):
l = 16 - (len(b) % 16)
return b + bytes([l-1])*l
return b + bytes([l - 1]) * l
def unpad(b):
return b[:-1-b[-1]]
return b[:-1 - b[-1]]
# TODO assert the right state transitions
class Tls():
def __init__(self, usb):
self.usb = usb
self.reset()
@ -107,14 +113,14 @@ class Tls():
# pre-TLS keys
self.psk_encryption_key = prf(password_hardcoded, b'GWK' + hw_key, 0x20)
self.psk_validation_key = prf(self.psk_encryption_key,
b'GWK_SIGN' + gwk_sign_hardcoded, 0x20)
self.psk_validation_key = prf(self.psk_encryption_key, b'GWK_SIGN' + gwk_sign_hardcoded,
0x20)
def cmd(self, cmd):
if self.secure_rx and self.secure_tx:
rsp=self.app(cmd)
rsp = self.app(cmd)
else:
rsp=self.usb.cmd(cmd)
rsp = self.usb.cmd(cmd)
return rsp
@ -124,19 +130,15 @@ class Tls():
self.handshake_hash = sha256()
rsp=self.usb.cmd(unhexlify('44000000') + self.make_handshake(self.make_client_hello()))
rsp = self.usb.cmd(unhexlify('44000000') + self.make_handshake(self.make_client_hello()))
self.parse_tls_response(rsp)
self.make_keys()
rsp=self.usb.cmd(
unhexlify('44000000') +
self.make_handshake(
self.make_certs() +
self.make_client_kex() +
self.make_cert_verify()) +
self.make_change_cipher_spec() +
self.make_handshake(self.make_finish()))
rsp = self.usb.cmd(
unhexlify('44000000') + self.make_handshake(self.make_certs() + self.make_client_kex() +
self.make_cert_verify()) +
self.make_change_cipher_spec() + self.make_handshake(self.make_finish()))
self.parse_tls_response(rsp)
@ -156,27 +158,28 @@ class Tls():
self.session_public = skey.private_numbers().public_numbers
pre_master_secret = skey.exchange(ec.ECDH(), self.ecdh_q)
seed = self.client_random + self.server_random
self.master_secret = prf(pre_master_secret, b'master secret'+seed, 0x30)
key_block = prf(self.master_secret, b'key expansion'+seed, 0x120)
self.master_secret = prf(pre_master_secret, b'master secret' + seed, 0x30)
key_block = prf(self.master_secret, b'key expansion' + seed, 0x120)
self.sign_key = key_block[0x00:0x20]
self.validation_key = key_block[0x20:0x20+0x20]
self.encryption_key = key_block[0x40:0x40+0x20]
self.decryption_key = key_block[0x60:0x60+0x20]
self.validation_key = key_block[0x20:0x20 + 0x20]
self.encryption_key = key_block[0x40:0x40 + 0x20]
self.decryption_key = key_block[0x60:0x60 + 0x20]
def save(self):
with open('tls.dict', 'wb') as f:
pickle.dump({
'sign_key': self.sign_key,
'validation_key': self.validation_key,
'encryption_key': self.encryption_key,
'decryption_key': self.decryption_key,
'secure_rx': self.secure_rx,
'secure_tx': self.secure_tx
}, f)
pickle.dump(
{
'sign_key': self.sign_key,
'validation_key': self.validation_key,
'encryption_key': self.encryption_key,
'decryption_key': self.decryption_key,
'secure_rx': self.secure_rx,
'secure_tx': self.secure_tx
}, f)
def load(self):
with open('tls.dict', 'rb') as f:
d=pickle.load(f)
d = pickle.load(f)
self.sign_key = d['sign_key']
self.validation_key = d['validation_key']
self.encryption_key = d['encryption_key']
@ -189,7 +192,7 @@ class Tls():
cipher = Cipher(algorithms.AES(self.decryption_key), modes.CBC(iv), backend=crypto_backend)
decryptor = cipher.decryptor()
m = decryptor.update(c) + decryptor.finalize()
m=unpad(m)
m = unpad(m)
return m
def encrypt(self, b):
@ -197,15 +200,15 @@ class Tls():
iv = os.urandom(0x10)
cipher = Cipher(algorithms.AES(self.encryption_key), modes.CBC(iv), backend=crypto_backend)
encryptor = cipher.encryptor()
b=pad(b)
c=encryptor.update(b) + encryptor.finalize()
b = pad(b)
c = encryptor.update(b) + encryptor.finalize()
return iv + c
def validate(self, t, b):
b, hs = b[:-0x20], b[-0x20:]
hdr = pack('>BBBH', t, 3, 3, len(b))
sig=hmac.new(self.validation_key, hdr+b, sha256).digest()
sig = hmac.new(self.validation_key, hdr + b, sha256).digest()
if sig != hs:
raise Exception('Packet signature validation check failed')
@ -217,13 +220,13 @@ class Tls():
self.trace('>tls> %02x: %s' % (t, hexlify(b).decode()))
hdr = pack('>BBBH', t, 3, 3, len(b))
sig=hmac.new(self.sign_key, hdr+b, sha256).digest()
sig = hmac.new(self.sign_key, hdr + b, sha256).digest()
return b + sig
def make_finish(self):
self.secure_tx = True
hs_hash = self.handshake_hash.copy().digest()
verify_data = prf(self.master_secret, b'client finished'+hs_hash, 0xc)
verify_data = prf(self.master_secret, b'client finished' + hs_hash, 0xc)
return b'\x14' + with_3bytes_size(verify_data)
def make_change_cipher_spec(self):
@ -231,9 +234,10 @@ class Tls():
def make_certs(self):
cert = self.tls_cert
cert = unhexlify('ac16') + cert # what's this?
cert = pack('>BH', 0, len(self.tls_cert)) + cert # this seems to violate the standard (should be len(cert))
cert = pack('>BH', 0, len(self.tls_cert)) + cert # same
cert = unhexlify('ac16') + cert # what's this?
cert = pack('>BH', 0, len(
self.tls_cert)) + cert # this seems to violate the standard (should be len(cert))
cert = pack('>BH', 0, len(self.tls_cert)) + cert # same
return self.with_neg_hdr(0x0b, cert)
def with_neg_hdr(self, t, b):
@ -246,8 +250,8 @@ class Tls():
return self.with_neg_hdr(0x10, b)
def make_cert_verify(self):
buf=self.handshake_hash.copy().digest()
b=self.priv_key.sign(buf, ec.ECDSA(Prehashed(hashes.SHA256())))
buf = self.handshake_hash.copy().digest()
b = self.priv_key.sign(buf, ec.ECDSA(Prehashed(hashes.SHA256())))
return self.with_neg_hdr(0x0f, b)
def handle_server_hello(self, p):
@ -258,15 +262,16 @@ class Tls():
self.server_random, p = p[:0x20], p[0x20:]
l = p[0]
self.server_sessid, p = p[1:1+l], p[1+l:]
self.server_sessid, p = p[1:1 + l], p[1 + l:]
(suite,), p = unpack('>H', p[:2]), p[2:]
(suite, ), p = unpack('>H', p[:2]), p[2:]
if suite != 0xc005:
raise Exception('Server accepted unsupported cipher suite %04x' % suite)
if p[0] != 0:
raise Exception('Server selected to enable compression, which we don''t support %02x' % p[0])
raise Exception('Server selected to enable compression, which we don'
't support %02x' % p[0])
p = p[1:]
@ -274,11 +279,13 @@ class Tls():
raise Exception('Not expecting any more data')
def handle_cert_req(self, p):
(sign_and_hash_algo,), p = unpack('>H', p[:2]), p[2:]
(sign_and_hash_algo, ), p = unpack('>H', p[:2]), p[2:]
if sign_and_hash_algo != 0x140:
raise Exception('Server requested a cert with an unsupported sign and hash algo combination %04x' % sign_and_hash_algo)
raise Exception(
'Server requested a cert with an unsupported sign and hash algo combination %04x' %
sign_and_hash_algo)
(l,), p = unpack('>H', p[:2]), p[2:]
(l, ), p = unpack('>H', p[:2]), p[2:]
if l != 0:
raise Exception('Server requested a cert with non-empty list of CAs')
@ -287,11 +294,12 @@ class Tls():
def handle_server_hello_done(self, p):
if p != b'':
raise Exception('Not expecting any body for "server hello done" pkt: %s' % hexlify(p).decode())
raise Exception('Not expecting any body for "server hello done" pkt: %s' %
hexlify(p).decode())
def handle_finish(self, b):
hs_hash = self.handshake_hash.copy().digest()
verify_data = prf(self.master_secret, b'server finished'+hs_hash, 0xc)
verify_data = prf(self.master_secret, b'server finished' + hs_hash, 0xc)
if verify_data != b:
raise Exception('Final handshake check failed')
@ -325,10 +333,10 @@ class Tls():
else:
raise Exception('Unknown handshake packet %02x' % t)
self.update_neg(hdr+p)
self.update_neg(hdr + p)
def parse_tls_response(self, rsp):
app_data=b''
app_data = b''
while len(rsp) > 0:
while len(rsp) < 5:
@ -362,36 +370,37 @@ class Tls():
if not self.secure_tx:
raise Exception('App payload before secure connection established')
b=self.encrypt(self.sign(0x17, b))
b = self.encrypt(self.sign(0x17, b))
return unhexlify('170303') + with_2bytes_size(b)
def make_handshake(self, b):
if self.secure_tx:
b=self.encrypt(self.sign(0x16, b))
b = self.encrypt(self.sign(0x16, b))
return unhexlify('160303') + with_2bytes_size(b)
def make_client_hello(self):
h = unhexlify('0303') # TLS 1.2
h = unhexlify('0303') # TLS 1.2
#self.client_random = unhexlify('bc349559ac16c8f8362191395b4d04a435d870315f519eed8777488bc2b9600c')
self.client_random = os.urandom(0x20)
h += self.client_random # client's random
h += with_1byte_size(unhexlify('00000000000000')) # session ID
h += self.client_random # client's random
h += with_1byte_size(unhexlify('00000000000000')) # session ID
suits = b''
suits += pack('>H', 0xc005) # TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
suits += pack('>H', 0x003d) # TLS_RSA_WITH_AES_256_CBC_SHA256
suits += pack('>H', 0x008d) # TLS_RSA_WITH_AES_256_CBC_SHA256
suits += pack('>H', 0xc005) # TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
suits += pack('>H', 0x003d) # TLS_RSA_WITH_AES_256_CBC_SHA256
suits += pack('>H', 0x008d) # TLS_RSA_WITH_AES_256_CBC_SHA256
h += with_2bytes_size(suits)
h += with_1byte_size(b'') # no compression options
h += with_1byte_size(b'') # no compression options
exts = b''
exts += self.make_ext(0x004, pack('>H', 0x0017)) # truncated_hmac = 0x17
exts += self.make_ext(0x00b, with_1byte_size(unhexlify('00'))) # EC points format = uncompressed
exts += self.make_ext(0x004, pack('>H', 0x0017)) # truncated_hmac = 0x17
exts += self.make_ext(0x00b,
with_1byte_size(unhexlify('00'))) # EC points format = uncompressed
# h += with_2bytes_size(exts)
h += pack('>H', len(exts)-2) + exts # -2? WHY?!...
h += pack('>H', len(exts) - 2) + exts # -2? WHY?!...
return self.with_neg_hdr(0x01, h)
@ -410,7 +419,7 @@ class Tls():
self.trace('block id %04x (%d bytes)' % (id, sz))
m=sha256()
m = sha256()
m.update(body)
if m.digest() != hs:
@ -432,20 +441,20 @@ class Tls():
self.trace('unhandled block id %04x (%d bytes): %s' % (id, sz, hexlify(body)))
def makeTlsFlashBlock(self, id, body):
m=sha256()
m = sha256()
m.update(body)
hdr = pack('<HH', id, len(body))
return hdr+m.digest()+body
return hdr + m.digest() + body
def makeTlsFlash(self):
b = self.makeTlsFlashBlock(0, b'\0')
b+= self.makeTlsFlashBlock(4, self.priv_blob)
b+= self.makeTlsFlashBlock(3, self.tls_cert)
b+= self.makeTlsFlashBlock(5, crt_hardcoded)
b+= self.makeTlsFlashBlock(1, b'\0' * 0x100)
b+= self.makeTlsFlashBlock(2, b'\0' * 0x100)
b+= self.makeTlsFlashBlock(6, self.ecdh_blob)
b+= b'\xff' * (0x1000 - len(b))
b += self.makeTlsFlashBlock(4, self.priv_blob)
b += self.makeTlsFlashBlock(3, self.tls_cert)
b += self.makeTlsFlashBlock(5, crt_hardcoded)
b += self.makeTlsFlashBlock(1, b'\0' * 0x100)
b += self.makeTlsFlashBlock(2, b'\0' * 0x100)
b += self.makeTlsFlashBlock(6, self.ecdh_blob)
b += b'\xff' * (0x1000 - len(b))
return b
def handle_empty(self, body):
@ -460,8 +469,8 @@ class Tls():
def handle_ecdh(self, body):
self.ecdh_blob = body
key, signature = body[:0x90], body[0x90:]
x = key[0x8:0x8+0x20]
y = key[0x4c:0x4c+0x20]
x = key[0x8:0x8 + 0x20]
y = key[0x4c:0x4c + 0x20]
x, y = [int(hexlify(i[::-1]), 0x10) for i in [x, y]]
@ -477,19 +486,19 @@ class Tls():
l, = unpack('<L', l)
signature, zeroes = signature[:l], signature[l:]
if zeroes != b'\0'*len(zeroes):
if zeroes != b'\0' * len(zeroes):
raise Exception('Zeroes expected')
# The following pub key is hardcoded for each fw revision in the synaWudfBioUsb.dll.
# Corresponding private key should only be known to a genuine Synaptic device.
fwpub = ec.EllipticCurvePublicNumbers(
0xf727653b4e16ce0665a6894d7f3a30d7d0a0be310d1292a743671fdf69f6a8d3,
0xa85538f8b6bec50d6eef8bd5f4d07a886243c58b2393948df761a84721a6ca94, ec.SECP256R1()).public_key(crypto_backend)
0xa85538f8b6bec50d6eef8bd5f4d07a886243c58b2393948df761a84721a6ca94,
ec.SECP256R1()).public_key(crypto_backend)
# throws InvalidSignature
fwpub.verify(signature, key, ec.ECDSA(hashes.SHA256()))
def handle_priv(self, body):
self.priv_blob = body
prefix, body = body[0], body[1:]
@ -497,15 +506,19 @@ class Tls():
raise Exception('Unknown private key prefix %02x' % prefix)
c, hs = body[:-0x20], body[-0x20:]
sig=hmac.new(self.psk_validation_key, c, sha256).digest()
sig = hmac.new(self.psk_validation_key, c, sha256).digest()
if hs != sig:
raise Exception('Signature verification failed. This device was probably paired with another computer.')
raise Exception(
'Signature verification failed. This device was probably paired with another computer.'
)
iv, c = c[:0x10], c[0x10:]
cipher = Cipher(algorithms.AES(self.psk_encryption_key), modes.CBC(iv), backend=crypto_backend)
cipher = Cipher(algorithms.AES(self.psk_encryption_key),
modes.CBC(iv),
backend=crypto_backend)
decryptor = cipher.decryptor()
m = decryptor.update(c) + decryptor.finalize()
m=m[:-m[-1]] # unpad (standard this time)
m = m[:-m[-1]] # unpad (standard this time)
x, m = m[:0x20], m[0x20:]
y, m = m[:0x20], m[0x20:]

View file

@ -6,7 +6,8 @@ from .usb import usb
from .sensor import reboot, write_hw_reg32, read_hw_reg32, identify_sensor
from .flash import write_flash_all, write_fw_signature, get_fw_info
firmware_home='/usr/share/python-validity'
firmware_home = '/usr/share/python-validity'
def default_fwext_name():
if usb.usb_dev().idVendor == 0x138a:
@ -19,10 +20,12 @@ def default_fwext_name():
# So, it is important that xpfwext file is matching the blobs contents.
return '6_07f_lenovo_mis_qm.xpfwext'
def upload_fwext(fw_path=None):
fwi=get_fw_info(2)
fwi = get_fw_info(2)
if fwi != None:
logging.info('Detected firmware version %d.%d (%s))' % (fwi.major, fwi.minor, ctime(fwi.buildtime)))
logging.info('Detected firmware version %d.%d (%s))' %
(fwi.major, fwi.minor, ctime(fwi.buildtime)))
return
else:
logging.info('No firmware detected. Uploading...')
@ -32,33 +35,32 @@ def upload_fwext(fw_path=None):
if read_hw_reg32(0x80002080) not in [2, 3]:
raise Exception('Unexpected register value')
dev=identify_sensor()
dev = identify_sensor()
logging.debug('Sensor: %s' % dev.name)
# ^ TODO -- what is the real reason to detect HW at this stage?
# just a guess: perhaps it is used to construct fwext filename
default_name = firmware_home + '/' + default_fwext_name()
if not fw_path:
fw_path = default_name
elif basename(fw_path) != default_name:
logging.warning('WARNING: Your device fw is supposed to be called {}'.format(
default_name))
logging.warning('WARNING: Your device fw is supposed to be called {}'.format(default_name))
with open(fw_path, 'rb') as f:
fwext=f.read()
fwext = f.read()
fwext=fwext[fwext.index(b'\x1a')+1:]
fwext = fwext[fwext.index(b'\x1a') + 1:]
fwext, signature = fwext[:-0x100], fwext[-0x100:]
write_flash_all(2, 0, fwext)
write_fw_signature(2, signature)
fwi=get_fw_info(2)
fwi = get_fw_info(2)
if fwi == None:
raise Exception('No firmware detected')
logging.info('Loaded FWExt version %d.%d (%s), %d modules' % (fwi.major, fwi.minor, ctime(fwi.buildtime), len(fwi.modules)))
logging.info('Loaded FWExt version %d.%d (%s), %d modules' %
(fwi.major, fwi.minor, ctime(fwi.buildtime), len(fwi.modules)))
# Reboot
reboot()

View file

@ -1,4 +1,3 @@
import logging
import errno
import usb.core as ucore
@ -8,15 +7,17 @@ from struct import unpack
from usb.core import USBError
from .blobs import init_hardcoded, init_hardcoded_clean_slate
supported_devices=[
supported_devices = [
(0x138a, 0x0090),
(0x138a, 0x0097),
(0x06cb, 0x009a),
]
class CancelledException(Exception):
pass
class Usb():
def __init__(self):
self.interrupt_cb = None
@ -28,6 +29,7 @@ class Usb():
if vendor is not None and product is not None:
dev = ucore.find(idVendor=vendor, idProduct=product)
else:
def match(d):
return (d.idVendor, d.idProduct) in supported_devices
@ -65,16 +67,16 @@ class Usb():
#self.dev.set_configuration()
# TODO analyse responses, detect hardware type
assert_status(self.cmd(unhexlify('01'))) # RomInfo.get()
assert_status(self.cmd(unhexlify('01'))) # RomInfo.get()
assert_status(self.cmd(unhexlify('19')))
# 43 -- get partition header(?) (02 -- fwext partition)
# c28c745a in response is a FwextBuildtime = 0x5A748CC2
rsp=self.cmd(unhexlify('4302')) # get_fw_info()
rsp = self.cmd(unhexlify('4302')) # get_fw_info()
assert_status(self.cmd(init_hardcoded))
(err,), rsp = unpack('<H', rsp[:2]), rsp[2:]
(err, ), rsp = unpack('<H', rsp[:2]), rsp[2:]
if err != 0:
# fwext is not loaded
logging.info('Clean slate')
@ -87,14 +89,14 @@ class Usb():
return 0
self.trace('>cmd> %s' % hexlify(out).decode())
self.dev.write(1, out)
resp = self.dev.read(129, 100*1024)
resp = self.dev.read(129, 100 * 1024)
resp = bytes(resp)
self.trace('<cmd< %s' % hexlify(resp).decode())
return resp
def read_82(self):
try:
resp = self.dev.read(130, 1024*1024, timeout=10000)
resp = self.dev.read(130, 1024 * 1024, timeout=10000)
resp = bytes(resp)
self.trace('<130< %s' % hexlify(resp).decode())
return resp
@ -126,4 +128,5 @@ class Usb():
if self.trace_enabled:
logging.debug(s)
usb=Usb()
usb = Usb()

View file

@ -1,10 +1,10 @@
import re
from struct import unpack
from binascii import unhexlify
def assert_status(b):
s,=unpack('<H', b[:2])
s, = unpack('<H', b[:2])
if s != 0:
if s == 0x44f:
raise Exception('Signature validation failed: %04x' % s)
@ -14,4 +14,3 @@ def assert_status(b):
def unhex(x):
return unhexlify(re.sub('\W', '', x))